#include "tile.h"
#include "resources.h"
#include "sprite_manager.h"
+#include "gameloop.h"
Sprite* img_mriceblock_flat_left;
Sprite* img_mriceblock_flat_right;
Sprite* img_jumpy_left_up;
Sprite* img_jumpy_left_down;
Sprite* img_jumpy_left_middle;
+Sprite* img_jumpy_left_iced;
Sprite* img_mrbomb_left;
Sprite* img_mrbomb_right;
+Sprite* img_mrbomb_iced_left;
+Sprite* img_mrbomb_iced_right;
Sprite* img_mrbomb_ticking_left;
Sprite* img_mrbomb_ticking_right;
Sprite* img_mrbomb_explosion;
Sprite* img_flame;
Sprite* img_fish;
Sprite* img_fish_down;
+Sprite* img_fish_iced;
+Sprite* img_fish_iced_down;
Sprite* img_bouncingsnowball_left;
Sprite* img_bouncingsnowball_right;
Sprite* img_bouncingsnowball_squished;
Sprite* img_flyingsnowball_squished;
Sprite* img_spiky_left;
Sprite* img_spiky_right;
+Sprite* img_spiky_iced_left;
+Sprite* img_spiky_iced_right;
Sprite* img_snowball_left;
Sprite* img_snowball_right;
Sprite* img_snowball_squished_left;
old_base = base;
dir = LEFT;
seen = false;
+ frozen_timer.init(true);
animation_offset = 0;
sprite_left = sprite_right = 0;
physic.reset();
}
// if we're in a solid tile at start correct that now
- if(kind != BAD_FLAME && kind != BAD_FISH && collision_object_map(base)) {
- printf("Warning: badguy started in wall!.\n");
- while(collision_object_map(base))
- --base.y;
- }
+ if(kind != BAD_FLAME && kind != BAD_FISH && collision_object_map(base))
+ {
+ std::cout << "Warning: badguy started in wall: kind: " << badguykind_to_string(kind)
+ << " pos: (" << base.x << ", " << base.y << ")" << std::endl;
+ while(collision_object_map(base))
+ --base.y;
+ }
}
void
-BadGuy::action_mriceblock(float frame_ratio)
+BadGuy::action_mriceblock(double frame_ratio)
{
Player& tux = *World::current()->get_tux();
float halfheight = base.height / 2;
if (dir == LEFT && issolid( base.x, (int) base.y + halfheight))
{
+ if (kind == BAD_MRICEBLOCK && mode == KICK)
+ World::current()->trybreakbrick(base.x, (int) base.y + halfheight, false);
+
dir = RIGHT;
physic.set_velocity(-physic.get_velocity_x(), physic.get_velocity_y());
return;
}
if (dir == RIGHT && issolid( base.x + base.width, (int)base.y + halfheight))
{
+ if (kind == BAD_MRICEBLOCK && mode == KICK)
+ World::current()->trybreakbrick(base.x + base.width, (int) base.y + halfheight, false);
+
dir = LEFT;
physic.set_velocity(-physic.get_velocity_x(), physic.get_velocity_y());
return;
if (!issolid(base.x + ((dir == LEFT) ? 0 : base.width),
base.y + base.height))
{
- physic.set_velocity_x(-physic.get_velocity_x());
if (dir == LEFT)
+ {
dir = RIGHT;
+ physic.set_velocity_x(fabsf(physic.get_velocity_x()));
+ }
else
+ {
dir = LEFT;
+ physic.set_velocity_x(-fabsf(physic.get_velocity_x()));
+ }
}
}
}
}
void
-BadGuy::action_jumpy(float frame_ratio)
+BadGuy::action_jumpy(double frame_ratio)
{
- if (fabsf(physic.get_velocity_y()) < 2.5f)
+ if(frozen_timer.check())
+ {
+ set_sprite(img_jumpy_left_iced, img_jumpy_left_iced);
+ return;
+ }
+
+ const float vy = physic.get_velocity_y();
+
+ // XXX: These tests *should* use location from ground, not velocity
+ if (fabsf(vy) > 5.6f)
+ set_sprite(img_jumpy_left_down, img_jumpy_left_down);
+ else if (fabsf(vy) > 5.3f)
set_sprite(img_jumpy_left_middle, img_jumpy_left_middle);
- else if (physic.get_velocity_y() < 0)
+ else
set_sprite(img_jumpy_left_up, img_jumpy_left_up);
- else
- set_sprite(img_jumpy_left_down, img_jumpy_left_down);
Player& tux = *World::current()->get_tux();
}
void
-BadGuy::action_mrbomb(float frame_ratio)
+BadGuy::action_mrbomb(double frame_ratio)
{
+ if(frozen_timer.check())
+ {
+ set_sprite(img_mrbomb_iced_left, img_mrbomb_iced_right);
+ return;
+ }
+
if (dying == DYING_NOT)
check_horizontal_bump(true);
}
void
-BadGuy::action_bomb(float frame_ratio)
+BadGuy::action_bomb(double frame_ratio)
{
static const int TICKINGTIME = 1000;
static const int EXPLODETIME = 1000;
}
void
-BadGuy::action_stalactite(float frame_ratio)
+BadGuy::action_stalactite(double frame_ratio)
{
Player& tux = *World::current()->get_tux();
}
void
-BadGuy::action_flame(float frame_ratio)
+BadGuy::action_flame(double frame_ratio)
{
static const float radius = 100;
static const float speed = 0.02;
}
void
-BadGuy::action_fish(float frame_ratio)
+BadGuy::action_fish(double frame_ratio)
{
+ if(frozen_timer.check())
+ {
+ if(physic.get_velocity_y() < 0)
+ set_sprite(img_fish_iced_down, img_fish_iced_down);
+ else
+ set_sprite(img_fish_iced, img_fish_iced);
+
+ return;
+ }
+
static const float JUMPV = 6;
static const int WAITTIME = 1000;
}
void
-BadGuy::action_bouncingsnowball(float frame_ratio)
+BadGuy::action_bouncingsnowball(double frame_ratio)
{
static const float JUMPV = 4.5;
}
void
-BadGuy::action_flyingsnowball(float frame_ratio)
+BadGuy::action_flyingsnowball(double frame_ratio)
{
static const float FLYINGSPEED = 1;
static const int DIRCHANGETIME = 1000;
}
void
-BadGuy::action_spiky(float frame_ratio)
+BadGuy::action_spiky(double frame_ratio)
{
+ if(frozen_timer.check())
+ {
+ set_sprite(img_spiky_iced_left, img_spiky_iced_right);
+ return;
+ }
+
if (dying == DYING_NOT)
check_horizontal_bump();
}
void
-BadGuy::action_snowball(float frame_ratio)
+BadGuy::action_snowball(double frame_ratio)
{
if (dying == DYING_NOT)
check_horizontal_bump();
}
void
-BadGuy::action(float frame_ratio)
+BadGuy::action(double frame_ratio)
{
// Remove if it's far off the screen:
if (base.x < scroll_x - OFFSCREEN_DISTANCE)
}
// BadGuy fall below the ground
- if (base.y > screen->h) {
+ if (base.y > World::current()->get_level()->height * 32) {
remove_me();
return;
}
+ // Kill us if we landed on spikes
+ if (dying == DYING_NOT
+ && (kind != BAD_STALACTITE && kind != BAD_FLAME && kind != BAD_BOMB)
+ && (isspike(base.x, base.y) || isspike(base.x + base.width, base.y)
+ || isspike(base.x, base.y + base.height)
+ || isspike(base.x + base.width, base.y + base.height)))
+ {
+ physic.set_velocity_y(3);
+ kill_me(0);
+ }
+
// Once it's on screen, it's activated!
if (base.x <= scroll_x + screen->w + OFFSCREEN_DISTANCE)
seen = true;
case BAD_SNOWBALL:
action_snowball(frame_ratio);
break;
+ default:
+ break;
}
}
}
Sprite* sprite = (dir == LEFT) ? sprite_left : sprite_right;
- sprite->draw(base.x - scroll_x, base.y);
+ sprite->draw(base.x, base.y);
if (debug_mode)
- fillrect(base.x - scroll_x, base.y, base.width, base.height, 75,0,75, 150);
+ fillrect(base.x - scroll_x, base.y - scroll_y, base.width, base.height, 75,0,75, 150);
}
void
if(kind == BAD_FLAME || kind == BAD_BOMB || kind == BAD_FISH
|| kind == BAD_FLYINGSNOWBALL)
return;
-
+
+ physic.set_velocity_y(3);
kill_me(25);
}
{
make_player_jump(player);
- World::current()->add_score(base.x - scroll_x,
+ World::current()->add_score(base.x,
base.y, 50 * player_status.score_multiplier);
play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER);
player_status.score_multiplier++;
World::current()->add_bad_guy(base.x, base.y, BAD_BOMB);
make_player_jump(player);
- World::current()->add_score(base.x - scroll_x, base.y, 50 * player_status.score_multiplier);
+ World::current()->add_score(base.x, base.y, 50 * player_status.score_multiplier);
play_sound(sounds[SND_SQUISH], SOUND_CENTER_SPEAKER);
player_status.score_multiplier++;
remove_me();
make_player_jump(player);
- World::current()->add_score(base.x - scroll_x, base.y, 25 * player_status.score_multiplier);
+ World::current()->add_score(base.x, base.y, 25 * player_status.score_multiplier);
player_status.score_multiplier++;
// simply remove the fish...
void
BadGuy::kill_me(int score)
{
- if(kind == BAD_BOMB || kind == BAD_STALACTITE || kind == BAD_FLAME)
+ if(kind == BAD_BOMB)
return;
dying = DYING_FALLING;
tux.holding_something = false;
}
}
-
+
physic.enable_gravity(true);
- physic.set_velocity_y(0);
/* Gain some points: */
- World::current()->add_score(base.x - scroll_x, base.y,
+ if (score != 0)
+ World::current()->add_score(base.x, base.y,
score * player_status.score_multiplier);
/* Play death sound: */
play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
}
+void BadGuy::explode(BadGuy *badguy)
+{
+World::current()->add_bad_guy(badguy->base.x, badguy->base.y, BAD_BOMB);
+badguy->remove_me();
+}
+
void
BadGuy::collision(void *p_c_object, int c_object, CollisionType type)
{
BadGuy* pbad_c = NULL;
+ Bullet* pbullet_c = NULL;
if(type == COLLISION_BUMP) {
bump();
switch (c_object)
{
case CO_BULLET:
- kill_me(10);
+ pbullet_c = (Bullet*) p_c_object;
+
+ if(pbullet_c->kind == FIRE_BULLET)
+ {
+ if (kind != BAD_BOMB && kind != BAD_STALACTITE && kind != BAD_FLAME)
+ kill_me(10);
+ }
+ else if(pbullet_c->kind == ICE_BULLET)
+ {
+ //if(kind == BAD_FLAME)
+ // kill_me(10);
+ //else
+ frozen_timer.start(FROZEN_TIME);
+ }
break;
case CO_BADGUY:
pbad_c = (BadGuy*) p_c_object;
- /* If we're a kicked mriceblock, kill any badguys we hit */
- if(kind == BAD_MRICEBLOCK && mode == KICK)
+ /* If we're a kicked mriceblock, kill [almost] any badguys we hit */
+ if(kind == BAD_MRICEBLOCK && mode == KICK &&
+ kind != BAD_FLAME && kind != BAD_BOMB && kind != BAD_STALACTITE)
{
pbad_c->kill_me(25);
}
- // a held mriceblock gets kills the enemy too but falls to ground then
+ // a held mriceblock kills the enemy too but falls to ground then
else if(kind == BAD_MRICEBLOCK && mode == HELD)
{
pbad_c->kill_me(25);
if (pbad_c->kind == BAD_MRBOMB)
{
// mrbomb transforms into a bomb now
- World::current()->add_bad_guy(pbad_c->base.x, pbad_c->base.y,
- BAD_BOMB);
- pbad_c->remove_me();
+ explode(pbad_c);
return;
}
else if (pbad_c->kind != BAD_MRBOMB)
/* Kill any badguys that get hit by stalactite */
else if (kind == BAD_STALACTITE && dying == DYING_NOT)
{
- pbad_c->kill_me(50);
+ if (pbad_c->kind == BAD_MRBOMB)
+ {
+ // mrbomb transforms into a bomb now
+ explode(pbad_c);
+ return;
+ }
+ else
+ pbad_c->kill_me(50);
}
/* When enemies run into eachother, make them change directions */
// Bounce off of other badguy if we land on top of him
if (base.y + base.height < pbad_c->base.y + pbad_c->base.height)
{
- Direction old_dir = dir;
if (pbad_c->dir == LEFT)
+ {
dir = RIGHT;
+ physic.set_velocity(fabsf(physic.get_velocity_x()), 2);
+ }
else if (pbad_c->dir == RIGHT)
+ {
dir = LEFT;
-
- if (dir != old_dir)
- physic.inverse_velocity_x();
-
- physic.set_velocity(fabs(physic.get_velocity_x()), 2);
+ physic.set_velocity(-fabsf(physic.get_velocity_x()), 2);
+ }
break;
}
if (pbad_c->kind != BAD_FLAME)
{
- if (dir == LEFT)
- dir = RIGHT;
- else if (dir == RIGHT)
- dir = LEFT;
-
- physic.inverse_velocity_x();
+ if (dir == LEFT)
+ {
+ dir = RIGHT;
+ physic.set_velocity_x(fabsf(physic.get_velocity_x()));
+
+ // in case badguys get "jammed"
+ if (physic.get_velocity_x() != 0)
+ base.x = pbad_c->base.x + pbad_c->base.width;
+ }
+ else if (dir == RIGHT)
+ {
+ dir = LEFT;
+ physic.set_velocity_x(-fabsf(physic.get_velocity_x()));
+ }
+
}
}
}
}
+
//---------------------------------------------------------------------------
void load_badguy_gfx()
img_jumpy_left_up = sprite_manager->load("jumpy-left-up");
img_jumpy_left_down = sprite_manager->load("jumpy-left-down");
img_jumpy_left_middle = sprite_manager->load("jumpy-left-middle");
+ img_jumpy_left_iced = sprite_manager->load("jumpy-left-iced");
img_mrbomb_left = sprite_manager->load("mrbomb-left");
img_mrbomb_right = sprite_manager->load("mrbomb-right");
+ img_mrbomb_iced_left = sprite_manager->load("mrbomb-iced-left");
+ img_mrbomb_iced_right = sprite_manager->load("mrbomb-iced-right");
img_mrbomb_ticking_left = sprite_manager->load("mrbomb-ticking-left");
img_mrbomb_ticking_right = sprite_manager->load("mrbomb-ticking-right");
img_mrbomb_explosion = sprite_manager->load("mrbomb-explosion");
img_flame = sprite_manager->load("flame");
img_fish = sprite_manager->load("fish");
img_fish_down = sprite_manager->load("fish-down");
+ img_fish_iced = sprite_manager->load("fish-iced");
+ img_fish_iced_down = sprite_manager->load("fish-iced-down");
img_bouncingsnowball_left = sprite_manager->load("bouncingsnowball-left");
img_bouncingsnowball_right = sprite_manager->load("bouncingsnowball-right");
img_bouncingsnowball_squished = sprite_manager->load("bouncingsnowball-squished");
img_flyingsnowball_squished = sprite_manager->load("flyingsnowball-squished");
img_spiky_left = sprite_manager->load("spiky-left");
img_spiky_right = sprite_manager->load("spiky-right");
+ img_spiky_iced_left = sprite_manager->load("spiky-iced-left");
+ img_spiky_iced_right = sprite_manager->load("spiky-iced-right");
img_snowball_left = sprite_manager->load("snowball-left");
img_snowball_right = sprite_manager->load("snowball-right");
img_snowball_squished_left = sprite_manager->load("snowball-squished-left");