X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fobject%2Fplayer.cpp;h=1a8feb6f48a033519a89f7ee9ee5e54028ddb61b;hb=70fdbd45026801f0f0f312278c69b383eaca9d3a;hp=935713860202a5f2ff992637dee94c1f3d237f30;hpb=60908c905544776c376421b8d3e12eeb936c068f;p=supertux.git diff --git a/src/object/player.cpp b/src/object/player.cpp index 935713860..1a8feb6f4 100644 --- a/src/object/player.cpp +++ b/src/object/player.cpp @@ -23,23 +23,26 @@ #include #include -#include "gettext.h" -#include "sprite/sprite_manager.h" -#include "player.h" -#include "tile.h" -#include "sprite/sprite.h" -#include "sector.h" -#include "resources.h" -#include "video/screen.h" -#include "statistics.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" +#include "gettext.hpp" +#include "sprite/sprite_manager.hpp" +#include "audio/sound_manager.hpp" +#include "player.hpp" +#include "tile.hpp" +#include "sprite/sprite.hpp" +#include "sector.hpp" +#include "resources.hpp" +#include "video/screen.hpp" +#include "statistics.hpp" +#include "game_session.hpp" +#include "object/tilemap.hpp" +#include "object/camera.hpp" +#include "object/particles.hpp" +#include "object/portable.hpp" +#include "object/bullet.hpp" +#include "trigger/trigger_base.hpp" +#include "control/joystickkeyboardcontroller.hpp" +#include "main.hpp" +#include "player_status.hpp" static const int TILES_FOR_BUTTJUMP = 3; static const float SHOOTING_TIME = .150; @@ -54,6 +57,8 @@ static const float MAX_WALK_XM = 230; static const float MAX_RUN_XM = 320; static const float WALK_SPEED = 100; +static const float KICK_TIME = .3; + // growing animation Surface* growingtux_left[GROWING_FRAMES]; Surface* growingtux_right[GROWING_FRAMES]; @@ -79,17 +84,16 @@ TuxBodyParts::set_action(std::string action, int loops) } void -TuxBodyParts::draw(DrawingContext& context, const Vector& pos, int layer, - Uint32 drawing_effect) +TuxBodyParts::draw(DrawingContext& context, const Vector& pos, int layer) { if(head != NULL) - head->draw(context, pos, layer-1, drawing_effect); + head->draw(context, pos, layer-1); if(body != NULL) - body->draw(context, pos, layer-3, drawing_effect); + body->draw(context, pos, layer-3); if(arms != NULL) - arms->draw(context, pos, layer, drawing_effect); + arms->draw(context, pos, layer); if(feet != NULL) - feet->draw(context, pos, layer-2, drawing_effect); + feet->draw(context, pos, layer-2); } Player::Player(PlayerStatus* _player_status) @@ -126,21 +130,12 @@ Player::init() last_ground_y = 0; fall_mode = ON_GROUND; jumping = false; - flapping = false; can_jump = true; - can_flap = false; - falling_from_flap = false; - enable_hover = false; butt_jump = false; + deactivated = false; + backflipping = false; + backflip_direction = 0; - flapping_velocity = 0; - - // temporary to help player's choosing a flapping - flapping_mode = NO_FLAP; - - // Ricardo's flapping - flaps_nb = 0; - on_ground_flag = false; grabbed_object = 0; @@ -154,30 +149,42 @@ Player::set_controller(Controller* controller) } void -Player::action(float elapsed_time) +Player::update(float elapsed_time) { if(dying && dying_timer.check()) { dead = true; return; } + // fixes the "affected even while blinking" bug + if (safe_timer.started() && this->get_group() != COLGROUP_MOVING_ONLY_STATIC) { + this->set_group(COLGROUP_MOVING_ONLY_STATIC); + } + else if (!safe_timer.started() && this->get_group() == COLGROUP_MOVING_ONLY_STATIC) { + this->set_group(COLGROUP_MOVING); + } + 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(), + Vector(dir == LEFT ? -bbox.get_width()-1 : bbox.get_width()+1, bbox.get_height()*0.66666 - 32); - MovingObject* object = dynamic_cast (grabbed_object); - if(object) { - object->set_pos(pos); - } else { + Rect dest(pos, pos + Vector(32, 32)); + if(Sector::current()->is_free_space(dest)) { + MovingObject* moving_object = dynamic_cast (grabbed_object); + if(moving_object) { + moving_object->set_pos(pos); + } else { #ifdef DEBUG - std::cout << "Non MovingObjetc grabbed?!?\n"; + std::cout << "Non MovingObjetc grabbed?!?\n"; #endif + } + grabbed_object->ungrab(*this, dir); + grabbed_object = 0; } } - if(!dying) + if(!dying && !deactivated) handle_input(); movement = physic.get_movement(elapsed_time); @@ -197,7 +204,7 @@ Player::action(float elapsed_time) Vector pos = get_pos() + Vector(dir == LEFT ? -16 : 16, bbox.get_height()*0.66666 - 32); - grabbed_object->grab(*this, pos); + grabbed_object->grab(*this, pos, dir); } } @@ -270,14 +277,13 @@ Player::handle_horizontal_input() // let's skid! if(fabs(vx)>SKID_XM && !skidding_timer.started()) { skidding_timer.start(SKID_TIME); - sound_manager->play_sound("skid"); - // dust some partcles + sound_manager->play("sounds/skid.wav"); + // dust some particles Sector::current()->add_object( new Particles( - Vector(bbox.p1.x + (dir == RIGHT ? bbox.get_width() : 0), - bbox.p2.y), + Vector(dir == RIGHT ? bbox.p2.x : bbox.p1.x, 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, + Vector(280, -260), Vector(0, 300), 3, Color(.4, .4, .4), 3, .8, LAYER_OBJECTS+1)); ax *= 2.5; @@ -341,128 +347,42 @@ Player::handle_vertical_input() if(on_ground()) { /* Make sure jumping is off. */ jumping = false; - flapping = false; - falling_from_flap = false; - if (flapping_timer.started()) { - flapping_timer.start(0); + if (backflipping) { + backflipping = false; + backflip_direction = 0; } - - physic.set_acceleration_y(0); //for flapping } // Press jump key 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) + if (duck) { + if (physic.get_velocity_x() != 0) // only jump a little bit when running ducked + physic.set_velocity_y(300); + else { //do a backflip + backflipping = true; physic.set_velocity_y(580); - else - physic.set_velocity_y(520); + backflip_timer.start(0.15); + } } + else if (fabs(physic.get_velocity_x()) > MAX_WALK_XM) // jump higher if we are running + 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"); + sound_manager->play("sounds/bigjump.wav"); else - sound_manager->play_sound("jump"); + sound_manager->play("sounds/jump.wav"); } 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) { + if (!backflipping && 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 (!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 (controller->hold(Controller::JUMP) && 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); - } - } - /* 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) @@ -536,7 +456,15 @@ void Player::handle_input() { /* Handle horizontal movement: */ - handle_horizontal_input(); + if (!backflipping) handle_horizontal_input(); + else { + if (backflip_direction == 0) { + dir == LEFT ? backflip_direction = 1 : backflip_direction = -1; + } + else backflip_direction == 1 ? dir = LEFT : dir = RIGHT; //prevent player from changing direction when backflipping + if (backflip_timer.check()) physic.set_velocity_x(100 * backflip_direction); + } + /* Jump/jumping? */ if (on_ground() && !controller->hold(Controller::JUMP)) @@ -580,7 +508,7 @@ Player::handle_input() void Player::set_bonus(BonusType type, bool animate) { - if(player_status->bonus == type) + if(player_status->bonus >= type) return; if(player_status->bonus == NO_BONUS) { @@ -594,6 +522,12 @@ Player::set_bonus(BonusType type, bool animate) } void +Player::kick() +{ + kick_timer.start(KICK_TIME); +} + +void Player::draw(DrawingContext& context) { TuxBodyParts* tux_body; @@ -723,7 +657,7 @@ Player::draw(DrawingContext& context) get_pos(), layer); } } - else if (safe_timer.started() && size_t(global_time*40)%2) + else if (safe_timer.started() && size_t(game_time*40)%2) ; // don't draw Tux else tux_body->draw(context, get_pos(), layer); @@ -731,7 +665,7 @@ Player::draw(DrawingContext& context) // Draw blinking star overlay if (invincible_timer.started() && (invincible_timer.get_timeleft() > TUX_INVINCIBLE_TIME_WARNING - || size_t(global_time*20)%2) + || size_t(game_time*20)%2) && !dying) { if (!is_big() || duck) @@ -741,19 +675,33 @@ Player::draw(DrawingContext& context) } } +void +Player::collision_tile(uint32_t tile_attributes) +{ + if(tile_attributes & Tile::HURTS) + kill(SHRINK); +} + 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; + Bullet* bullet = dynamic_cast (&other); + if(bullet) { + return FORCE_MOVE; + } + + if(other.get_flags() & FLAG_PORTABLE) { + 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) + if(physic.get_velocity_y() < 0) physic.set_velocity_y(0); on_ground_flag = true; } else if(hit.normal.y > 0) { // bumped against the roof @@ -771,15 +719,24 @@ Player::collision(GameObject& other, const CollisionHit& hit) if(trigger) { if(controller->pressed(Controller::UP)) trigger->event(*this, TriggerBase::EVENT_ACTIVATE); + + return FORCE_MOVE; } - return FORCE_MOVE; + MovingObject* moving_object = static_cast (&other); + if(moving_object->get_group() == COLGROUP_TOUCHABLE) + return FORCE_MOVE; + + if(is_invincible()) + return FORCE_MOVE; + + return CONTINUE; } void Player::make_invincible() { - sound_manager->play_sound("invincible"); + sound_manager->play("sounds/invincible.wav"); invincible_timer.start(TUX_INVINCIBLE_TIME); Sector::current()->play_music(HERRING_MUSIC); } @@ -788,14 +745,14 @@ Player::make_invincible() void Player::kill(HurtMode mode) { - if(dying) + if(dying || deactivated) return; if(mode != KILL && safe_timer.get_timeleft() > 0 || invincible_timer.get_timeleft() > 0) return; - sound_manager->play_sound("hurt"); + sound_manager->play("sounds/hurt.wav"); physic.set_velocity_x(0); @@ -825,7 +782,7 @@ Player::kill(HurtMode mode) player_status->bonus = NO_BONUS; dying = true; dying_timer.start(3.0); - flags |= FLAG_NO_COLLDET; + set_group(COLGROUP_DISABLED); } } @@ -890,13 +847,29 @@ Player::check_bounds(Camera* camera) void Player::bounce(BadGuy& ) { - //Make sure we stopped flapping - flapping = false; - falling_from_flap = false; - if(controller->hold(Controller::JUMP)) physic.set_velocity_y(520); else - physic.set_velocity_y(200); + physic.set_velocity_y(300); } +//Scripting Functions Below + +void +Player::deactivate() +{ + deactivated = true; + physic.set_velocity_x(0); + physic.set_velocity_y(0); +} + +void +Player::activate() +{ + deactivated = false; +} + +void Player::walk(float speed) +{ + physic.set_velocity_x(speed); +}