From: Christoph Sommer Date: Fri, 3 Mar 2006 22:30:17 +0000 (+0000) Subject: New badguy SkullHop - a skull that hops around on one foot. Graphics based on data... X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=8dde188b365f32b5dfa37d3912b959d7acf5c845;p=supertux.git New badguy SkullHop - a skull that hops around on one foot. Graphics based on data/images/creatures/skullhead/skullhead.xcf SVN-Revision: 3070 --- diff --git a/data/images/creatures/skullhead/skullhead2.xcf b/data/images/creatures/skullhead/skullhead2.xcf new file mode 100644 index 000000000..2f9903990 Binary files /dev/null and b/data/images/creatures/skullhead/skullhead2.xcf differ diff --git a/data/images/creatures/skullyhop/charging-0.png b/data/images/creatures/skullyhop/charging-0.png new file mode 100644 index 000000000..1b223c5e4 Binary files /dev/null and b/data/images/creatures/skullyhop/charging-0.png differ diff --git a/data/images/creatures/skullyhop/charging-1.png b/data/images/creatures/skullyhop/charging-1.png new file mode 100644 index 000000000..95051bf7b Binary files /dev/null and b/data/images/creatures/skullyhop/charging-1.png differ diff --git a/data/images/creatures/skullyhop/jumping-0.png b/data/images/creatures/skullyhop/jumping-0.png new file mode 100644 index 000000000..a1aa6c88b Binary files /dev/null and b/data/images/creatures/skullyhop/jumping-0.png differ diff --git a/data/images/creatures/skullyhop/skullyhop.xcf b/data/images/creatures/skullyhop/skullyhop.xcf new file mode 100644 index 000000000..599ef0a56 Binary files /dev/null and b/data/images/creatures/skullyhop/skullyhop.xcf differ diff --git a/data/images/creatures/skullyhop/squished-0.png b/data/images/creatures/skullyhop/squished-0.png new file mode 100644 index 000000000..384f6a967 Binary files /dev/null and b/data/images/creatures/skullyhop/squished-0.png differ diff --git a/data/images/creatures/skullyhop/standing-0.png b/data/images/creatures/skullyhop/standing-0.png new file mode 100644 index 000000000..c9f2f0eb9 Binary files /dev/null and b/data/images/creatures/skullyhop/standing-0.png differ diff --git a/data/images/sprites.strf b/data/images/sprites.strf index 144e63812..fefa3ed52 100644 --- a/data/images/sprites.strf +++ b/data/images/sprites.strf @@ -944,6 +944,52 @@ (name "attacking") (images "creatures/angrystone/attacking-0.png"))) +; SkullyHop + (sprite (name "skullyhop") + (action + (name "standing-left") + (x-offset 0) + (y-offset 0) + (images "creatures/skullyhop/standing-0.png")) + (action + (name "standing-right") + (x-offset 0) + (y-offset 0) + (mirror-action "standing-left")) + (action + (name "charging-left") + (x-offset 0) + (y-offset 0) + (fps 10.0) + (images "creatures/skullyhop/charging-0.png" + "creatures/skullyhop/charging-1.png")) + (action + (name "charging-right") + (fps 10.0) + (x-offset 0) + (y-offset 0) + (mirror-action "charging-left")) + (action + (name "jumping-left") + (x-offset 0) + (y-offset 0) + (images "creatures/skullyhop/jumping-0.png")) + (action + (name "jumping-right") + (x-offset 0) + (y-offset 0) + (mirror-action "jumping-left")) + (action + (name "squished-left") + (x-offset 0) + (y-offset -14) + (images "creatures/skullyhop/squished-0.png")) + (action + (name "squished-right") + (x-offset 0) + (y-offset -14) + (mirror-action "squished-left"))) + ;; Game elements follow (sprite (name "egg") diff --git a/src/badguy/dispenser.cpp b/src/badguy/dispenser.cpp index 010e9c792..e22f81998 100644 --- a/src/badguy/dispenser.cpp +++ b/src/badguy/dispenser.cpp @@ -27,6 +27,7 @@ #include "badguy/mrrocket.hpp" #include "badguy/poisonivy.hpp" #include "badguy/snowsnail.hpp" +#include "badguy/skullyhop.hpp" Dispenser::Dispenser(const lisp::Lisp& reader) { @@ -104,9 +105,11 @@ Dispenser::launch_badguy() Sector::current()->add_object(new MrRocket(get_pos().x+(dir == LEFT ? -32 : 32), get_pos().y, dir));} else if (badguy == "poisonivy") Sector::current()->add_object(new PoisonIvy(get_pos().x, get_pos().y+32, dir)); + else if (badguy == "skullyhop") + Sector::current()->add_object(new SkullyHop(get_pos().x, get_pos().y+44, dir)); else if (badguy == "random") { - switch (rand()%6) + switch (rand()%7) { case 0: Sector::current()->add_object(new SnowBall(get_pos().x, get_pos().y+32, dir)); break; case 1: Sector::current()->add_object(new BouncingSnowball(get_pos().x, get_pos().y+32, dir)); break; @@ -114,6 +117,7 @@ Dispenser::launch_badguy() case 3: Sector::current()->add_object(new MrIceBlock(get_pos().x, get_pos().y+32, dir, false)); break; case 4: Sector::current()->add_object(new PoisonIvy(get_pos().x, get_pos().y+32, dir)); break; case 5: Sector::current()->add_object(new SnowSnail(get_pos().x, get_pos().y+32, dir)); break; + case 6: Sector::current()->add_object(new SkullyHop(get_pos().x, get_pos().y+44, dir)); break; } } } diff --git a/src/badguy/skullyhop.cpp b/src/badguy/skullyhop.cpp new file mode 100644 index 000000000..418a63fc3 --- /dev/null +++ b/src/badguy/skullyhop.cpp @@ -0,0 +1,151 @@ +// $Id: skullyhop.cpp 2960 2005-12-28 00:09:51Z matzebraun $ +// +// SkullyHop - A Hopping Skull +// Copyright (C) 2006 Christoph Sommer +// +// 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 "skullyhop.hpp" + +namespace { + const float VERTICAL_SPEED = 450; /**< y-speed when jumping */ + const float HORIZONTAL_SPEED = 220; /**< x-speed when jumping */ + const float MIN_RECOVER_TIME = 0.1; /**< minimum time to stand still before starting a (new) jump */ + const float MAX_RECOVER_TIME = 1.0; /**< maximum time to stand still before starting a (new) jump */ +} + +SkullyHop::SkullyHop(const lisp::Lisp& reader) +{ + reader.get("x", start_position.x); + reader.get("y", start_position.y); + bbox.set_size(33.8, 43.8); //sprite is 34x44 + sprite = sprite_manager->create("skullyhop"); + has_initial_direction = false; +} + +SkullyHop::SkullyHop(float pos_x, float pos_y, Direction d) +{ + start_position.x = pos_x; + start_position.y = pos_y; + bbox.set_size(33.8, 43.8); //sprite is 34x44 + sprite = sprite_manager->create("skullyhop"); + has_initial_direction = true; + initial_direction = d; +} + +void +SkullyHop::write(lisp::Writer& writer) +{ + writer.start_list("skullyhop"); + writer.write_float("x", start_position.x); + writer.write_float("y", start_position.y); + writer.end_list("skullyhop"); +} + +void +SkullyHop::activate() +{ + if (has_initial_direction) dir = initial_direction; + + // initial state is JUMPING, because we might start airborne + state = JUMPING; + sprite->set_action(dir == LEFT ? "jumping-left" : "jumping-right"); +} + +void +SkullyHop::set_state(SkullyHopState newState) +{ + if (newState == STANDING) { + physic.set_velocity_x(0); + physic.set_velocity_y(0); + sprite->set_action(dir == LEFT ? "standing-left" : "standing-right"); + + float recover_time = MIN_RECOVER_TIME + (float)rand() / RAND_MAX * (MAX_RECOVER_TIME - MIN_RECOVER_TIME); + recover_timer.start(recover_time); + } else + if (newState == CHARGING) { + sprite->set_action(dir == LEFT ? "charging-left" : "charging-right", 1); + } else + if (newState == JUMPING) { + sprite->set_action(dir == LEFT ? "jumping-left" : "jumping-right"); + physic.set_velocity_x(dir == LEFT ? -HORIZONTAL_SPEED : HORIZONTAL_SPEED); + physic.set_velocity_y(VERTICAL_SPEED); + } + + state = newState; +} + +bool +SkullyHop::collision_squished(Player& player) +{ + sprite->set_action(dir == LEFT ? "squished-left" : "squished-right"); + kill_squished(player); + return true; +} + +HitResponse +SkullyHop::collision_solid(GameObject& , const CollisionHit& hit) +{ + // ignore collisions while standing still + if(state != JUMPING) return CONTINUE; + + // check if we hit the floor while falling + if ((hit.normal.y < 0) && (physic.get_velocity_y() < 0)) { + set_state(STANDING); + } + + // check if we hit the roof while climbing + if ((hit.normal.y > 0) && (physic.get_velocity_y() > 0)) { + physic.set_velocity_y(0); + } + + // check if we hit left or right while moving in either direction + if ((hit.normal.x != 0) && (physic.get_velocity_x() != 0)) { + dir = dir == LEFT ? RIGHT : LEFT; + sprite->set_action(dir == LEFT ? "jumping-left" : "jumping-right"); + physic.set_velocity_x(-0.25*physic.get_velocity_x()); + } + + return CONTINUE; +} + +HitResponse +SkullyHop::collision_badguy(BadGuy& badguy, const CollisionHit& hit) +{ + // behaviour for badguy collisions is the same as for collisions with solids + return collision_solid(badguy, hit); +} + +void +SkullyHop::active_update(float elapsed_time) +{ + BadGuy::active_update(elapsed_time); + + // charge when fully recovered + if ((state == STANDING) && (recover_timer.check())) { + set_state(CHARGING); + return; + } + + // jump as soon as charging animation completed + if ((state == CHARGING) && (sprite->animation_done())) { + set_state(JUMPING); + return; + } +} + +IMPLEMENT_FACTORY(SkullyHop, "skullyhop") diff --git a/src/badguy/skullyhop.hpp b/src/badguy/skullyhop.hpp new file mode 100644 index 000000000..3f4dd5278 --- /dev/null +++ b/src/badguy/skullyhop.hpp @@ -0,0 +1,59 @@ +// $Id: skullyhop.hpp 2642 2005-06-26 13:38:53Z matzebraun $ +// +// SkullyHop - A Hopping Skull +// Copyright (C) 2006 Christoph Sommer +// +// 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 __SKULLYHOP_H__ +#define __SKULLYHOP_H__ + +#include "badguy.hpp" + +/** + * Badguy "SkullyHop" - A Hopping Skull + */ +class SkullyHop : public BadGuy +{ +public: + SkullyHop(const lisp::Lisp& reader); + SkullyHop(float pos_x, float pos_y, Direction d); + + void activate(); + void write(lisp::Writer& writer); + HitResponse collision_solid(GameObject& other, const CollisionHit& hit); + HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit); + bool collision_squished(Player& player); + void active_update(float elapsed_time); + +protected: + enum SkullyHopState { + STANDING, + CHARGING, + JUMPING + }; + + bool has_initial_direction; + Direction initial_direction; + + Timer recover_timer; + SkullyHopState state; + + void set_state(SkullyHopState newState); +}; + +#endif +