X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fobject%2Fplayer.cpp;h=92cd5880a46b84193c9c5311469a0fbd5a6db938;hb=e8a1d89d3d0f4824d3d906ca67149afec0a75e4b;hp=fcbe6584996acf02604068d370e92532a58dde2c;hpb=44c614038ecdc2d1b69a6fee255d9c0ebc2a5098;p=supertux.git diff --git a/src/object/player.cpp b/src/object/player.cpp index fcbe65849..92cd5880a 100644 --- a/src/object/player.cpp +++ b/src/object/player.cpp @@ -25,9 +25,8 @@ #include "app/globals.h" #include "app/gettext.h" +#include "special/sprite_manager.h" #include "player.h" -#include "defines.h" -#include "scene.h" #include "tile.h" #include "special/sprite.h" #include "sector.h" @@ -38,6 +37,7 @@ #include "object/tilemap.h" #include "object/camera.h" #include "object/gameobjs.h" +#include "object/portable.h" #include "trigger/trigger_base.h" static const int TILES_FOR_BUTTJUMP = 3; @@ -59,10 +59,6 @@ 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; @@ -81,18 +77,24 @@ PlayerKeymap::PlayerKeymap() keymap.jump = SDLK_SPACE; } -void player_input_init(player_input_type* pplayer_input) +PlayerInputType::PlayerInputType() { - 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; + reset(); +} + +void +PlayerInputType::reset() +{ + up = false; + old_up = false; + down = false; + fire = false; + old_fire = false; + left = false; + right = false; + jump = false; + old_jump = false; + activate = false; } void @@ -122,31 +124,36 @@ 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) { + 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,20 +167,20 @@ 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; + grabbed_object = 0; - player_input_init(&input); - + input.reset(); physic.reset(); } -int -Player::key_event(SDLKey key, int state) +bool +Player::key_event(SDLKey key, bool state) { idle_timer.start(IDLE_TIME, true); @@ -189,8 +196,8 @@ Player::key_event(SDLKey key, int state) } else if(key == keymap.up) { - if(state == UP) - input.old_up = UP; + if(state == false) + input.old_up = false; input.up = state; /* Up key also opens activates stuff */ input.activate = state; @@ -203,16 +210,16 @@ Player::key_event(SDLKey key, int state) } else if(key == keymap.power) { - if (state == UP) - input.old_fire = UP; + if(state == false) + input.old_fire = false; input.fire = state; return true; } else if(key == keymap.jump) { - if (state == UP) - input.old_jump = UP; + if(state == false) + input.old_jump = false; input.jump = state; return true; } @@ -221,27 +228,6 @@ Player::key_event(SDLKey key, int state) } 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() -{ - return player_status; -} - -void Player::action(float elapsed_time) { if(dying && dying_timer.check()) { @@ -249,44 +235,44 @@ Player::action(float elapsed_time) return; } - if (input.fire == UP) - holding_something = false; + if(input.fire == false && 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 +281,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 +299,38 @@ 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(input.left && !input.right) { old_dir = dir; dir = LEFT; dirsign = -1; - } else if(input.left == UP && input.right == DOWN && (!duck || physic.get_velocity_y() != 0)) { + } else if(!input.left && input.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 (!input.fire) { + 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 +339,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); + 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; } + } // 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,7 +424,7 @@ Player::handle_vertical_input() } // Press jump key - if(input.jump == DOWN && can_jump && on_ground()) + if(input.jump && can_jump && on_ground()) { if(duck) { // only jump a little bit when in duck mode { physic.set_velocity_y(300); @@ -449,13 +442,13 @@ Player::handle_vertical_input() can_jump = false; can_flap = false; flaps_nb = 0; // Ricardo's flapping - if (size == SMALL) - SoundManager::get()->play_sound(IDToSound(SND_JUMP)); - else + if (is_big()) SoundManager::get()->play_sound(IDToSound(SND_BIGJUMP)); + else + SoundManager::get()->play_sound(IDToSound(SND_JUMP)); } // Let go of jump key - else if(input.jump == UP) + else if(!input.jump) { if (!flapping && !duck && !falling_from_flap && !on_ground()) { @@ -473,8 +466,7 @@ Player::handle_vertical_input() { // Flapping, Ricardo's version // similar to SM3 Fox - if(input.jump == DOWN && input.old_jump == UP && can_flap && - flaps_nb < 3) + if(input.jump && !input.old_jump && can_flap && flaps_nb < 3) { physic.set_velocity_y(350); physic.set_velocity_x(physic.get_velocity_x() * 35); @@ -484,7 +476,7 @@ Player::handle_vertical_input() else if(flapping_mode == MAREK_FLAP) { // Flapping, Marek's version - if (input.jump == DOWN && can_flap) + if (input.jump && can_flap) { if (!flapping_timer.started()) { @@ -516,7 +508,7 @@ Player::handle_vertical_input() else if(flapping_mode == RYAN_FLAP) { // Flapping, Ryan's version - if (input.jump == DOWN && can_flap) + if (input.jump && can_flap) { if (!flapping_timer.started()) { @@ -558,28 +550,19 @@ Player::handle_vertical_input() } } - // 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) - { - physic.set_velocity_y(-100); - } - -#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) + if (input.down && !butt_jump && !duck) + //if(tiles_on_air(TILES_FOR_BUTTJUMP) && jumping) butt_jump = true; -#endif /* When Down is not held anymore, disable butt jump */ - if(butt_jump && input.down == UP) + if(butt_jump && !input.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) @@ -590,7 +573,6 @@ Player::handle_vertical_input() butt_jump = false; -#if 0 // Break bricks beneath Tux if(Sector::current()->trybreakbrick( Vector(base.x + 1, base.y + base.height), false) @@ -600,9 +582,7 @@ Player::handle_vertical_input() 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(); @@ -622,8 +602,8 @@ Player::handle_vertical_input() } } } -#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,13 +617,14 @@ 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 + // FIXME: why the heck is this here and not somewhere where the keys are + // checked?!? input.old_jump = input.jump; } @@ -654,30 +635,31 @@ Player::handle_input() handle_horizontal_input(); /* Jump/jumping? */ - if (on_ground() && input.jump == UP) + if (on_ground() && !input.jump) can_jump = true; handle_vertical_input(); /* Shoot! */ - if (input.fire == DOWN && input.old_fire == UP && got_power != NONE_POWER) { + if (input.fire && !input.old_fire && 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)) shooting_timer.start(SHOOTING_TIME); - input.old_fire = DOWN; + // FIXME: why the heck is this here + input.old_fire = false; } /* Duck! */ - if (input.down == DOWN && size == BIG && !duck + if (input.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(input.down == UP && size == BIG && duck) + else if(!input.down && is_big() && duck) { // try if we can really unduck bbox.move(Vector(0, -32)); @@ -698,22 +680,19 @@ Player::handle_input() } 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 +700,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 +733,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 +767,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 +778,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 +798,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,7 +836,7 @@ 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); @@ -872,6 +851,13 @@ Player::draw(DrawingContext& context) HitResponse Player::collision(GameObject& other, const CollisionHit& hit) { + Portable* portable = dynamic_cast (&other); + if(portable && grabbed_object == 0 && input.fire + && 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 +876,7 @@ Player::collision(GameObject& other, const CollisionHit& hit) TriggerBase* trigger = dynamic_cast (&other); if(trigger) { - if(input.up == DOWN && input.old_up == UP) + if(input.up && !input.old_up) trigger->event(*this, TriggerBase::EVENT_ACTIVATE); } @@ -919,20 +905,21 @@ Player::kill(HurtMode mode) 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 +927,28 @@ 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; + + input.reset(); + physic.reset(); } void @@ -985,10 +974,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; }