From: Christoph Sommer Date: Mon, 10 Jul 2006 19:55:56 +0000 (+0000) Subject: Fixed MrTree floating in the air when squished / X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=dde03feb2d56f02e1515612a0c7e4ee9a4238563;p=supertux.git Fixed MrTree floating in the air when squished / Two more WalkingBadguys SVN-Revision: 3980 --- diff --git a/src/badguy/mrtree.cpp b/src/badguy/mrtree.cpp index 497f5005c..f5c1c0787 100644 --- a/src/badguy/mrtree.cpp +++ b/src/badguy/mrtree.cpp @@ -34,9 +34,10 @@ static const float POISONIVY_Y_OFFSET = 24; MrTree::MrTree(const lisp::Lisp& reader) - : BadGuy(reader, "images/creatures/mr_tree/mr_tree.sprite"), mystate(STATE_BIG) + : WalkingBadguy(reader, "images/creatures/mr_tree/mr_tree.sprite","large-left","large-right"), mystate(STATE_BIG) { - sprite->set_action(dir == LEFT ? "large-left" : "large-right"); + walk_speed = WALKSPEED; + max_drop_height = 0; sound_manager->preload("sounds/mr_tree.ogg"); sound_manager->preload("sounds/mr_treehit.ogg"); } @@ -45,48 +46,46 @@ void MrTree::write(lisp::Writer& writer) { writer.start_list("mrtree"); - - writer.write_float("x", start_position.x); - writer.write_float("y", start_position.y); - + WalkingBadguy::write(writer); writer.end_list("mrtree"); } void MrTree::activate() { - if (mystate == STATE_BIG) { - physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED); - sprite->set_action(dir == LEFT ? "large-left" : "large-right"); - return; - } - if (mystate == STATE_INVINCIBLE) { - physic.set_velocity_x(0); - sprite->set_action(dir == LEFT ? "small-left" : "small-right"); - return; - } - if (mystate == STATE_NORMAL) { - physic.set_velocity_x(dir == LEFT ? -WALKSPEED_SMALL : WALKSPEED_SMALL); - sprite->set_action(dir == LEFT ? "small-left" : "small-right"); - return; + switch (mystate) { + case STATE_BIG: + WalkingBadguy::activate(); + break; + case STATE_NORMAL: + walk_speed = WALKSPEED_SMALL; + walk_left_action = "small-left"; + walk_right_action = "small-right"; + WalkingBadguy::activate(); + break; + case STATE_INVINCIBLE: + physic.set_velocity_x(0); + sprite->set_action(dir == LEFT ? "small-left" : "small-right"); + break; } } void MrTree::active_update(float elapsed_time) { - if ((mystate == STATE_INVINCIBLE) && (invincible_timer.check())) { - mystate = STATE_NORMAL; - activate(); + switch (mystate) { + case STATE_BIG: + case STATE_NORMAL: + WalkingBadguy::active_update(elapsed_time); + break; + case STATE_INVINCIBLE: + if (invincible_timer.check()) { + mystate = STATE_NORMAL; + activate(); + } + BadGuy::active_update(elapsed_time); + break; } - - if (on_ground() && might_fall()) - { - dir = (dir == LEFT ? RIGHT : LEFT); - activate(); - } - - BadGuy::active_update(elapsed_time); } bool @@ -102,7 +101,7 @@ MrTree::collision_squished(Player& player) activate(); // shrink bounding box and adjust sprite position to where the stump once was - bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height()); + set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height()); Vector pos = get_pos(); pos.x += sprite->get_current_hitbox_x_offset() - old_x_offset; pos.y += sprite->get_current_hitbox_y_offset() - old_y_offset; @@ -110,28 +109,30 @@ MrTree::collision_squished(Player& player) sound_manager->play("sounds/mr_tree.ogg", get_pos()); player.bounce(*this); - // spawn some particles + // spawn some particles // TODO: provide convenience function in MovingSprite or MovingObject? - for (int i = 0; i < 25; i++) { - Vector ppos = bbox.get_middle(); - float angle = systemRandom.randf(-M_PI_2, M_PI_2); - float velocity = systemRandom.randf(45, 90); - float vx = sin(angle)*velocity; - float vy = -cos(angle)*velocity; - Vector pspeed = Vector(vx, vy); - Vector paccel = Vector(0, 100); - Sector::current()->add_object(new SpriteParticle("images/objects/particles/leaf.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1)); - } + for (int i = 0; i < 25; i++) { + Vector ppos = bbox.get_middle(); + float angle = systemRandom.randf(-M_PI_2, M_PI_2); + float velocity = systemRandom.randf(45, 90); + float vx = sin(angle)*velocity; + float vy = -cos(angle)*velocity; + Vector pspeed = Vector(vx, vy); + Vector paccel = Vector(0, 100); + Sector::current()->add_object(new SpriteParticle("images/objects/particles/leaf.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1)); + } Vector leaf1_pos = Vector(pos.x - POISONIVY_WIDTH - 1, pos.y - POISONIVY_Y_OFFSET); Rect leaf1_bbox = Rect(leaf1_pos.x, leaf1_pos.y, leaf1_pos.x + POISONIVY_WIDTH, leaf1_pos.y + POISONIVY_HEIGHT); if (Sector::current()->is_free_space(leaf1_bbox)) { PoisonIvy* leaf1 = new PoisonIvy(leaf1_bbox.p1, LEFT); + leaf1 = leaf1; Sector::current()->add_object(leaf1); } Vector leaf2_pos = Vector(pos.x + sprite->get_current_hitbox_width() + 1, pos.y - POISONIVY_Y_OFFSET); Rect leaf2_bbox = Rect(leaf2_pos.x, leaf2_pos.y, leaf2_pos.x + POISONIVY_WIDTH, leaf2_pos.y + POISONIVY_HEIGHT); if (Sector::current()->is_free_space(leaf2_bbox)) { PoisonIvy* leaf2 = new PoisonIvy(leaf2_bbox.p1, RIGHT); + leaf2 = leaf2; Sector::current()->add_object(leaf2); } @@ -148,20 +149,20 @@ MrTree::collision_squished(Player& player) // if we're small, we die if (mystate == STATE_NORMAL) { sprite->set_action(dir == LEFT ? "squished-left" : "squished-right"); - bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height()); + set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height()); kill_squished(player); - // spawn some particles + // spawn some particles // TODO: provide convenience function in MovingSprite or MovingObject? - for (int i = 0; i < 25; i++) { - Vector ppos = bbox.get_middle(); - float angle = systemRandom.randf(-M_PI_2, M_PI_2); - float velocity = systemRandom.randf(45, 90); - float vx = sin(angle)*velocity; - float vy = -cos(angle)*velocity; - Vector pspeed = Vector(vx, vy); - Vector paccel = Vector(0, 100); - Sector::current()->add_object(new SpriteParticle("images/objects/particles/bark.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1)); - } + for (int i = 0; i < 25; i++) { + Vector ppos = bbox.get_middle(); + float angle = systemRandom.randf(-M_PI_2, M_PI_2); + float velocity = systemRandom.randf(45, 90); + float vx = sin(angle)*velocity; + float vy = -cos(angle)*velocity; + Vector pspeed = Vector(vx, vy); + Vector paccel = Vector(0, 100); + Sector::current()->add_object(new SpriteParticle("images/objects/particles/bark.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1)); + } return true; @@ -176,22 +177,39 @@ MrTree::collision_solid(const CollisionHit& hit) { update_on_ground_flag(hit); - if(hit.top || hit.bottom) { - physic.set_velocity_y(0); - } else { - if( ( hit.left && dir == LEFT )|| (hit.right && dir == RIGHT ) ){ - dir = dir == LEFT ? RIGHT : LEFT; - activate(); - } + switch (mystate) { + case STATE_BIG: + case STATE_NORMAL: + WalkingBadguy::collision_solid(hit); + break; + case STATE_INVINCIBLE: + if(hit.top || hit.bottom) { + physic.set_velocity_y(0); + } + if(hit.left || hit.right) { + physic.set_velocity_x(0); + } + break; } } HitResponse -MrTree::collision_badguy(BadGuy& , const CollisionHit& hit) +MrTree::collision_badguy(BadGuy& badguy, const CollisionHit& hit) { - if( ( hit.left && dir == LEFT )|| (hit.right && dir == RIGHT ) ){ - dir = dir == LEFT ? RIGHT : LEFT; - activate(); + switch (mystate) { + case STATE_BIG: + case STATE_NORMAL: + return WalkingBadguy::collision_badguy(badguy, hit); + break; + case STATE_INVINCIBLE: + if(hit.top || hit.bottom) { + physic.set_velocity_y(0); + } + if(hit.left || hit.right) { + physic.set_velocity_x(0); + } + return CONTINUE; + break; } return CONTINUE; } diff --git a/src/badguy/mrtree.hpp b/src/badguy/mrtree.hpp index 5b2641d82..b6437cad6 100644 --- a/src/badguy/mrtree.hpp +++ b/src/badguy/mrtree.hpp @@ -20,9 +20,9 @@ #ifndef __MRTREE_H__ #define __MRTREE_H__ -#include "badguy.hpp" +#include "walking_badguy.hpp" -class MrTree : public BadGuy +class MrTree : public WalkingBadguy { public: MrTree(const lisp::Lisp& reader); diff --git a/src/badguy/snail.cpp b/src/badguy/snail.cpp index fd8819f42..f54573fd0 100644 --- a/src/badguy/snail.cpp +++ b/src/badguy/snail.cpp @@ -23,23 +23,26 @@ #include "object/block.hpp" namespace { - const float WALKSPEED = 80; const float KICKSPEED = 500; const int MAXSQUISHES = 10; const float KICKSPEED_Y = -500; /**< y-velocity gained when kicked */ } Snail::Snail(const lisp::Lisp& reader) - : BadGuy(reader, "images/creatures/snail/snail.sprite"), state(STATE_NORMAL), squishcount(0) + : WalkingBadguy(reader, "images/creatures/snail/snail.sprite", "left", "right"), state(STATE_NORMAL), squishcount(0) { + walk_speed = 80; + max_drop_height = 600; sound_manager->preload("sounds/iceblock_bump.wav"); sound_manager->preload("sounds/stomp.wav"); sound_manager->preload("sounds/kick.wav"); } Snail::Snail(const Vector& pos, Direction d) - : BadGuy(pos, d, "images/creatures/snail/snail.sprite"), state(STATE_NORMAL), squishcount(0) + : WalkingBadguy(pos, d, "images/creatures/snail/snail.sprite", "left", "right"), state(STATE_NORMAL), squishcount(0) { + walk_speed = 80; + max_drop_height = 600; sound_manager->preload("sounds/iceblock_bump.wav"); sound_manager->preload("sounds/stomp.wav"); sound_manager->preload("sounds/kick.wav"); @@ -49,26 +52,24 @@ void Snail::write(lisp::Writer& writer) { writer.start_list("snail"); - - writer.write_float("x", start_position.x); - writer.write_float("y", start_position.y); - + WalkingBadguy::write(writer); writer.end_list("snail"); } void Snail::activate() { + WalkingBadguy::activate(); be_normal(); } void Snail::be_normal() { - state = STATE_NORMAL; - sprite->set_action(dir == LEFT ? "left" : "right"); + if (state == STATE_NORMAL) return; - physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED); + state = STATE_NORMAL; + WalkingBadguy::activate(); } void @@ -105,11 +106,7 @@ Snail::active_update(float elapsed_time) switch (state) { case STATE_NORMAL: - if (on_ground() && might_fall(601)) { - dir = (dir == LEFT ? RIGHT : LEFT); - sprite->set_action(dir == LEFT ? "left" : "right"); - physic.set_velocity_x(-physic.get_velocity_x()); - } + WalkingBadguy::active_update(elapsed_time); break; case STATE_FLAT: @@ -119,6 +116,7 @@ Snail::active_update(float elapsed_time) if (flat_timer.check()) { be_normal(); } + BadGuy::active_update(elapsed_time); break; case STATE_KICKED_DELAY: @@ -127,15 +125,16 @@ Snail::active_update(float elapsed_time) physic.set_velocity_y(KICKSPEED_Y); state = STATE_KICKED; } + BadGuy::active_update(elapsed_time); break; case STATE_KICKED: physic.set_velocity_x(physic.get_velocity_x() * pow(0.99, elapsed_time/0.02)); - if (fabsf(physic.get_velocity_x()) < WALKSPEED) be_normal(); + if (fabsf(physic.get_velocity_x()) < walk_speed) be_normal(); + BadGuy::active_update(elapsed_time); break; } - BadGuy::active_update(elapsed_time); } void @@ -143,62 +142,56 @@ Snail::collision_solid(const CollisionHit& hit) { update_on_ground_flag(hit); - if(hit.top || hit.bottom) { // floor or roof - physic.set_velocity_y(0); - - switch (state) { - case STATE_NORMAL: - case STATE_FLAT: - case STATE_KICKED_DELAY: - break; - case STATE_KICKED: - break; - } - - return; - } - // hit left or right - switch(state) { - + switch (state) { case STATE_NORMAL: - if( (dir == LEFT && hit.left) || ( dir == RIGHT && hit.right) ){ - dir = dir == LEFT ? RIGHT : LEFT; - sprite->set_action(dir == LEFT ? "left" : "right"); - physic.set_velocity_x(-physic.get_velocity_x()); - } + WalkingBadguy::collision_solid(hit); break; - case STATE_FLAT: + if(hit.top || hit.bottom) { + physic.set_velocity_y(0); + } + if(hit.left || hit.right) { + } + break; case STATE_KICKED_DELAY: - physic.set_velocity_x(0); + if(hit.top || hit.bottom) { + physic.set_velocity_y(0); + } + if(hit.left || hit.right) { + physic.set_velocity_x(0); + } break; + case STATE_KICKED: + if(hit.top || hit.bottom) { + physic.set_velocity_y(0); + } + if(hit.left || hit.right) { + sound_manager->play("sounds/iceblock_bump.wav", get_pos()); - case STATE_KICKED: { - sound_manager->play("sounds/iceblock_bump.wav", get_pos()); - #if 0 - // TODO move this into BonusBlock code - // open bonusblocks, crash bricks - BonusBlock* bonusblock = dynamic_cast (&object); - if(bonusblock) { - bonusblock->try_open(); - } - Brick* brick = dynamic_cast (&object); - if(brick) { - brick->try_break(); - } + // TODO move this into BonusBlock code + // open bonusblocks, crash bricks + BonusBlock* bonusblock = dynamic_cast (&object); + if(bonusblock) { + bonusblock->try_open(); + } + Brick* brick = dynamic_cast (&object); + if(brick) { + brick->try_break(); + } #endif - if( ( dir == LEFT && hit.left ) || ( dir == RIGHT && hit.right) ){ - dir = (dir == LEFT) ? RIGHT : LEFT; - sprite->set_action(dir == LEFT ? "flat-left" : "flat-right"); + if( ( dir == LEFT && hit.left ) || ( dir == RIGHT && hit.right) ){ + dir = (dir == LEFT) ? RIGHT : LEFT; + sprite->set_action(dir == LEFT ? "flat-left" : "flat-right"); + + physic.set_velocity_x(-physic.get_velocity_x()*0.75); + if (fabsf(physic.get_velocity_x()) < walk_speed) be_normal(); + } - physic.set_velocity_x(-physic.get_velocity_x()*0.75); - if (fabsf(physic.get_velocity_x()) < WALKSPEED) be_normal(); } break; - - } } + } HitResponse @@ -206,17 +199,7 @@ Snail::collision_badguy(BadGuy& badguy, const CollisionHit& hit) { switch(state) { case STATE_NORMAL: - // printf("Snail <-> Badguy %s %s %s %s %s\n", hit.left?"left":"", hit.right?"right":"", hit.top?"top":"", hit.bottom?"bottom":"", hit.crush?"crush":""); - if( hit.left && dir == LEFT ){ - dir = RIGHT; - sprite->set_action( "right" ); - physic.set_velocity_x(-physic.get_velocity_x()); - } else if( hit.right && dir == RIGHT ){ - dir = LEFT; - sprite->set_action( "left" ); - physic.set_velocity_x(-physic.get_velocity_x()); - } - return CONTINUE; + return WalkingBadguy::collision_badguy(badguy, hit); case STATE_FLAT: case STATE_KICKED_DELAY: return FORCE_MOVE; diff --git a/src/badguy/snail.hpp b/src/badguy/snail.hpp index 35802b022..83f4a1060 100644 --- a/src/badguy/snail.hpp +++ b/src/badguy/snail.hpp @@ -20,12 +20,12 @@ #ifndef __SNAIL_H__ #define __SNAIL_H__ -#include "badguy.hpp" +#include "walking_badguy.hpp" /** * Badguy "Snail" - a snail-like creature that can be flipped and tossed around at an angle */ -class Snail : public BadGuy +class Snail : public WalkingBadguy { public: Snail(const lisp::Lisp& reader); diff --git a/src/badguy/walking_badguy.cpp b/src/badguy/walking_badguy.cpp index 6b51f0048..110511095 100644 --- a/src/badguy/walking_badguy.cpp +++ b/src/badguy/walking_badguy.cpp @@ -77,8 +77,7 @@ WalkingBadguy::collision_solid(const CollisionHit& hit) physic.set_velocity_y(0); } -// if ((hit.left && dir == LEFT) || (hit.right && dir == RIGHT)) { - if (hit.left || hit.right) { + if ((hit.left && dir == LEFT) || (hit.right && dir == RIGHT)) { turn_around(); } @@ -88,8 +87,7 @@ HitResponse WalkingBadguy::collision_badguy(BadGuy& , const CollisionHit& hit) { - //if ((hit.left && (dir == LEFT)) || (hit.right && (dir == RIGHT))) { - if (hit.left || hit.right) { + if ((hit.left && (dir == LEFT)) || (hit.right && (dir == RIGHT))) { turn_around(); } diff --git a/src/badguy/walking_badguy.hpp b/src/badguy/walking_badguy.hpp index feeae8652..98d694fb2 100644 --- a/src/badguy/walking_badguy.hpp +++ b/src/badguy/walking_badguy.hpp @@ -41,8 +41,8 @@ public: protected: void turn_around(); - const std::string walk_left_action; - const std::string walk_right_action; + std::string walk_left_action; + std::string walk_right_action; float walk_speed; int max_drop_height; /**< Maximum height of drop before we will turn around, or -1 to just drop from any ledge */ };