src/Player.cc
changeset 221 fbc5db6fce45
parent 220 1c92222af6d3
child 222 293ddf4c067d
equal deleted inserted replaced
220:1c92222af6d3 221:fbc5db6fce45
    20 Player::Player(GameState &state, Vector position, bool visible) : 
    20 Player::Player(GameState &state, Vector position, bool visible) : 
    21     PhysicsObject(state.world, PLAYER_MASS, position, Vector(0, 0)), state(state), visible(visible), arsenal(), selectedWeapon(0), changing(false), animation_step(0) {
    21     PhysicsObject(state.world, PLAYER_MASS, position, Vector(0, 0)), state(state), visible(visible), arsenal(), selectedWeapon(0), changing(false), animation_step(0) {
    22     // TODO: arsenal's size should be affected by some value
    22     // TODO: arsenal's size should be affected by some value
    23     // and weapons should be loaded from somewhere, not generated here
    23     // and weapons should be loaded from somewhere, not generated here
    24     for (int i = 0; i < 5; i++) {
    24     for (int i = 0; i < 5; i++) {
    25         arsenal.push_back(Weapon(10000, (5-i)*40+30, i*6+5, i*100+50, "asdf"));
    25         arsenal.push_back(Weapon(state, 10000, (5 - i) * 40 + 30, i * 6 + 5, i * 100 + 50, "asdf"));
    26     }
    26     }
    27     
    27     
    28     // build the player's shape
    28     // build the player's shape
    29     // XXX: these dimensions are incorrect...
    29     // XXX: these dimensions are incorrect...
    30     std::vector<Vector> shape(4);
    30     std::vector<Vector> shape(4);
    50     Vector shotVelocity = unitVectorAim*shotspeed;
    50     Vector shotVelocity = unitVectorAim*shotspeed;
    51     new Projectile(this->state, this->position, shotVelocity, false, radius, 1);
    51     new Projectile(this->state, this->position, shotVelocity, false, radius, 1);
    52 
    52 
    53 }
    53 }
    54 
    54 
    55 void Player::debugInfo (void) {
    55 void Player::handleShoot (Weapon &weapon) {
    56     Engine::log(DEBUG, "Player.debugInfo") << "In air: " << this->inAir;
    56     Vector unitVectorAim = (facingRight ? 
    57 }
    57         Vector(std::cos(aim), -std::sin(aim)) : 
    58 
    58         Vector(-std::cos(aim), -std::sin(aim))
    59 /**
    59     );
    60  * shoots the selected weapon.
    60     
    61  * TODO: selection and weapon information
    61     // XXX: what does the PHYSICS_TICK_MS stuff mean?
    62  */
    62     float shotspeed = weapon.getVelocity() * PHYSICS_TICK_MS / 2;
    63 void LocalPlayer::shoot (void) {
    63 
    64     // here should be somehow considered which projectile it is
       
    65     if(!canShoot())
       
    66         return;
       
    67     reloadTimer += getWeapon().reloadTime;
       
    68     Vector unitVectorAim = facingRight ? Vector(std::cos(aim), -std::sin(aim)) : 
       
    69             Vector(-std::cos(aim), -std::sin(aim));
       
    70     float shotspeed = getWeapon().velocity*PHYSICS_TICK_MS/2;
       
    71     Vector shotRelativeVelocity = unitVectorAim * shotspeed;
    64     Vector shotRelativeVelocity = unitVectorAim * shotspeed;
    72     Vector shotVelocity = this->velocity + shotRelativeVelocity;
    65     Vector shotVelocity = this->velocity + shotRelativeVelocity;
    73     Vector shotPosition = this->position + unitVectorAim*10;
    66     Vector shotPosition = this->position + unitVectorAim * 10;
    74     new Projectile(this->state, shotPosition, shotVelocity, true, getWeapon().explosionRadius);
    67     
    75 }
    68     weapon.shoot(shotPosition, shotVelocity);
    76 
    69 }
    77 void LocalPlayer::handleMove (PlayerInput_Move input) {
    70 
    78     float fx = 0; // Force in x-direction
    71 void Player::printDebugInfo (void) {
    79     float da = 0; // Crosshair angle
    72     Engine::log(DEBUG, "layer.debug") << "In air: " << this->inAir;
    80 
    73 }
    81     // handle left/right
    74         
    82     if ((input & INPUT_MOVE_LEFT) && (velocity.x > -PLAYER_MAX_SPEED))
    75 void Player::tick (TimeMS dt) {
    83         fx -= PLAYER_MOVE_FORCE;
    76     // let PhysicsObject execute
    84 
    77     PhysicsObject::tick(dt);
    85     if ((input & INPUT_MOVE_RIGHT) && (velocity.x < PLAYER_MAX_SPEED))
    78     
    86         fx += PLAYER_MOVE_FORCE;
    79     // tick current weapon reload
    87 
    80     getWeapon().tickReload(dt);
    88     if (input & INPUT_MOVE_UP)
    81 }
    89         da += CROSSHAIR_ANGLE_SPEED;
    82 
    90 
    83 void LocalPlayer::handleInput (PlayerInput input) {
    91     if (input & INPUT_MOVE_DOWN)
    84     // Movement force, vertical is always zero
    92         da -= CROSSHAIR_ANGLE_SPEED;
    85     Vector move_force = Vector(0, 0); 
    93 
    86 
    94     if (input & INPUT_MOVE_JUMP) {
    87     // Crosshair angle change
    95         if ((input & INPUT_MOVE_LEFT))
    88     float aim_delta = 0; 
       
    89 
       
    90     // handle movement left/right by applying a horizontal force, but limit the player's speed
       
    91     if ((input & INPUT_MOVE_LEFT) && (velocity.x > -PLAYER_MAX_SPEED)) {
       
    92         setFacing(false);
       
    93         move_force.x -= PLAYER_MOVE_FORCE;
       
    94 
       
    95     }
       
    96 
       
    97     if ((input & INPUT_MOVE_RIGHT) && (velocity.x < PLAYER_MAX_SPEED)) {
       
    98         setFacing(true);
       
    99         move_force.x += PLAYER_MOVE_FORCE;
       
   100     }
       
   101 
       
   102     // handle aim by creating a aim angle delta
       
   103     if (input & INPUT_AIM_UP)
       
   104         aim_delta += CROSSHAIR_ANGLE_SPEED;
       
   105 
       
   106     if (input & INPUT_AIM_DOWN)
       
   107         aim_delta -= CROSSHAIR_ANGLE_SPEED;
       
   108     
       
   109     // handle jumping by invoking the jump method
       
   110     // XXX: the direction should ideally be given using some other method
       
   111     if (input & INPUT_JUMP) {
       
   112         if (input & INPUT_MOVE_LEFT)
    96             jump(-1);
   113             jump(-1);
    97         else if ((input & INPUT_MOVE_RIGHT))
   114 
       
   115         else if (input & INPUT_MOVE_RIGHT)
    98             jump(1);
   116             jump(1);
       
   117 
    99         else
   118         else
   100             jump(0);
   119             jump(0);
   101     }
   120     }
   102 
   121     
   103     if (input & INPUT_MOVE_DIG) {
   122     // outsource digging to Player::handleDig, since this modifies the Terrain and Network needs to know
       
   123     if (input & INPUT_DIG) {
       
   124         handleDig(position, 15);
       
   125 
   104         // Should create Projectile which destroys ground, but also should be destroyed then,
   126         // Should create Projectile which destroys ground, but also should be destroyed then,
   105         // but it doesn't.
   127         // but it doesn't.
   106         // But this now just segfaults
   128         // But this now just segfaults
   107 //        world.addObject(new Projectile(state, position, true));
   129 //        world.addObject(new Projectile(state, position, true));
   108 
   130     }
   109         handleDig(position, 15);
   131     
   110     }
   132     // XXX: currently not network safe
   111 
       
   112     if (input & INPUT_CHANGE) {
   133     if (input & INPUT_CHANGE) {
   113         if(changing) {
   134         if (changing) {
   114 
   135 
   115         } else {
   136         } else {
   116             changing = true;
   137             changing = true;
   117             selectedWeapon = (selectedWeapon+1)%arsenal.size();
   138             selectedWeapon = (selectedWeapon + 1) % arsenal.size();
   118             Engine::log(DEBUG, "Player.cc:input ") << "changed weapon " << selectedWeapon;
   139             Engine::log(DEBUG, "Player.cc:input ") << "changed weapon " << selectedWeapon;
   119         }
   140         }
   120     } else {
   141     } else {
   121         changing = false;
   142         changing = false;
   122     }
   143     }
   123 
   144     
   124     if (input & INPUT_SHOOT) {
   145     // validate shoot events, and then outsource to handleShoot so Network can intercept it
   125         this->shoot();
   146     if (input & INPUT_SHOOT && getWeapon().canShoot()) {
   126     }
   147         this->handleShoot(getWeapon());
   127 
   148     }
   128 
   149     
   129 
   150     // XXX: how should this be written?
   130     // Player facing
   151     if (move_force.x != 0) 
   131     if (fx < 0) setFacing(false);
   152         animation_step = (animation_step + 1) % img_num_step;
   132     else if (fx > 0) setFacing(true);
   153 
   133 
   154     // apply aim delta
   134     if (fx != 0) animation_step = (animation_step+1)%img_num_step;
   155     if (aim_delta)
   135 
   156         changeAim(aim_delta);
   136 
   157 
   137     this->changeAim(da); // Move crosshair
   158     // apply force
   138 
   159     if (!move_force.zero())
   139     // Apply force
   160         applyForce(move_force);
   140     applyForce(Vector(fx, 0));
       
   141 
       
   142 }
   161 }
   143 
   162 
   144 Weapon& Player::getWeapon() {
   163 Weapon& Player::getWeapon() {
   145     return arsenal[selectedWeapon%arsenal.size()];
   164     return arsenal[selectedWeapon % arsenal.size()];
   146 }
   165 }
   147 
   166 
   148 void Player::draw(CL_GraphicContext *gc) {
   167 void Player::draw (CL_GraphicContext *gc) {
   149     int aim_img_idx = (int)((1 - (getAim()+KG_PI/2)/KG_PI)*img_num_aim);
   168     int aim_img_idx = (int)((1 - (getAim()+KG_PI/2)/KG_PI)*img_num_aim);
   150     int step_img_idx = animation_step%img_num_step;
   169     int step_img_idx = animation_step%img_num_step;
   151 
   170 
   152     // load skin image if not yet loaded
   171     // load skin image if not yet loaded
   153     if (!skin_loaded) {
   172     if (!skin_loaded) {
   154         skin_surface = CL_Surface(PLAYER_SKIN_PATH);
   173         skin_surface = CL_Surface(PLAYER_SKIN_PATH);
   155         skin_loaded = true;
   174         skin_loaded = true;
   156     }
   175     }
   157 
   176     
       
   177     // XXX: this logic looks weird
   158     CL_Rectf destination(position.x - 4, position.y - 4, position.x + 5, position.y + 4);
   178     CL_Rectf destination(position.x - 4, position.y - 4, position.x + 5, position.y + 4);
   159 
   179 
   160     if (!getFacing()) {
   180     if (!getFacing()) {
   161         destination = CL_Rect(position.x + 5, position.y - 4, position.x - 4, position.y + 4);
   181         destination = CL_Rect(position.x + 5, position.y - 4, position.x - 4, position.y + 4);
   162     }
   182     }
   163 
   183 
   164     skin_surface.draw_subpixel(
   184     skin_surface.draw_subpixel(
   165             CL_Rectf(1+step_img_idx*img_width, aim_img_idx*img_height+1, 1+(1+step_img_idx)*img_width, (aim_img_idx+1)*img_height+1), 
   185             CL_Rectf(
   166             destination, 
   186                 1 + step_img_idx * img_width, 
   167             gc);
   187                 aim_img_idx * img_height + 1, 
       
   188                 1 + (1 + step_img_idx) * img_width, 
       
   189                 (aim_img_idx + 1) * img_height + 1
       
   190             ), 
       
   191             destination, gc
       
   192     );
   168     
   193     
   169     const uint16_t chlen = 10;
   194     const uint16_t chlen = 10;
   170     uint16_t x = position.x;
   195     uint16_t x = position.x;
   171     uint16_t y = position.y;
   196     uint16_t y = position.y;
   172     
   197