X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fobject%2Fplayer.cpp;h=935713860202a5f2ff992637dee94c1f3d237f30;hb=845dceca7faef5eec20976fbc482f7a7cda2b96b;hp=fcbe6584996acf02604068d370e92532a58dde2c;hpb=44c614038ecdc2d1b69a6fee255d9c0ebc2a5098;p=supertux.git diff --git a/src/object/player.cpp b/src/object/player.cpp index fcbe65849..935713860 100644 --- a/src/object/player.cpp +++ b/src/object/player.cpp @@ -23,22 +23,23 @@ #include #include -#include "app/globals.h" -#include "app/gettext.h" +#include "gettext.h" +#include "sprite/sprite_manager.h" #include "player.h" -#include "defines.h" -#include "scene.h" #include "tile.h" -#include "special/sprite.h" +#include "sprite/sprite.h" #include "sector.h" #include "resources.h" #include "video/screen.h" #include "statistics.h" -#include "gameloop.h" +#include "game_session.h" #include "object/tilemap.h" #include "object/camera.h" #include "object/gameobjs.h" +#include "object/portable.h" #include "trigger/trigger_base.h" +#include "control/joystickkeyboardcontroller.h" +#include "main.h" static const int TILES_FOR_BUTTJUMP = 3; static const float SHOOTING_TIME = .150; @@ -59,42 +60,11 @@ Surface* growingtux_right[GROWING_FRAMES]; Surface* tux_life = 0; -Sprite* smalltux_gameover = 0; -Sprite* smalltux_star = 0; -Sprite* bigtux_star = 0; - TuxBodyParts* small_tux = 0; TuxBodyParts* big_tux = 0; TuxBodyParts* fire_tux = 0; TuxBodyParts* ice_tux = 0; -PlayerKeymap keymap; - -PlayerKeymap::PlayerKeymap() -{ - keymap.up = SDLK_UP; - keymap.down = SDLK_DOWN; - keymap.left = SDLK_LEFT; - keymap.right = SDLK_RIGHT; - - keymap.power = SDLK_LCTRL; - keymap.jump = SDLK_SPACE; -} - -void player_input_init(player_input_type* pplayer_input) -{ - pplayer_input->up = UP; - pplayer_input->old_up = UP; - pplayer_input->down = UP; - pplayer_input->fire = UP; - pplayer_input->left = UP; - pplayer_input->old_fire = UP; - pplayer_input->right = UP; - pplayer_input->jump = UP; - pplayer_input->old_jump = UP; - pplayer_input->activate = UP; -} - void TuxBodyParts::set_action(std::string action, int loops) { @@ -122,31 +92,37 @@ TuxBodyParts::draw(DrawingContext& context, const Vector& pos, int layer, feet->draw(context, pos, layer-2, drawing_effect); } -Player::Player() +Player::Player(PlayerStatus* _player_status) + : player_status(_player_status), grabbed_object(0) { + controller = main_controller; + smalltux_gameover = sprite_manager->create("smalltux-gameover"); + smalltux_star = sprite_manager->create("smalltux-star"); + bigtux_star = sprite_manager->create("bigtux-star"); init(); } Player::~Player() { + delete smalltux_gameover; + delete smalltux_star; + delete bigtux_star; } void Player::init() { - holding_something = false; - - bbox.set_size(31.8, 31.8); - - size = SMALL; - got_power = NONE_POWER; + if(is_big()) + bbox.set_size(31.8, 63.8); + else + bbox.set_size(31.8, 31.8); dir = RIGHT; old_dir = dir; duck = false; dead = false; - dying = DYING_NOT; + dying = false; last_ground_y = 0; fall_mode = ON_GROUND; jumping = false; @@ -160,85 +136,21 @@ Player::init() flapping_velocity = 0; // temporary to help player's choosing a flapping - flapping_mode = MAREK_FLAP; + flapping_mode = NO_FLAP; // Ricardo's flapping flaps_nb = 0; on_ground_flag = false; - - player_input_init(&input); + grabbed_object = 0; physic.reset(); } -int -Player::key_event(SDLKey key, int state) -{ - idle_timer.start(IDLE_TIME, true); - - if(key == keymap.right) - { - input.right = state; - return true; - } - else if(key == keymap.left) - { - input.left = state; - return true; - } - else if(key == keymap.up) - { - if(state == UP) - input.old_up = UP; - input.up = state; - /* Up key also opens activates stuff */ - input.activate = state; - return true; - } - else if(key == keymap.down) - { - input.down = state; - return true; - } - else if(key == keymap.power) - { - if (state == UP) - input.old_fire = UP; - input.fire = state; - - return true; - } - else if(key == keymap.jump) - { - if (state == UP) - input.old_jump = UP; - input.jump = state; - return true; - } - else - return false; -} - void -Player::level_begin() -{ - move(Vector(100, 170)); - duck = false; - - dying = DYING_NOT; - - player_input_init(&input); - - on_ground_flag = false; - - physic.reset(); -} - -PlayerStatus& -Player::get_status() +Player::set_controller(Controller* controller) { - return player_status; + this->controller = controller; } void @@ -249,44 +161,44 @@ Player::action(float elapsed_time) return; } - if (input.fire == UP) - holding_something = false; + if(!controller->hold(Controller::ACTION) && grabbed_object) { + grabbed_object = 0; + // move the grabbed object a bit away from tux + Vector pos = get_pos() + + Vector(dir == LEFT ? -bbox.get_width() : bbox.get_width(), + bbox.get_height()*0.66666 - 32); + MovingObject* object = dynamic_cast (grabbed_object); + if(object) { + object->set_pos(pos); + } else { +#ifdef DEBUG + std::cout << "Non MovingObjetc grabbed?!?\n"; +#endif + } + } - if(dying == DYING_NOT) + if(!dying) handle_input(); movement = physic.get_movement(elapsed_time); + on_ground_flag = false; #if 0 - // special exception for cases where we're stuck under tiles after - // being ducked. In this case we drift out - if(!duck && on_ground() && old_base.x == base.x && old_base.y == base.y - && collision_object_map(base)) - { - base.x += elapsed_time * WALK_SPEED * (dir ? 1: -1); - previous_base = old_base = base; - } - - /* Reset score multiplier (for multi-hits): */ - if (!invincible_timer.started()) - { - if(player_status.score_multiplier > player_status.max_score_multiplier) - { - player_status.max_score_multiplier = player_status.score_multiplier; - - // show a message - char str[124]; - sprintf(str, _("New max combo: %d"), player_status.max_score_multiplier-1); - Sector::current()->add_floating_text(base, str); - } - player_status.score_multiplier = 1; - } - } - - } + // special exception for cases where we're stuck under tiles after + // being ducked. In this case we drift out + if(!duck && on_ground() && old_base.x == base.x && old_base.y == base.y + && collision_object_map(base)) { + base.x += elapsed_time * WALK_SPEED * (dir ? 1: -1); + previous_base = old_base = base; + } #endif - on_ground_flag = false; + if(grabbed_object != 0) { + Vector pos = get_pos() + + Vector(dir == LEFT ? -16 : 16, + bbox.get_height()*0.66666 - 32); + grabbed_object->grab(*this, pos); + } } bool @@ -295,6 +207,15 @@ Player::on_ground() return on_ground_flag; } +bool +Player::is_big() +{ + if(player_status->bonus == NO_BONUS) + return false; + + return true; +} + void Player::handle_horizontal_input() { @@ -304,36 +225,39 @@ Player::handle_horizontal_input() float ay = physic.get_acceleration_y(); float dirsign = 0; - if(input.left == DOWN && input.right == UP && (!duck || physic.get_velocity_y() != 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(input.left == UP && input.right == DOWN && (!duck || physic.get_velocity_y() != 0)) { + } else if(!controller->hold(Controller::LEFT) + && controller->hold(Controller::RIGHT)) { old_dir = dir; dir = RIGHT; dirsign = 1; + } } - if (input.fire == UP) { - 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; - } + 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; - } + 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 @@ -342,40 +266,36 @@ Player::handle_horizontal_input() } // 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::get()->play_sound(IDToSound(SND_SKID)); - // dust some partcles - Sector::current()->add_object( - new Particles( - Vector(bbox.p1.x + (dir == RIGHT ? bbox.get_width() : 0), - bbox.p2.y), - dir == RIGHT ? 270+20 : 90-40, dir == RIGHT ? 270+40 : 90-20, - Vector(280,-260), Vector(0,0.030), 3, Color(100,100,100), 3, .8, - LAYER_OBJECTS+1)); - - ax *= 2.5; - } - else - { - ax *= 2; - } + 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_sound("skid"); + // dust some partcles + Sector::current()->add_object( + new Particles( + Vector(bbox.p1.x + (dir == RIGHT ? bbox.get_width() : 0), + bbox.p2.y), + dir == RIGHT ? 270+20 : 90-40, dir == RIGHT ? 270+40 : 90-20, + Vector(280,-260), Vector(0,0.030), 3, Color(100,100,100), 3, .8, + LAYER_OBJECTS+1)); + + ax *= 2.5; + } else { + ax *= 2; } + } // we get slower when not pressing any keys if(dirsign == 0) { - if(fabs(vx) < WALK_SPEED) { - vx = 0; - ax = 0; - } else if(vx < 0) { - ax = WALK_ACCELERATION_X * 1.5; - } else { - ax = WALK_ACCELERATION_X * -1.5; - } + if(fabs(vx) < WALK_SPEED) { + vx = 0; + ax = 0; + } else if(vx < 0) { + ax = WALK_ACCELERATION_X * 1.5; + } else { + ax = WALK_ACCELERATION_X * -1.5; + } } #if 0 @@ -431,199 +351,167 @@ Player::handle_vertical_input() } // Press jump key - if(input.jump == DOWN && can_jump && on_ground()) + if(controller->pressed(Controller::JUMP) && can_jump && on_ground()) { + if(duck) { // only jump a little bit when in duck mode { + physic.set_velocity_y(300); + } else { + // jump higher if we are running + if (fabs(physic.get_velocity_x()) > MAX_WALK_XM) + physic.set_velocity_y(580); + else + physic.set_velocity_y(520); + } + + //bbox.move(Vector(0, -1)); + jumping = true; + flapping = false; + can_jump = false; + can_flap = false; + flaps_nb = 0; // Ricardo's flapping + if (is_big()) + sound_manager->play_sound("bigjump"); + else + sound_manager->play_sound("jump"); + } else if(!controller->hold(Controller::JUMP)) { // Let go of jump key + if (!flapping && !duck && !falling_from_flap && !on_ground()) { + can_flap = true; + } + if (jumping && physic.get_velocity_y() > 0) { + jumping = false; + physic.set_velocity_y(0); + } + } + + // temporary to help player's choosing a flapping + if(flapping_mode == RICARDO_FLAP) { + // Flapping, Ricardo's version + // similar to SM3 Fox + if(controller->pressed(Controller::JUMP) && can_flap && flaps_nb < 3) { + physic.set_velocity_y(350); + physic.set_velocity_x(physic.get_velocity_x() * 35); + flaps_nb++; + } + } else if(flapping_mode == MAREK_FLAP) { + // Flapping, Marek's version + if (controller->hold(Controller::JUMP) && can_flap) { - if(duck) { // only jump a little bit when in duck mode { - physic.set_velocity_y(300); - } else { - // jump higher if we are running - if (fabs(physic.get_velocity_x()) > MAX_WALK_XM) - physic.set_velocity_y(580); - else - physic.set_velocity_y(520); + if (!flapping_timer.started()) + { + flapping_timer.start(TUX_FLAPPING_TIME); + flapping_velocity = physic.get_velocity_x(); + } + if (flapping_timer.check()) + { + can_flap = false; + falling_from_flap = true; } - - //bbox.move(Vector(0, -1)); jumping = true; - flapping = false; - can_jump = false; - can_flap = false; - flaps_nb = 0; // Ricardo's flapping - if (size == SMALL) - SoundManager::get()->play_sound(IDToSound(SND_JUMP)); - else - SoundManager::get()->play_sound(IDToSound(SND_BIGJUMP)); + flapping = true; + if (!flapping_timer.check()) { + float cv = flapping_velocity * sqrt( + TUX_FLAPPING_TIME - flapping_timer.get_timegone() + / TUX_FLAPPING_TIME); + + //Handle change of direction while flapping + if (((dir == LEFT) && (cv > 0)) || (dir == RIGHT) && (cv < 0)) { + cv *= (-1); + } + physic.set_velocity_x(cv); + physic.set_velocity_y( + flapping_timer.get_timegone()/.850); + } } - // Let go of jump key - else if(input.jump == UP) + } else if(flapping_mode == RYAN_FLAP) { + // Flapping, Ryan's version + if (controller->hold(Controller::JUMP) && can_flap) { - if (!flapping && !duck && !falling_from_flap && !on_ground()) - { - can_flap = true; - } - if (jumping && physic.get_velocity_y() > 0) - { - jumping = false; - physic.set_velocity_y(0); - } - } - - // temporary to help player's choosing a flapping - if(flapping_mode == RICARDO_FLAP) - { - // Flapping, Ricardo's version - // similar to SM3 Fox - if(input.jump == DOWN && input.old_jump == UP && can_flap && - flaps_nb < 3) - { - physic.set_velocity_y(350); - physic.set_velocity_x(physic.get_velocity_x() * 35); - flaps_nb++; - } - } - else if(flapping_mode == MAREK_FLAP) - { - // Flapping, Marek's version - if (input.jump == DOWN && can_flap) - { - if (!flapping_timer.started()) - { - flapping_timer.start(TUX_FLAPPING_TIME); - flapping_velocity = physic.get_velocity_x(); - } - if (flapping_timer.check()) - { - can_flap = false; - falling_from_flap = true; - } - jumping = true; - flapping = true; - if (!flapping_timer.check()) { - float cv = flapping_velocity * sqrt( - TUX_FLAPPING_TIME - flapping_timer.get_timegone() - / TUX_FLAPPING_TIME); - - //Handle change of direction while flapping - if (((dir == LEFT) && (cv > 0)) || (dir == RIGHT) && (cv < 0)) { - cv *= (-1); - } - physic.set_velocity_x(cv); - physic.set_velocity_y( - flapping_timer.get_timegone()/.850); - } - } - } - else if(flapping_mode == RYAN_FLAP) - { - // Flapping, Ryan's version - if (input.jump == DOWN && can_flap) - { - if (!flapping_timer.started()) - { - flapping_timer.start(TUX_FLAPPING_TIME); - } - if (flapping_timer.check()) - { - can_flap = false; - falling_from_flap = true; - } - jumping = true; - flapping = true; - if (flapping && flapping_timer.get_timegone() <= TUX_FLAPPING_TIME - && physic.get_velocity_y() < 0) - { - float gravity = Sector::current()->gravity; - (void)gravity; - float xr = (fabsf(physic.get_velocity_x()) / MAX_RUN_XM); - - // XXX: magic numbers. should be a percent of gravity - // gravity is (by default) -0.1f - physic.set_acceleration_y(12 + 1*xr); - -#if 0 - // To slow down x-vel when flapping (not working) - if (fabsf(physic.get_velocity_x()) > MAX_WALK_XM) - { - if (physic.get_velocity_x() < 0) - physic.set_acceleration_x(1.0f); - else if (physic.get_velocity_x() > 0) - physic.set_acceleration_x(-1.0f); - } -#endif - } - } - else - { - physic.set_acceleration_y(0); - } - } - - // Hover - //(disabled by default, use cheat code "hover" to toggle on/off) - //TODO: needs some tweaking, especially when used together with double jump and jumping off badguys - if (enable_hover && input.jump == DOWN && !jumping && !butt_jump && physic.get_velocity_y() <= 0) + if (!flapping_timer.started()) { - physic.set_velocity_y(-100); + flapping_timer.start(TUX_FLAPPING_TIME); } - + if (flapping_timer.check()) + { + can_flap = false; + falling_from_flap = true; + } + jumping = true; + flapping = true; + if (flapping && flapping_timer.get_timegone() <= TUX_FLAPPING_TIME + && physic.get_velocity_y() < 0) + { + float gravity = Sector::current()->gravity; + (void)gravity; + float xr = (fabsf(physic.get_velocity_x()) / MAX_RUN_XM); + + // XXX: magic numbers. should be a percent of gravity + // gravity is (by default) -0.1f + physic.set_acceleration_y(12 + 1*xr); + #if 0 - /* In case the player has pressed Down while in a certain range of air, - enable butt jump action */ - if (input.down == DOWN && !butt_jump && !duck) - if(tiles_on_air(TILES_FOR_BUTTJUMP) && jumping) - butt_jump = true; + // To slow down x-vel when flapping (not working) + if (fabsf(physic.get_velocity_x()) > MAX_WALK_XM) + { + if (physic.get_velocity_x() < 0) + physic.set_acceleration_x(1.0f); + else if (physic.get_velocity_x() > 0) + physic.set_acceleration_x(-1.0f); + } #endif + } + } else { + physic.set_acceleration_y(0); + } + } - /* When Down is not held anymore, disable butt jump */ - if(butt_jump && input.down == UP) + /* In case the player has pressed Down while in a certain range of air, + enable butt jump action */ + if (controller->hold(Controller::DOWN) && !butt_jump && !duck) + //if(tiles_on_air(TILES_FOR_BUTTJUMP) && jumping) + butt_jump = true; + + /* When Down is not held anymore, disable butt jump */ + if(butt_jump && !controller->hold(Controller::DOWN)) butt_jump = false; - + +#if 0 // Do butt jump - if (butt_jump && on_ground() && size == BIG) - { + 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)); + Vector(get_pos().x - 32, get_pos().y + 32)); butt_jump = false; - -#if 0 + // 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)) - { + 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; } -#endif - -#if 0 + // Kill nearby badguys std::vector gameobjects = Sector::current()->gameobjects; for (std::vector::iterator i = gameobjects.begin(); i != gameobjects.end(); - i++) - { + i++) { BadGuy* badguy = dynamic_cast (*i); - if(badguy) - { + 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); - } + 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 } +#endif /** jumping is only allowed if we're about to touch ground soon and if the * button has been up in between the last jump @@ -637,14 +525,11 @@ Player::handle_vertical_input() get_pos().y + bbox.get_height() + 64)) && jumping == false && can_jump == false - && input.jump == DOWN - && input.old_jump == UP) + && input.jump && !input.old_jump) { can_jump = true; } #endif - - input.old_jump = input.jump; } void @@ -654,66 +539,58 @@ Player::handle_input() handle_horizontal_input(); /* Jump/jumping? */ - if (on_ground() && input.jump == UP) + if (on_ground() && !controller->hold(Controller::JUMP)) can_jump = true; handle_vertical_input(); /* Shoot! */ - if (input.fire == DOWN && input.old_fire == UP && got_power != NONE_POWER) { + if (controller->pressed(Controller::ACTION) && player_status->bonus == FIRE_BONUS) { if(Sector::current()->add_bullet( -// get_pos() + Vector(0, bbox.get_height()/2), - get_pos() + ((dir == LEFT)? Vector(0, bbox.get_height()/2) - : Vector(32, bbox.get_height()/2)), - physic.get_velocity_x(), dir)) + get_pos() + ((dir == LEFT)? Vector(0, bbox.get_height()/2) + : Vector(32, bbox.get_height()/2)), + physic.get_velocity_x(), dir)) shooting_timer.start(SHOOTING_TIME); - input.old_fire = DOWN; } - + /* Duck! */ - if (input.down == DOWN && size == BIG && !duck - && physic.get_velocity_y() == 0 && on_ground()) - { - duck = true; + if (controller->hold(Controller::DOWN) && is_big() && !duck + && physic.get_velocity_y() == 0 && on_ground()) { + duck = true; + bbox.move(Vector(0, 32)); + bbox.set_height(31.8); + } else if(!controller->hold(Controller::DOWN) && is_big() && duck) { + // try if we can really unduck + bbox.move(Vector(0, -32)); + bbox.set_height(63.8); + duck = false; + // FIXME +#if 0 + // when unducking in air we need some space to do so + if(on_ground() || !collision_object_map(bbox)) { + duck = false; + } else { + // undo the ducking changes bbox.move(Vector(0, 32)); bbox.set_height(31.8); } - else if(input.down == UP && size == BIG && duck) - { - // try if we can really unduck - bbox.move(Vector(0, -32)); - bbox.set_height(63.8); - duck = false; - // FIXME -#if 0 - // when unducking in air we need some space to do so - if(on_ground() || !collision_object_map(bbox)) { - duck = false; - } else { - // undo the ducking changes - bbox.move(Vector(0, 32)); - bbox.set_height(31.8); - } #endif - } + } } void -Player::grow(bool animate) +Player::set_bonus(BonusType type, bool animate) { - if(size == BIG) + if(player_status->bonus == type) return; - size = BIG; - bbox.set_height(63.8); - bbox.move(Vector(0, -32)); - - if(animate) - growing_timer.start(GROWING_TIME); -} - -void -Player::grabdistros() -{ + if(player_status->bonus == NO_BONUS) { + bbox.set_height(63.8); + bbox.move(Vector(0, -32)); + if(animate) + growing_timer.start(GROWING_TIME); + } + + player_status->bonus = type; } void @@ -721,19 +598,19 @@ Player::draw(DrawingContext& context) { TuxBodyParts* tux_body; - if (size == SMALL) - tux_body = small_tux; - else if (got_power == FIRE_POWER) + if (player_status->bonus == GROWUP_BONUS) + tux_body = big_tux; + else if (player_status->bonus == FIRE_BONUS) tux_body = fire_tux; - else if (got_power == ICE_POWER) + else if (player_status->bonus == ICE_BONUS) tux_body = ice_tux; else - tux_body = big_tux; + tux_body = small_tux; int layer = LAYER_OBJECTS + 10; /* Set Tux sprite action */ - if (duck && size == BIG) + if (duck && is_big()) { if(dir == LEFT) tux_body->set_action("duck-left"); @@ -754,7 +631,7 @@ Player::draw(DrawingContext& context) else // dir == RIGHT tux_body->set_action("kick-right"); } - else if (butt_jump && size == BIG) + else if (butt_jump && is_big()) { if(dir == LEFT) tux_body->set_action("buttjump-left"); @@ -788,7 +665,7 @@ Player::draw(DrawingContext& context) if(idle_timer.check()) { - if(size == BIG) + if(is_big()) { if(dir == LEFT) tux_body->head->set_action("idle-left", 1); @@ -799,7 +676,7 @@ Player::draw(DrawingContext& context) } // Tux is holding something - if ((holding_something && physic.get_velocity_y() == 0) || + if ((grabbed_object != 0 && physic.get_velocity_y() == 0) || (shooting_timer.get_timeleft() > 0 && !shooting_timer.check())) { if (duck) @@ -819,10 +696,10 @@ Player::draw(DrawingContext& context) } /* Draw Tux */ - if (dying == DYING_SQUISHED) { - smalltux_gameover->draw(context, get_pos(), LAYER_FOREGROUNDTILES+1); + if(dying) { + smalltux_gameover->draw(context, get_pos(), layer); } else if(growing_timer.get_timeleft() > 0) { - if(size == SMALL) + if(!is_big()) { if (dir == RIGHT) context.draw_surface(growingtux_right[GROWING_FRAMES-1 - @@ -857,21 +734,23 @@ Player::draw(DrawingContext& context) || size_t(global_time*20)%2) && !dying) { - if (size == SMALL || duck) + if (!is_big() || duck) smalltux_star->draw(context, get_pos(), layer + 5); else bigtux_star->draw(context, get_pos(), layer + 5); - } - - if (debug_mode) - context.draw_filled_rect(get_pos(), - Vector(bbox.get_width(), bbox.get_height()), - Color(75,75,75, 150), LAYER_OBJECTS+20); + } } HitResponse Player::collision(GameObject& other, const CollisionHit& hit) { + Portable* portable = dynamic_cast (&other); + if(portable && grabbed_object == 0 && controller->hold(Controller::ACTION) + && fabsf(hit.normal.x) > .9) { + grabbed_object = portable; + return CONTINUE; + } + if(other.get_flags() & FLAG_SOLID) { if(hit.normal.y < 0) { // landed on floor? if (physic.get_velocity_y() < 0) @@ -890,7 +769,7 @@ Player::collision(GameObject& other, const CollisionHit& hit) TriggerBase* trigger = dynamic_cast (&other); if(trigger) { - if(input.up == DOWN && input.old_up == UP) + if(controller->pressed(Controller::UP)) trigger->event(*this, TriggerBase::EVENT_ACTIVATE); } @@ -900,7 +779,7 @@ Player::collision(GameObject& other, const CollisionHit& hit) void Player::make_invincible() { - SoundManager::get()->play_sound(IDToSound(SND_HERRING)); + sound_manager->play_sound("invincible"); invincible_timer.start(TUX_INVINCIBLE_TIME); Sector::current()->play_music(HERRING_MUSIC); } @@ -912,27 +791,29 @@ Player::kill(HurtMode mode) if(dying) return; - if(safe_timer.get_timeleft() > 0 || invincible_timer.get_timeleft() > 0) + if(mode != KILL && + safe_timer.get_timeleft() > 0 || invincible_timer.get_timeleft() > 0) return; - SoundManager::get()->play_sound(IDToSound(SND_HURT)); + sound_manager->play_sound("hurt"); physic.set_velocity_x(0); - if (mode == SHRINK && size == BIG) + if (mode == SHRINK && is_big()) { - if (got_power != NONE_POWER) + if (player_status->bonus == FIRE_BONUS + || player_status->bonus == ICE_BONUS) { safe_timer.start(TUX_SAFE_TIME); - got_power = NONE_POWER; + player_status->bonus = GROWUP_BONUS; } - else + else { growing_timer.start(GROWING_TIME); safe_timer.start(TUX_SAFE_TIME + GROWING_TIME); - size = SMALL; bbox.set_height(31.8); duck = false; + player_status->bonus = NO_BONUS; } } else @@ -940,26 +821,27 @@ Player::kill(HurtMode mode) physic.enable_gravity(true); physic.set_acceleration(0, 0); physic.set_velocity(0, 700); - --player_status.lives; - dying = DYING_SQUISHED; + player_status->lives -= 1; + player_status->bonus = NO_BONUS; + dying = true; dying_timer.start(3.0); flags |= FLAG_NO_COLLDET; } } -/* Remove Tux's power ups */ -void -Player::remove_powerups() -{ - got_power = NONE_POWER; - size = SMALL; - bbox.set_height(31.8); -} - void Player::move(const Vector& vector) { bbox.set_pos(vector); + if(is_big()) + bbox.set_size(31.8, 63.8); + else + bbox.set_size(31.8, 31.8); + on_ground_flag = false; + duck = false; + last_ground_y = vector.y; + + physic.reset(); } void @@ -985,10 +867,10 @@ Player::check_bounds(Camera* camera) bbox.set_pos(Vector(camera->get_translation().x, get_pos().y)); adjust = true; } - if(get_pos().x >= camera->get_translation().x + screen->w - bbox.get_width()) + if(get_pos().x >= camera->get_translation().x + SCREEN_WIDTH - bbox.get_width()) { bbox.set_pos(Vector( - camera->get_translation().x + screen->w - bbox.get_width(), + camera->get_translation().x + SCREEN_WIDTH - bbox.get_width(), get_pos().y)); adjust = true; } @@ -1012,7 +894,7 @@ Player::bounce(BadGuy& ) flapping = false; falling_from_flap = false; - if (input.jump) + if(controller->hold(Controller::JUMP)) physic.set_velocity_y(520); else physic.set_velocity_y(200);