// Hero.cpp : Hero class // // 08.09.1998 / DH - First release // 16.11.1998 / DH - Layer vertical scrolling // 03.01.1999 / DH - Hero sprite (shooting & walking) corrected // // Copyright (c) 1998 Daniel Hartmeier. All rights reserved. #include "Hero.hpp" #include "Sound.hpp" #include "Pad.hpp" // ------------------------------------------------------------------- extern "C++" Image *imageSprites; extern "C++" Sound *sound; // ------------------------------------------------------------------- #define SPRITE_HERO_STAND 0, 92 #define SPRITE_HERO_WALK 24, 92 #define SPRITE_HERO_JUMP 48, 92 #define SPRITE_HERO_SHOOTSTAND 72, 92 #define SPRITE_HERO_SHOOTWALK 96, 92 #define SPRITE_BULLET_HIGH 160, 48 #define SPRITE_BULLET_LOW 160, 52 #define SPRITE_FIREBALL_1 0, 64 #define SPRITE_FIREBALL_2 16, 64 #define SPRITE_FIREBALL_3 32, 64 #define SPRITE_FIREBALL_4 48, 64 #define SPRITE_EXPLOSION_1 64, 64 #define SPRITE_EXPLOSION_2 80, 64 #define SPRITE_EXPLOSION_3 96, 64 #define SPRITE_EXPLOSION_4 112, 64 #define SPRITE_EXPLOSION_5 128, 64 // ------------------------------------------------------------------- inline int abs(int i) { return (i < 0 ? -i : i); } inline int min(int x, int y) { return (x < y ? x : y); } inline int max(int x, int y) { return (x > y ? x : y); } // ------------------------------------------------------------------- Hero::Hero(Handler &handler) : PersonSprite(imageSprites, 24, 20), handler(handler), light(0) { } Hero::~Hero() { if (light) { delete light; light = 0; } } void Hero::reset() { setSpeedX(0); setSpeedY(0); direction_ = 1; step = 0; released = false; dead = dying = false; } void Hero::act(unsigned long pad) { if (dying) dead = true; else { // Left, Right = Accelerate/Stop if (pad & padRight) { direction_ = 1; if (speedX() < 0) setSpeedX(speedX()+128); else if (!speedX()) { step = 0; change(SPRITE_HERO_WALK); setSpeedX(/*256*/160); } else setSpeedX(min(speedX()+/*64*/32, 1024)); } else if (pad & padLeft) { direction_ = -1; if (speedX() > 0) setSpeedX(speedX()-128); else if (!speedX()) { step = 0; change(SPRITE_HERO_WALK); setSpeedX(-/*256*/160); } else setSpeedX(max(speedX()-/*64*/32, -1024)); } else { if (speedX() > 0) setSpeedX(max(speedX()-/*64*/96, 0)); else if (speedX() < 0) setSpeedX(min(speedX()+/*64*/96, 0)); } // X = Jump if (pad & padX) { if (bottom) { if (released) { released = false; setSpeedY(-1500); sound->play(SOUND_DOINK); } } else if (speedY() < 0) setSpeedY(speedY()-80); } else released = true; } // ---------------------------------------------------------------- // Set image according to movement if (bottom) { if (speedX()) { step += abs(speedX()); if (step > 8000) step = 0; if (step > 4000) { if (pad & padS) change(SPRITE_HERO_SHOOTSTAND); else change(SPRITE_HERO_STAND); } else { if (pad & padS) change(SPRITE_HERO_SHOOTWALK); else change(SPRITE_HERO_WALK); } } else { if (pad & padS) change(SPRITE_HERO_SHOOTSTAND); else change(SPRITE_HERO_STAND); } } else { if (pad & padS) change(SPRITE_HERO_SHOOTWALK); else change(SPRITE_HERO_JUMP); } setScale((direction_ > 0 ? ONE : -ONE+1), ONE); // ---------------------------------------------------------------- // Hero carries torch light if (light) light->move(x(), y()); // ---------------------------------------------------------------- return; } // ------------------------------------------------------------------- Bullet::Bullet(const Sprite *parent) : ActiveSprite(imageSprites, 9, 3), parent_(parent), step(0), exploding(false), gone(false) { } Bullet::~Bullet() { } void Bullet::draw(GsOT *ot) { step++; if (exploding) { if (step > 15) gone = true; if (step > 12) change(SPRITE_EXPLOSION_5); else if (step > 9) change(SPRITE_EXPLOSION_4); else if (step > 6) change(SPRITE_EXPLOSION_3); else if (step > 3) change(SPRITE_EXPLOSION_2); else change(SPRITE_EXPLOSION_1); } else { if (step > 4) step = 0; if (step > 2) change(SPRITE_BULLET_HIGH); else change(SPRITE_BULLET_LOW); } setScale((speedX() > 0 ? ONE : -ONE+1), ONE); ActiveSprite::draw(ot); return; } void Bullet::act(unsigned long pad) { // if ((x() < -4) || (x() > 324)) gone = true; if ((x() < -320) || (x() > 640)) gone = true; return; } void Bullet::explode() { if (!exploding) { setSize(16, 16); exploding = true; setSpeedX(0); setSpeedY(0); step = 0; } return; } // ------------------------------------------------------------------- void Fireball::draw(GsOT *ot) { if (exploding) { step++; if (step > 15) gone = true; if (step > 12) change(SPRITE_EXPLOSION_5); else if (step > 9) change(SPRITE_EXPLOSION_4); else if (step > 6) change(SPRITE_EXPLOSION_3); else if (step > 3) change(SPRITE_EXPLOSION_2); else change(SPRITE_EXPLOSION_1); } else { if (step <= 32) step++; if (step > 24) change(SPRITE_FIREBALL_4); else if (step > 16) change(SPRITE_FIREBALL_3); else if (step > 8) change(SPRITE_FIREBALL_2); else change(SPRITE_FIREBALL_1); } setScale((speedX() > 0 ? ONE : -ONE+1), ONE); ActiveSprite::draw(ot); return; } // -------------------------------------------------------------------