From fd282d4799cb88eae93e471f5c055f9dc3f12b86 Mon Sep 17 00:00:00 2001 From: Christoph Sommer Date: Mon, 10 Jul 2006 20:23:45 +0000 Subject: [PATCH] Split off Mr.Tree's small form as new Badguy "Stumpy" SVN-Revision: 3981 --- data/images/creatures/mr_tree/mr_tree.sprite | 52 ++----- data/images/creatures/mr_tree/stumpy.sprite | 31 +++++ src/badguy/mrtree.cpp | 198 ++++++--------------------- src/badguy/mrtree.hpp | 14 +- src/badguy/stumpy.cpp | 166 ++++++++++++++++++++++ src/badguy/stumpy.hpp | 50 +++++++ 6 files changed, 302 insertions(+), 209 deletions(-) create mode 100644 data/images/creatures/mr_tree/stumpy.sprite create mode 100644 src/badguy/stumpy.cpp create mode 100644 src/badguy/stumpy.hpp diff --git a/data/images/creatures/mr_tree/mr_tree.sprite b/data/images/creatures/mr_tree/mr_tree.sprite index a4bc6e878..c53d42cb0 100644 --- a/data/images/creatures/mr_tree/mr_tree.sprite +++ b/data/images/creatures/mr_tree/mr_tree.sprite @@ -1,45 +1,19 @@ (supertux-sprite - (action - (hitbox 0 -2 84.8 84.8) - (name "large-left") - (images "walk-left-1.png" - "walk-left-2.png" - "walk-left-3.png" - "walk-left-4.png" - "walk-left-5.png" - "walk-left-6.png" -) - ) - (action - (hitbox 0 -2 84.8 84.8) - (name "large-right") - (mirror-action "large-left") - ) - (action - (hitbox 20 23 42 62) - (name "small-left") - (images "small-left-0.png" - "small-left-1.png" - "small-left-2.png" - "small-left-3.png" - "small-left-4.png" - "small-left-5.png" - -) - ) - (action - (hitbox 20 23 42 62) - (name "small-right") - (mirror-action "small-left") - ) (action - (hitbox 20 23 42 42) - (name "squished-left") - (images "squished-left.png") + (hitbox 0 -2 84.8 84.8) + (name "left") + (images + "walk-left-1.png" + "walk-left-2.png" + "walk-left-3.png" + "walk-left-4.png" + "walk-left-5.png" + "walk-left-6.png" + ) ) (action - (hitbox 20 23 42 42) - (name "squished-right") - (mirror-action "squished-left") + (hitbox 0 -2 84.8 84.8) + (name "right") + (mirror-action "left") ) ) diff --git a/data/images/creatures/mr_tree/stumpy.sprite b/data/images/creatures/mr_tree/stumpy.sprite new file mode 100644 index 000000000..fa56260a2 --- /dev/null +++ b/data/images/creatures/mr_tree/stumpy.sprite @@ -0,0 +1,31 @@ +(supertux-sprite + (action + (hitbox 20 23 42 62) + (name "left") + (images + "small-left-0.png" + "small-left-1.png" + "small-left-2.png" + "small-left-3.png" + "small-left-4.png" + "small-left-5.png" + ) + ) + (action + (hitbox 20 23 42 62) + (name "right") + (mirror-action "left") + ) + (action + (hitbox 20 23 42 42) + (name "squished-left") + (images + "squished-left.png" + ) + ) + (action + (hitbox 20 23 42 42) + (name "squished-right") + (mirror-action "squished-left") + ) +) diff --git a/src/badguy/mrtree.cpp b/src/badguy/mrtree.cpp index f5c1c0787..565cf7090 100644 --- a/src/badguy/mrtree.cpp +++ b/src/badguy/mrtree.cpp @@ -20,13 +20,13 @@ #include #include "mrtree.hpp" +#include "stumpy.hpp" #include "poisonivy.hpp" #include "random_generator.hpp" #include "object/sprite_particle.hpp" +#include "sector.hpp" static const float WALKSPEED = 100; -static const float WALKSPEED_SMALL = 120; -static const float INVINCIBLE_TIME = 1; static const float POISONIVY_WIDTH = 32; static const float POISONIVY_HEIGHT = 32; @@ -34,12 +34,11 @@ static const float POISONIVY_Y_OFFSET = 24; MrTree::MrTree(const lisp::Lisp& reader) - : WalkingBadguy(reader, "images/creatures/mr_tree/mr_tree.sprite","large-left","large-right"), mystate(STATE_BIG) + : WalkingBadguy(reader, "images/creatures/mr_tree/mr_tree.sprite","left","right") { walk_speed = WALKSPEED; max_drop_height = 0; sound_manager->preload("sounds/mr_tree.ogg"); - sound_manager->preload("sounds/mr_treehit.ogg"); } void @@ -50,169 +49,54 @@ MrTree::write(lisp::Writer& writer) writer.end_list("mrtree"); } -void -MrTree::activate() -{ - 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) -{ - 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; - } -} - bool MrTree::collision_squished(Player& player) { - // if we're big, we shrink - if(mystate == STATE_BIG) { - mystate = STATE_INVINCIBLE; - invincible_timer.start(INVINCIBLE_TIME); - - float old_x_offset = sprite->get_current_hitbox_x_offset(); - float old_y_offset = sprite->get_current_hitbox_y_offset(); - activate(); - - // shrink bounding box and adjust sprite position to where the stump once was - 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; - set_pos(pos); - - sound_manager->play("sounds/mr_tree.ogg", get_pos()); - player.bounce(*this); - // 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)); - } - 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); - } - - return true; + // replace with Stumpy + Vector stumpy_pos = get_pos(); + stumpy_pos.x += 20; + stumpy_pos.y += 25; + Stumpy* stumpy = new Stumpy(stumpy_pos, dir); + remove_me(); + Sector::current()->add_object(stumpy); + + // give Feedback + sound_manager->play("sounds/mr_tree.ogg", get_pos()); + player.bounce(*this); + + // 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)); } - // if we're still invincible, we ignore the hit - if (mystate == STATE_INVINCIBLE) { - sound_manager->play("sounds/mr_treehit.ogg", get_pos()); - player.bounce(*this); - return true; + // spawn PoisonIvy + Vector leaf1_pos = Vector(stumpy_pos.x - POISONIVY_WIDTH - 1, stumpy_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); } - - // if we're small, we die - if (mystate == STATE_NORMAL) { - sprite->set_action(dir == LEFT ? "squished-left" : "squished-right"); - set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height()); - kill_squished(player); - // 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)); - } - - return true; - + + // spawn PoisonIvy + Vector leaf2_pos = Vector(stumpy_pos.x + sprite->get_current_hitbox_width() + 1, stumpy_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); } - //TODO: exception? return true; } -void -MrTree::collision_solid(const CollisionHit& hit) -{ - update_on_ground_flag(hit); - - 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& badguy, const CollisionHit& hit) -{ - 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; -} - IMPLEMENT_FACTORY(MrTree, "mrtree") diff --git a/src/badguy/mrtree.hpp b/src/badguy/mrtree.hpp index b6437cad6..4eae54948 100644 --- a/src/badguy/mrtree.hpp +++ b/src/badguy/mrtree.hpp @@ -26,24 +26,12 @@ class MrTree : public WalkingBadguy { public: MrTree(const lisp::Lisp& reader); - - void activate(); - void active_update(float elapsed_time); void write(lisp::Writer& writer); - void collision_solid(const CollisionHit& hit); - HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit); - virtual MrTree* clone() const { return new MrTree(*this); } protected: - enum MyState { - STATE_BIG, STATE_INVINCIBLE, STATE_NORMAL - }; - MyState mystate; - - Timer invincible_timer; - bool collision_squished(Player& player); + }; #endif diff --git a/src/badguy/stumpy.cpp b/src/badguy/stumpy.cpp new file mode 100644 index 000000000..4f0fd53c1 --- /dev/null +++ b/src/badguy/stumpy.cpp @@ -0,0 +1,166 @@ +// $Id: stumpy.cpp 3980 2006-07-10 19:55:56Z sommer $ +// +// SuperTux +// Copyright (C) 2006 Matthias Braun +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include + +#include "stumpy.hpp" +#include "poisonivy.hpp" +#include "random_generator.hpp" +#include "object/sprite_particle.hpp" + +static const float WALKSPEED = 120; +static const float INVINCIBLE_TIME = 1; + +Stumpy::Stumpy(const lisp::Lisp& reader) + : WalkingBadguy(reader, "images/creatures/mr_tree/stumpy.sprite","left","right"), mystate(STATE_NORMAL) +{ + walk_speed = WALKSPEED; + max_drop_height = 0; + sound_manager->preload("sounds/mr_tree.ogg"); + sound_manager->preload("sounds/mr_treehit.ogg"); +} + +Stumpy::Stumpy(const Vector& pos, Direction d) + : WalkingBadguy(pos, d, "images/creatures/mr_tree/stumpy.sprite","left","right"), mystate(STATE_INVINCIBLE) +{ + walk_speed = WALKSPEED; + max_drop_height = 0; + sound_manager->preload("sounds/mr_treehit.ogg"); + invincible_timer.start(INVINCIBLE_TIME); +} + + +void +Stumpy::write(lisp::Writer& writer) +{ + writer.start_list("stumpy"); + WalkingBadguy::write(writer); + writer.end_list("stumpy"); +} + +void +Stumpy::activate() +{ + switch (mystate) { + case STATE_INVINCIBLE: + WalkingBadguy::activate(); + physic.set_velocity_x(0); + break; + case STATE_NORMAL: + WalkingBadguy::activate(); + break; + } +} + +void +Stumpy::active_update(float elapsed_time) +{ + switch (mystate) { + case STATE_INVINCIBLE: + if (invincible_timer.check()) { + mystate = STATE_NORMAL; + WalkingBadguy::activate(); + } + BadGuy::active_update(elapsed_time); + break; + case STATE_NORMAL: + WalkingBadguy::active_update(elapsed_time); + break; + } +} + +bool +Stumpy::collision_squished(Player& player) +{ + + // if we're still invincible, we ignore the hit + if (mystate == STATE_INVINCIBLE) { + sound_manager->play("sounds/mr_treehit.ogg", get_pos()); + player.bounce(*this); + return true; + } + + // if we can die, we do + if (mystate == STATE_NORMAL) { + sprite->set_action(dir == LEFT ? "squished-left" : "squished-right"); + set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height()); + kill_squished(player); + // 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)); + } + + return true; + + } + + //TODO: exception? + return true; +} + +void +Stumpy::collision_solid(const CollisionHit& hit) +{ + update_on_ground_flag(hit); + + switch (mystate) { + case STATE_INVINCIBLE: + if(hit.top || hit.bottom) { + physic.set_velocity_y(0); + } + if(hit.left || hit.right) { + physic.set_velocity_x(0); + } + break; + case STATE_NORMAL: + WalkingBadguy::collision_solid(hit); + break; + } +} + +HitResponse +Stumpy::collision_badguy(BadGuy& badguy, const CollisionHit& hit) +{ + switch (mystate) { + 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; + case STATE_NORMAL: + return WalkingBadguy::collision_badguy(badguy, hit); + break; + } + return CONTINUE; +} + +IMPLEMENT_FACTORY(Stumpy, "stumpy") + diff --git a/src/badguy/stumpy.hpp b/src/badguy/stumpy.hpp new file mode 100644 index 000000000..a3bd2038b --- /dev/null +++ b/src/badguy/stumpy.hpp @@ -0,0 +1,50 @@ +// $Id: stumpy.hpp 3980 2006-07-10 19:55:56Z sommer $ +// +// SuperTux +// Copyright (C) 2006 Matthias Braun +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef __STUMPY_H__ +#define __STUMPY_H__ + +#include "walking_badguy.hpp" + +class Stumpy : public WalkingBadguy +{ +public: + Stumpy(const lisp::Lisp& reader); + Stumpy(const Vector& pos, Direction d); + + void activate(); + void active_update(float elapsed_time); + void write(lisp::Writer& writer); + void collision_solid(const CollisionHit& hit); + HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit); + + virtual Stumpy* clone() const { return new Stumpy(*this); } + +protected: + enum MyState { + STATE_INVINCIBLE, STATE_NORMAL + }; + MyState mystate; + + Timer invincible_timer; + + bool collision_squished(Player& player); +}; + +#endif -- 2.11.0