void
BadGuy::collision_solid(const CollisionHit& hit)
{
+ physic.set_velocity_x(0);
+ physic.set_velocity_y(0);
update_on_ground_flag(hit);
}
}
Igel::Igel(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/igel/igel.sprite"), state(STATE_NORMAL)
+ : WalkingBadguy(reader, "images/creatures/igel/igel.sprite", "walking-left", "walking-right")
{
+ walk_speed = WALKSPEED;
+ max_drop_height = 0;
}
Igel::Igel(const Vector& pos, Direction d)
- : BadGuy(pos, d, "images/creatures/igel/igel.sprite"), state(STATE_NORMAL)
+ : WalkingBadguy(pos, d, "images/creatures/igel/igel.sprite", "walking-left", "walking-right")
{
+ walk_speed = WALKSPEED;
+ max_drop_height = 0;
}
void
Igel::write(lisp::Writer& writer)
{
writer.start_list("igel");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-
+ WalkingBadguy::write(writer);
writer.end_list("igel");
}
void
-Igel::activate()
-{
- be_normal();
-}
-
-void
Igel::be_normal()
{
- state = STATE_NORMAL;
- sprite->set_action(dir == LEFT ? "walking-left" : "walking-right");
-
- physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
+ activate();
}
void
Igel::turn_around()
{
- dir = (dir == LEFT ? RIGHT : LEFT);
+ WalkingBadguy::turn_around();
turn_recover_timer.start(TURN_RECOVER_TIME);
- be_normal();
}
bool
void
Igel::active_update(float elapsed_time)
{
- switch (state) {
-
- case STATE_NORMAL:
- if (on_ground() && might_fall()) {
- // turn around when we are at a ledge
- turn_around();
- }
- else if (!turn_recover_timer.started()) {
- // turn around when we see a Bullet
- Sector* sector = Sector::current();
- for (Sector::GameObjects::iterator i = sector->gameobjects.begin(); i != sector->gameobjects.end(); ++i) {
- Bullet* bullet = dynamic_cast<Bullet*>(*i);
- if (bullet) {
- if (can_see(*bullet)) turn_around();
- }
- }
- }
- break;
-
+ bool wants_to_flee = false;
+
+ // check if we see a bullet
+ Sector* sector = Sector::current();
+ for (Sector::GameObjects::iterator i = sector->gameobjects.begin(); i != sector->gameobjects.end(); ++i) {
+ Bullet* bullet = dynamic_cast<Bullet*>(*i);
+ if (!bullet) continue;
+ if (can_see(*bullet)) wants_to_flee = true;
}
- BadGuy::active_update(elapsed_time);
-}
-
-void
-Igel::collision_solid(const CollisionHit& hit)
-{
- update_on_ground_flag(hit);
-
- if(hit.top || hit.bottom) { // floor or roof
- physic.set_velocity_y(0);
+ // if we flee, handle this ourselves
+ if (wants_to_flee && (!turn_recover_timer.started())) {
+ turn_around();
+ BadGuy::active_update(elapsed_time);
return;
}
-
- // hit left or right
- switch(state) {
- case STATE_NORMAL:
- if( hit.left && dir == LEFT || hit.right && dir ==RIGHT )
- turn_around();
- break;
- }
-}
-
-HitResponse
-Igel::collision_badguy(BadGuy& , const CollisionHit& hit)
-{
- if(hit.top || hit.bottom) { // floor or roof
- physic.set_velocity_y(0);
- return CONTINUE;
- }
-
- // hit left or right
- switch(state) {
-
- case STATE_NORMAL:
- if( hit.left && dir == LEFT || hit.right && dir ==RIGHT )
- turn_around();
- break;
-
- }
-
- return CONTINUE;
+
+ // else adhere to default behaviour
+ WalkingBadguy::active_update(elapsed_time);
}
HitResponse
bool
Igel::collision_squished(Player& )
{
- switch(state) {
-
- case STATE_NORMAL:
- // this will hurt
- return false;
- break;
-
- }
-
- kill_fall();
- return true;
+ // this will hurt
+ return false;
}
IMPLEMENT_FACTORY(Igel, "igel")
#ifndef __IGEL_H__
#define __IGEL_H__
-#include "badguy.hpp"
+#include "walking_badguy.hpp"
#include "moving_object.hpp"
/**
* Badguy "Igel" - a hedgehog that can absorb bullets
*/
-class Igel : public BadGuy
+class Igel : public WalkingBadguy
{
public:
Igel(const lisp::Lisp& reader);
Igel(const Vector& pos, Direction d);
- void activate();
void write(lisp::Writer& writer);
- void collision_solid(const CollisionHit& hit);
- HitResponse collision_badguy(BadGuy& badguy, const CollisionHit& hit);
HitResponse collision_bullet(Bullet& bullet, const CollisionHit& hit);
void active_update(float elapsed_time);
bool can_see(const MovingObject& o); /**< check if we can see o */
private:
- enum State {
- STATE_NORMAL /**< walking around */
- };
- State state;
Timer turn_recover_timer; /**< wait time until we will turn around again when shot at */
+
};
#endif
#include "sspiky.hpp"
static const float WALKSPEED = 80;
-static const float WAKE_TIME = .5;
SSpiky::SSpiky(const lisp::Lisp& reader)
- : BadGuy(reader, "images/creatures/spiky/sleepingspiky.sprite"), state(SSPIKY_SLEEPING)
+ : WalkingBadguy(reader, "images/creatures/spiky/sleepingspiky.sprite", "left", "right"), state(SSPIKY_SLEEPING)
{
+ walk_speed = WALKSPEED;
+ max_drop_height = -1;
}
void
SSpiky::write(lisp::Writer& writer)
{
writer.start_list("sspiky");
-
- writer.write_float("x", start_position.x);
- writer.write_float("y", start_position.y);
-
+ WalkingBadguy::write(writer);
writer.end_list("sspiky");
}
void
SSpiky::collision_solid(const CollisionHit& hit)
{
- if(hit.top || hit.bottom) { // hit floor or roof?
- physic.set_velocity_y(0);
- } else { // hit right or left
- dir = dir == LEFT ? RIGHT : LEFT;
- sprite->set_action(dir == LEFT ? "left" : "right");
- physic.set_velocity_x(-physic.get_velocity_x());
+ if(state != SSPIKY_WALKING) {
+ BadGuy::collision_solid(hit);
+ return;
}
+ WalkingBadguy::collision_solid(hit);
}
HitResponse
-SSpiky::collision_badguy(BadGuy& , const CollisionHit& hit)
+SSpiky::collision_badguy(BadGuy& badguy, const CollisionHit& hit)
{
- if(state != SSPIKY_WALKING)
- return CONTINUE;
-
- if(hit.left || hit.right) {
- dir = dir == LEFT ? RIGHT : LEFT;
- sprite->set_action(dir == LEFT ? "left" : "right");
- physic.set_velocity_x(-physic.get_velocity_x());
+ if(state != SSPIKY_WALKING) {
+ return BadGuy::collision_badguy(badguy, hit);
}
-
- return CONTINUE;
+ return WalkingBadguy::collision_badguy(badguy, hit);
}
void
SSpiky::active_update(float elapsed_time) {
- BadGuy::active_update(elapsed_time);
+
+ if(state == SSPIKY_WALKING) {
+ WalkingBadguy::active_update(elapsed_time);
+ return;
+ }
if(state == SSPIKY_SLEEPING) {
if (inReach_left && inReach_right && inReach_top && inReach_bottom) {
// wake up
- sprite->set_action(dir == LEFT ? "waking-left" : "waking-right");
- if(!timer.started()) timer.start(WAKE_TIME);
+ sprite->set_action(dir == LEFT ? "waking-left" : "waking-right", 1);
state = SSPIKY_WAKING;
}
}
+
+ BadGuy::active_update(elapsed_time);
}
if(state == SSPIKY_WAKING) {
- if(timer.check()) {
+ if(sprite->animation_done()) {
// start walking
- sprite->set_action(dir == LEFT ? "left" : "right");
- physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED);
state = SSPIKY_WALKING;
+ WalkingBadguy::activate();
}
+
+ BadGuy::active_update(elapsed_time);
}
}
#ifndef __SSPIKY_H__
#define __SSPIKY_H__
-#include "badguy.hpp"
+#include "walking_badguy.hpp"
-class SSpiky : public BadGuy
+class SSpiky : public WalkingBadguy
{
public:
SSpiky(const lisp::Lisp& reader);
virtual SSpiky* clone() const { return new SSpiky(*this); }
protected:
- Timer timer;
-
enum SSpikyState {
SSPIKY_SLEEPING,
SSPIKY_WAKING,