void Player::handle_horizontal_input() { float vx = physic.get_velocity_x(); float vy = physic.get_velocity_y(); float ax = physic.get_acceleration_x(); float ay = physic.get_acceleration_y(); float dirsign = 0; if(!duck || physic.get_velocity_y() != 0) { if(controller->hold(Controller::LEFT) && !controller->hold(Controller::RIGHT)) { old_dir = dir; dir = LEFT; dirsign = -1; } else if(!controller->hold(Controller::LEFT) && controller->hold(Controller::RIGHT)) { old_dir = dir; dir = RIGHT; dirsign = 1; } } if (!controller->hold(Controller::ACTION)) { ax = dirsign * WALK_ACCELERATION_X; // limit speed if(vx >= MAX_WALK_XM && dirsign > 0) { vx = MAX_WALK_XM; ax = 0; } else if(vx <= -MAX_WALK_XM && dirsign < 0) { vx = -MAX_WALK_XM; ax = 0; } } else { ax = dirsign * RUN_ACCELERATION_X; // limit speed if(vx >= MAX_RUN_XM && dirsign > 0) { vx = MAX_RUN_XM; ax = 0; } else if(vx <= -MAX_RUN_XM && dirsign < 0) { vx = -MAX_RUN_XM; ax = 0; } } // we can reach WALK_SPEED without any acceleration if(dirsign != 0 && fabs(vx) < WALK_SPEED) { vx = dirsign * WALK_SPEED; } // changing directions? if(on_ground() && ((vx < 0 && dirsign >0) || (vx>0 && dirsign<0))) { // let's skid! if(fabs(vx)>SKID_XM && !skidding_timer.started()) { skidding_timer.start(SKID_TIME); sound_manager->play("sounds/skid.wav"); // dust some particles Sector::current()->add_object( new Particles( Vector(dir == RIGHT ? get_bbox().p2.x : get_bbox().p1.x, get_bbox().p2.y), dir == RIGHT ? 270+20 : 90-40, dir == RIGHT ? 270+40 : 90-20, Vector(280, -260), Vector(0, 300), 3, Color(.4, .4, .4), 3, .8, LAYER_OBJECTS+1)); ax *= 2.5; } else { ax *= 2; } } physic.set_velocity(vx, vy); physic.set_acceleration(ax, ay); // we get slower when not pressing any keys if(dirsign == 0) { apply_friction(); } }
void Player::handle_horizontal_input() { float vx = physic.get_velocity_x(); float vy = physic.get_velocity_y(); float ax = physic.get_acceleration_x(); float ay = physic.get_acceleration_y(); float dirsign = 0; if(!duck || physic.get_velocity_y() != 0) { if((controller->hold(Controller::LEFT) && !controller->hold(Controller::RIGHT)) || jump_helper_move_left) { old_dir = dir; dir = LEFT; dirsign = -1; } else if((!controller->hold(Controller::LEFT) && controller->hold(Controller::RIGHT)) || jump_helper_move_right) { old_dir = dir; dir = RIGHT; dirsign = 1; } } // do not run if we're holding something which slows us down if ( grabbed_object && grabbed_object->is_hampering() ) { ax = dirsign * WALK_ACCELERATION_X; // limit speed if(vx >= MAX_WALK_XM && dirsign > 0) { vx = MAX_WALK_XM; ax = 0; } else if(vx <= -MAX_WALK_XM && dirsign < 0) { vx = -MAX_WALK_XM; ax = 0; } } else { if( vx * dirsign < MAX_WALK_XM ) { ax = dirsign * WALK_ACCELERATION_X; } else { ax = dirsign * RUN_ACCELERATION_X; } // limit speed if(vx >= MAX_RUN_XM && dirsign > 0) { vx = MAX_RUN_XM; ax = 0; } else if(vx <= -MAX_RUN_XM && dirsign < 0) { vx = -MAX_RUN_XM; ax = 0; } } // we can reach WALK_SPEED without any acceleration if(dirsign != 0 && fabs(vx) < WALK_SPEED) { vx = dirsign * WALK_SPEED; } //Check speedlimit. if( speedlimit > 0 && vx * dirsign >= speedlimit ) { vx = dirsign * speedlimit; ax = 0; } // changing directions? if(on_ground() && ((vx < 0 && dirsign >0) || (vx>0 && dirsign<0))) { // let's skid! if(fabs(vx)>SKID_XM && !skidding_timer.started()) { skidding_timer.start(SKID_TIME); SoundManager::current()->play("sounds/skid.wav"); // dust some particles Sector::current()->add_object( std::make_shared<Particles>( Vector(dir == RIGHT ? get_bbox().p2.x : get_bbox().p1.x, get_bbox().p2.y), dir == RIGHT ? 270+20 : 90-40, dir == RIGHT ? 270+40 : 90-20, Vector(280, -260), Vector(0, 300), 3, Color(.4f, .4f, .4f), 3, .8f, LAYER_OBJECTS+1)); ax *= 2.5; } else { ax *= 2; } } if(on_ice) { ax *= ICE_ACCELERATION_MULTIPLIER; } physic.set_velocity(vx, vy); physic.set_acceleration(ax, ay); // we get slower when not pressing any keys if(dirsign == 0) { apply_friction(); } }
void Player::update(float elapsed_time) { if(dying && dying_timer.check()) { dead = true; return; } if(!dying && !deactivated) handle_input(); // handle_input() calls apply_friction() when Tux is not walking, so we'll have to do this ourselves if (deactivated) apply_friction(); // extend/shrink tux collision rectangle so that we fall through/walk over 1 // tile holes if(fabsf(physic.get_velocity_x()) > MAX_WALK_XM) { set_width(34); } else { set_width(31.8); } // on downward slopes, adjust vertical velocity so tux walks smoothly down if (on_ground()) { if(floor_normal.y != 0) { if ((floor_normal.x * physic.get_velocity_x()) >= 0) { physic.set_velocity_y(250); } } } // handle backflipping if (backflipping) { //prevent player from changing direction when backflipping dir = (backflip_direction == 1) ? LEFT : RIGHT; if (backflip_timer.started()) physic.set_velocity_x(100 * backflip_direction); } // set fall mode... if(on_ground()) { fall_mode = ON_GROUND; last_ground_y = get_pos().y; } else { if(get_pos().y > last_ground_y) fall_mode = FALLING; else if(fall_mode == ON_GROUND) fall_mode = JUMPING; } // check if we landed if(on_ground()) { jumping = false; if (backflipping && (!backflip_timer.started())) { backflipping = false; backflip_direction = 0; // if controls are currently deactivated, we take care of standing up ourselves if (deactivated) do_standup(); } } #if 0 // Do butt jump if (butt_jump && on_ground() && is_big()) { // Add a smoke cloud if (duck) Sector::current()->add_smoke_cloud(Vector(get_pos().x - 32, get_pos().y)); else Sector::current()->add_smoke_cloud( Vector(get_pos().x - 32, get_pos().y + 32)); butt_jump = false; // Break bricks beneath Tux if(Sector::current()->trybreakbrick( Vector(base.x + 1, base.y + base.height), false) || Sector::current()->trybreakbrick( Vector(base.x + base.width - 1, base.y + base.height), false)) { physic.set_velocity_y(-2); butt_jump = true; } // Kill nearby badguys std::vector<GameObject*> gameobjects = Sector::current()->gameobjects; for (std::vector<GameObject*>::iterator i = gameobjects.begin(); i != gameobjects.end(); i++) { BadGuy* badguy = dynamic_cast<BadGuy*> (*i); if(badguy) { // don't kill when badguys are already dying or in a certain mode if(badguy->dying == DYING_NOT && badguy->mode != BadGuy::BOMB_TICKING && badguy->mode != BadGuy::BOMB_EXPLODE) { if (fabsf(base.x - badguy->base.x) < 96 && fabsf(base.y - badguy->base.y) < 64) badguy->kill_me(25); } } } } #endif // calculate movement for this frame movement = physic.get_movement(elapsed_time); if(grabbed_object != NULL && !dying) { Vector pos = get_pos() + Vector(dir == LEFT ? -16 : 16, get_bbox().get_height()*0.66666 - 32); grabbed_object->grab(*this, pos, dir); } if(grabbed_object != NULL && dying){ grabbed_object->ungrab(*this, dir); grabbed_object = NULL; } on_ground_flag = false; }