music_manager.cpp \
music_manager.h \
musicref.cpp \
-musicref.h
+musicref.h \
+viewport.cpp \
+viewport.h \
+game_object.cpp \
+game_object.h \
+display_manager.h \
+display_manager.cpp \
+background.h \
+background.cpp
# EOF #
{
make_player_jump(player);
- World::current()->add_score(base.x,
- base.y, 50 * player_status.score_multiplier);
+ World::current()->add_score(Vector(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, base.y, 50 * player_status.score_multiplier);
+ World::current()->add_score(Vector(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, base.y, 25 * player_status.score_multiplier);
+ World::current()->add_score(Vector(base.x, base.y),
+ 25 * player_status.score_multiplier);
player_status.score_multiplier++;
// simply remove the fish...
/* Gain some points: */
if (score != 0)
- World::current()->add_score(base.x, base.y,
- score * player_status.score_multiplier);
+ World::current()->add_score(Vector(base.x, base.y),
+ score * player_status.score_multiplier);
/* Play death sound: */
play_sound(sounds[SND_FALL], SOUND_CENTER_SPEAKER);
--- /dev/null
+#include "display_manager.h"
+
+#include <algorithm>
+
+DisplayManager::DisplayManager()
+{
+}
+
+DisplayManager::~DisplayManager()
+{
+}
+
+void
+DisplayManager::add_drawable(Drawable* drawable, int layer)
+{
+ DisplayList::iterator i
+ = std::lower_bound(displaylist.begin(), displaylist.end(), layer);
+ if(i == displaylist.end())
+ displaylist.push_back(DrawingQueueEntry(drawable, layer));
+ else
+ displaylist.insert(i, DrawingQueueEntry(drawable, layer));
+}
+
+void
+DisplayManager::remove_drawable(Drawable* drawable)
+{
+ for(DisplayList::iterator i = displaylist.begin();
+ i != displaylist.end(); ) {
+ if(i->object == drawable)
+ i = displaylist.erase(i);
+ else
+ ++i;
+ }
+}
+
+void
+DisplayManager::draw()
+{
+ for(DisplayList::iterator i = displaylist.begin(); i != displaylist.end();
+ ++i)
+ i->object->draw(viewport, i->layer);
+}
+
--- /dev/null
+#ifndef __DISPLAY_MANAGER_H__
+#define __DISPLAY_MANAGER_H__
+
+#include <vector>
+
+#include "drawable.h"
+#include "viewport.h"
+
+// some constants for predefined layer values
+enum {
+ LAYER_BACKGROUND0 = -300,
+ LAYER_BACKGROUND1 = -200,
+ LAYER_BACKGROUNDTILES = -100,
+ LAYER_TILES = 0,
+ LAYER_OBJECTS = 100,
+ LAYER_FOREGROUND0 = 200,
+ LAYER_FOREGROUND1 = 300
+};
+
+/** This class holds a list of all things that should be drawn to screen
+ */
+class DisplayManager
+{
+public:
+ DisplayManager();
+ ~DisplayManager();
+
+ /** adds an object to the list of stuff that should be drawn each frame.
+ * The layer argument specifies how early an object is drawn.
+ */
+ void add_drawable(Drawable* object, int layer);
+
+ void remove_drawable(Drawable* object);
+
+ void draw();
+
+ ViewPort& get_viewport()
+ { return viewport; }
+
+private:
+ class DrawingQueueEntry {
+ public:
+ DrawingQueueEntry(Drawable* newobject, int newlayer)
+ : object(newobject), layer(newlayer)
+ { }
+
+ bool operator <(int olayer) const
+ {
+ return layer < olayer;
+ }
+
+ Drawable* object;
+ int layer;
+ };
+
+ typedef std::vector<DrawingQueueEntry> DisplayList;
+ DisplayList displaylist;
+ ViewPort viewport;
+};
+
+#endif
+
--- /dev/null
+#ifndef __DRAWABLE_H__
+#define __DRAWABLE_H__
+
+class ViewPort;
+
+/** interface for all game objects that can be drawn on screen.
+ */
+class Drawable
+{
+public:
+ /** This function draws the object on screen.
+ */
+ virtual void draw(ViewPort& viewport, int layer) = 0;
+};
+
+#endif
+
--- /dev/null
+#include "game_object.h"
+
+_GameObject::_GameObject()
+ : wants_to_die(false)
+{
+}
+
+_GameObject::~_GameObject()
+{
+}
+
--- /dev/null
+#ifndef __GAMEOBJECT_HPP__
+#define __GAMEOBJECT_HPP__
+
+#include <string>
+
+class DisplayManager;
+
+/**
+ * Base class for all game objects. This contains functions for:
+ * -querying the actual type of the object
+ * -a flag that indicates if the object wants to be removed. Objects with this
+ * flag will be removed at the end of each frame. This is alot safer than
+ * having some uncontrollable "delete this" in the code.
+ * -an action function that is called once per frame and allows the object to
+ * update it's state.
+ *
+ * Most GameObjects will also implement the DrawableObject interface so that
+ * they can actually be drawn on screen.
+ */
+class _GameObject // TODO rename this once the game has been converted
+{
+public:
+ _GameObject();
+ virtual ~_GameObject();
+
+ /** returns the name of the objecttype, this is mainly usefull for the editor.
+ * For the coding part you should use C++ RTTI (ie. typeid and dynamic_cast)
+ * instead.
+ */
+ virtual std::string type() const = 0;
+ /** This function is called once per frame and allows the object to update
+ * it's state. The elapsed_time is the time since the last frame and should be
+ * the base for all timed things.
+ */
+ virtual void action(float elapsed_time) = 0;
+
+ /** returns true if the object is not scheduled to be removed yet */
+ bool is_valid() const
+ { return !wants_to_die; }
+ /** schedules this object to be removed at the end of the frame */
+ void remove_me()
+ { wants_to_die = true; }
+
+private:
+ /** this flag indicates if the object should be removed at the end of the
+ * frame
+ */
+ bool wants_to_die;
+};
+
+#endif
+
/* Bounce a brick: */
void bumpbrick(float x, float y)
{
- World::current()->add_bouncy_brick(((int)(x + 1) / 32) * 32,
- (int)(y / 32) * 32);
+ World::current()->add_bouncy_brick(Vector(((int)(x + 1) / 32) * 32,
+ (int)(y / 32) * 32));
play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER);
}
#include "sprite_manager.h"
#include "resources.h"
#include "level.h"
+#include "display_manager.h"
-void
-BouncyDistro::init(float x, float y)
+BouncyDistro::BouncyDistro(DisplayManager& displaymanager, const Vector& pos)
+ : position(pos)
{
- base.x = x;
- base.y = y;
- base.ym = -2;
+ ym = -2;
+ displaymanager.add_drawable(this, LAYER_OBJECTS);
}
void
-BouncyDistro::action(double frame_ratio)
+BouncyDistro::action(float elapsed_time)
{
- base.y = base.y + base.ym * frame_ratio;
-
- base.ym += 0.1 * frame_ratio;
+ position.y += ym * elapsed_time;
- if (base.ym >= 0)
- {
- std::vector<BouncyDistro*>::iterator i
- = std::find(World::current()->bouncy_distros.begin(),
- World::current()->bouncy_distros.end(),
- this);
- if (i != World::current()->bouncy_distros.end())
- World::current()->bouncy_distros.erase(i);
- }
+ ym += 0.1 * elapsed_time; // not framerate independent... but who really cares
+ if(ym >= 0)
+ remove_me();
}
void
-BouncyDistro::draw()
+BouncyDistro::draw(ViewPort& viewport, int )
{
- img_distro[0]->draw(base.x - scroll_x,
- base.y - scroll_y);
+ img_distro[0]->draw(viewport.world2screen(position));
}
-void
-BrokenBrick::init(Tile* tile_, float x, float y, float xm, float ym)
+BrokenBrick::BrokenBrick(DisplayManager& displaymanager, Tile* ntile,
+ const Vector& pos, const Vector& nmovement)
+ : tile(ntile), position(pos), movement(nmovement)
{
- tile = tile_;
- base.x = x;
- base.y = y;
- base.xm = xm;
- base.ym = ym;
-
- timer.init(true);
+ displaymanager.add_drawable(this, LAYER_OBJECTS);
timer.start(200);
}
void
-BrokenBrick::action(double frame_ratio)
+BrokenBrick::action(float elapsed_time)
{
- base.x = base.x + base.xm * frame_ratio;
- base.y = base.y + base.ym * frame_ratio;
+ position += movement * elapsed_time;
if (!timer.check())
- {
- std::vector<BrokenBrick*>::iterator i
- = std::find(World::current()->broken_bricks.begin(),
- World::current()->broken_bricks.end(),
- this);
- if (i != World::current()->broken_bricks.end())
- World::current()->broken_bricks.erase(i);
- }
+ remove_me();
}
void
-BrokenBrick::draw()
+BrokenBrick::draw(ViewPort& viewport, int )
{
SDL_Rect src, dest;
src.x = rand() % 16;
src.w = 16;
src.h = 16;
- dest.x = (int)(base.x - scroll_x);
- dest.y = (int)(base.y - scroll_y);
+ dest.x = (int)(position.x - viewport.get_translation().x);
+ dest.y = (int)(position.y - viewport.get_translation().y);
dest.w = 16;
dest.h = 16;
tile->images[0]->draw_part(src.x,src.y,dest.x,dest.y,dest.w,dest.h);
}
-void
-BouncyBrick::init(float x, float y)
+BouncyBrick::BouncyBrick(DisplayManager& displaymanager, const Vector& pos)
+ : position(pos), offset(0), offset_m(-BOUNCY_BRICK_SPEED)
{
- base.x = x;
- base.y = y;
- offset = 0;
- offset_m = -BOUNCY_BRICK_SPEED;
- shape = World::current()->get_level()->gettileid(x, y);
+ displaymanager.add_drawable(this, LAYER_OBJECTS);
+ shape = World::current()->get_level()->gettileid(pos.x, pos.y);
}
void
-BouncyBrick::action(double frame_ratio)
+BouncyBrick::action(float elapsed_time)
{
- offset = (offset + offset_m * frame_ratio);
+ offset += offset_m * elapsed_time;
/* Go back down? */
if (offset < -BOUNCY_BRICK_MAX_OFFSET)
offset_m = BOUNCY_BRICK_SPEED;
-
/* Stop bouncing? */
if (offset >= 0)
- {
- std::vector<BouncyBrick*>::iterator i
- = std::find(World::current()->bouncy_bricks.begin(),
- World::current()->bouncy_bricks.end(),
- this);
- if (i != World::current()->bouncy_bricks.end())
- World::current()->bouncy_bricks.erase(i);
- }
+ remove_me();
}
void
-BouncyBrick::draw()
+BouncyBrick::draw(ViewPort& viewport, int)
{
- SDL_Rect dest;
-
- if (base.x >= scroll_x - 32 &&
- base.x <= scroll_x + screen->w)
- {
- dest.x = (int)(base.x - scroll_x);
- dest.y = (int)(base.y - scroll_y);
- dest.w = 32;
- dest.h = 32;
-
- Level* plevel = World::current()->get_level();
-
- // FIXME: overdrawing hack to clean the tile from the screen to
- // paint it later at on offseted position
- if(plevel->img_bkgd)
- {
- fillrect(base.x - scroll_x, base.y - scroll_y,
- 32,32,
- plevel->bkgd_top.red, plevel->bkgd_top.green, plevel->bkgd_top.blue, 0);
-// FIXME: doesn't respect the gradient, futhermore is this necessary at all??
- }
- else
- {
- int s = ((int)scroll_x / 2)%640;
- plevel->img_bkgd->draw_part(dest.x + s, dest.y,
- dest.x, dest.y,dest.w,dest.h);
- }
-
- Tile::draw(base.x - scroll_x,
- base.y - scroll_y + offset,
- shape);
- }
+ Tile::draw(viewport.world2screen(position + Vector(0, offset)), shape);
}
-void
-FloatingScore::init(float x, float y, int s)
+FloatingScore::FloatingScore(DisplayManager& displaymanager,
+ const Vector& pos, int score)
+ : position(pos)
{
- base.x = x;
- base.y = y - 16;
- timer.init(true);
+ displaymanager.add_drawable(this, LAYER_OBJECTS+1);
timer.start(1000);
- value = s;
+ snprintf(str, 10, "%d", score);
+ position.x += - strlen(str) * 8;
}
void
-FloatingScore::action(double frame_ratio)
+FloatingScore::action(float elapsed_time)
{
- base.y = base.y - 2 * frame_ratio;
+ position.y -= 2 * elapsed_time;
if(!timer.check())
- {
- std::vector<FloatingScore*>::iterator i
- = std::find(World::current()->floating_scores.begin(),
- World::current()->floating_scores.end(),
- this);
- if (i != World::current()->floating_scores.end())
- World::current()->floating_scores.erase(i);
- }
+ remove_me();
}
void
-FloatingScore::draw()
+FloatingScore::draw(ViewPort& viewport, int )
{
- char str[10];
- sprintf(str, "%d", value);
- gold_text->draw(str, (int)base.x + 16 - strlen(str) * 8, (int)base.y, 1);
+ gold_text->draw(str, viewport.world2screen(position));
}
/* Trampoline */
void ObjectManager::load_badguys(std::string filename)
{
+ (void) filename;
/*
lisp_object_t* root_obj = lisp_read_from_file(filename);
#include "scene.h"
#include "physic.h"
#include "collision.h"
+#include "game_object.h"
+#include "drawable.h"
enum ObjectType { OBJ_NONE, OBJ_BADGUY, OBJ_TRAMPOLINE };
#define NO_BOUNCE 0
#define BOUNCE 1
-class BouncyDistro : public GameObject
+class BouncyDistro : public _GameObject, public Drawable
{
- public:
-
- void init(float x, float y);
- void action(double frame_ratio);
- void draw();
- std::string type() { return "BouncyDistro"; };
+public:
+ BouncyDistro(DisplayManager& displaymanager, const Vector& pos);
+ virtual void action(float elapsed_time);
+ virtual void draw(ViewPort& viewport, int layer);
+ virtual std::string type() const
+ { return "BouncyDistro"; };
+
+private:
+ Vector position;
+ float ym;
};
extern Surface* img_distro[4];
class Tile;
-class BrokenBrick : public GameObject
+class BrokenBrick : public _GameObject, public Drawable
{
- public:
+public:
+ BrokenBrick(DisplayManager& displaymanager, Tile* tile,
+ const Vector& pos, const Vector& movement);
+
+ virtual void action(float elapsed_time);
+ virtual void draw(ViewPort& viewport, int layer);
+
+ virtual std::string type() const
+ { return "BrokenBrick"; };
+
+private:
Timer timer;
Tile* tile;
-
- void init(Tile* tile, float x, float y, float xm, float ym);
- void action(double frame_ratio);
- void draw();
- std::string type() { return "BrokenBrick"; };
+ Vector position;
+ Vector movement;
};
-class BouncyBrick : public GameObject
+class BouncyBrick : public _GameObject, public Drawable
{
- public:
- float offset;
- float offset_m;
- int shape;
+public:
+ BouncyBrick(DisplayManager& displaymanager, const Vector& pos);
+ virtual void action(float elapsed_time);
+ virtual void draw(ViewPort& viewport, int layer);
+
+ virtual std::string type() const
+ { return "BouncyBrick"; };
- void init(float x, float y);
- void action(double frame_ratio);
- void draw();
- std::string type() { return "BouncyBrick"; };
+private:
+ Vector position;
+ float offset;
+ float offset_m;
+ int shape;
};
-class FloatingScore : public GameObject
+class FloatingScore : public _GameObject, public Drawable
{
- public:
- int value;
- Timer timer;
+public:
+ FloatingScore(DisplayManager& displaymanager, const Vector& pos, int s);
- void init(float x, float y, int s);
- void action(double frame_ratio);
- void draw();
- std::string type() { return "FloatingScore"; };
+ virtual void action(float elapsed_time);
+ virtual void draw(ViewPort& viewport, int layer);
+ virtual std::string type() const
+ { return "FloatingScore"; };
+
+private:
+ Vector position;
+ char str[10];
+ Timer timer;
};
#include "world.h"
#include "level.h"
#include "scene.h"
+#include "viewport.h"
+#include "display_manager.h"
-ParticleSystem::ParticleSystem()
+ParticleSystem::ParticleSystem(DisplayManager& displaymanager)
{
virtual_width = screen->w;
virtual_height = screen->h;
+
+ displaymanager.add_drawable(this, LAYER_BACKGROUND1);
}
ParticleSystem::~ParticleSystem()
}
}
-void ParticleSystem::draw(float scrollx, float scrolly, int layer)
+void ParticleSystem::draw(ViewPort& viewport, int layer)
{
std::vector<Particle*>::iterator i;
for(i = particles.begin(); i != particles.end(); ++i) {
Particle* particle = *i;
if(particle->layer != layer)
continue;
+
+ float scrollx = viewport.get_translation().x;
+ float scrolly = viewport.get_translation().y;
// remap x,y coordinates onto screencoordinates
float x = fmodf(particle->x - scrollx, virtual_width);
}
}
-SnowParticleSystem::SnowParticleSystem()
+SnowParticleSystem::SnowParticleSystem(DisplayManager& displaymanager)
+ : ParticleSystem(displaymanager)
{
snowimages[0] = new Surface(datadir+"/images/shared/snow0.png", USE_ALPHA);
snowimages[1] = new Surface(datadir+"/images/shared/snow1.png", USE_ALPHA);
SnowParticle* particle = new SnowParticle;
particle->x = rand() % int(virtual_width);
particle->y = rand() % screen->h;
- particle->layer = i % 2;
+ particle->layer = LAYER_BACKGROUND1;
int snowsize = rand() % 3;
particle->texture = snowimages[snowsize];
do {
delete snowimages[i];
}
-void SnowParticleSystem::simulate(float elapsed_time)
+void SnowParticleSystem::action(float elapsed_time)
{
std::vector<Particle*>::iterator i;
for(i = particles.begin(); i != particles.end(); ++i) {
}
}
-CloudParticleSystem::CloudParticleSystem()
+CloudParticleSystem::CloudParticleSystem(DisplayManager& displaymanager)
+ : ParticleSystem(displaymanager)
{
cloudimage = new Surface(datadir + "/images/shared/cloud.png", USE_ALPHA);
CloudParticle* particle = new CloudParticle;
particle->x = rand() % int(virtual_width);
particle->y = rand() % int(virtual_height);
- particle->layer = 0;
+ particle->layer = LAYER_BACKGROUND1;
particle->texture = cloudimage;
particle->speed = -float(250 + rand() % 200) / 1000.0;
delete cloudimage;
}
-void CloudParticleSystem::simulate(float elapsed_time)
+void CloudParticleSystem::action(float elapsed_time)
{
std::vector<Particle*>::iterator i;
for(i = particles.begin(); i != particles.end(); ++i) {
#include <vector>
#include "texture.h"
+#include "drawable.h"
+#include "game_object.h"
+
+class DisplayManager;
/**
* This is the base class for particle systems. It is responsible for storing a
* initialize particles in the constructor and move them in the simulate
* function.
*/
-class ParticleSystem
+class ParticleSystem : public _GameObject, public Drawable
{
public:
- ParticleSystem();
+ ParticleSystem(DisplayManager& displaymanager);
virtual ~ParticleSystem();
- void draw(float scrollx, float scrolly, int layer);
-
- virtual void simulate(float elapsed_time) = 0;
+ virtual void draw(ViewPort& view, int layer);
protected:
class Particle
class SnowParticleSystem : public ParticleSystem
{
public:
- SnowParticleSystem();
+ SnowParticleSystem(DisplayManager& displaymanager);
virtual ~SnowParticleSystem();
- virtual void simulate(float elapsed_time);
+ virtual void action(float elapsed_time);
+
+ std::string type() const
+ { return "SnowParticleSystem"; }
private:
class SnowParticle : public Particle
class CloudParticleSystem : public ParticleSystem
{
public:
- CloudParticleSystem();
+ CloudParticleSystem(DisplayManager& displaymanager);
virtual ~CloudParticleSystem();
- virtual void simulate(float elapsed_time);
+ virtual void action(float elapsed_time);
+
+ std::string type() const
+ { return "SnowParticleSystem"; }
private:
class CloudParticle : public Particle
#include <string>
#include "texture.h"
+#include "vector.h"
void display_text_file(const std::string& file, const std::string& surface, float scroll_speed);
void display_text_file(const std::string& file, Surface* surface, float scroll_speed);
void draw_align(const char* text, int x, int y, TextHAlign halign, TextVAlign valign, int shadowsize = 1, int update = NO_UPDATE);
void erasetext(const char * text, int x, int y, Surface* surf, int update, int shadowsize);
void erasecenteredtext(const char * text, int y, Surface* surf, int update, int shadowsize);
+
+ /// conveniance function
+ void draw(const char* text, const Vector& pos, int shadowsize = 1, int update
+ = NO_UPDATE)
+ {
+ draw(text, int(pos.x), int(pos.y), shadowsize, update);
+ }
};
#endif /*SUPERTUX_TEXT_H*/
#include <list>
#include "screen.h"
+#include "vector.h"
SDL_Surface* sdl_surface_from_sdl_surface(SDL_Surface* sdl_surf, int use_alpha);
void draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha = 255, bool update = false);
void draw_stretched(float x, float y, int w, int h, Uint8 alpha, bool update = false);
void resize(int w_, int h_);
+
+ /// conveniance function
+ void draw(const Vector& pos, Uint8 alpha = 255, bool update = false)
+ {
+ draw(pos.x, pos.y, alpha, update);
+ }
};
/** Surface implementation, all implementation have to inherit from
#include "globals.h"
#include "lispreader.h"
#include "setup.h"
+#include "vector.h"
/**
Tile Class
/** Draw a tile on the screen: */
static void draw(float x, float y, unsigned int c, Uint8 alpha = 255);
static void draw_stretched(float x, float y, int w, int h, unsigned int c, Uint8 alpha = 255);
+
+ static void draw(const Vector& pos, unsigned int c, Uint8 alpha = 255)
+ {
+ draw(pos.x, pos.y, c, alpha);
+ }
};
struct TileGroup
--- /dev/null
+#ifndef __VECTOR_HPP__
+#define __VECTOR_HPP__
+
+class Vector
+{
+public:
+ Vector(float nx, float ny)
+ : x(nx), y(ny)
+ { }
+ Vector(const Vector& other)
+ : x(other.x), y(other.y)
+ { }
+ Vector()
+ : x(0), y(0)
+ { }
+
+ bool operator ==(const Vector& other) const
+ {
+ return x == other.x && y == other.y;
+ }
+
+ const Vector& operator=(const Vector& other)
+ {
+ x = other.x;
+ y = other.y;
+ return *this;
+ }
+
+ Vector operator+(const Vector& other) const
+ {
+ return Vector(x + other.x, y + other.y);
+ }
+
+ Vector operator-(const Vector& other) const
+ {
+ return Vector(x - other.x, y - other.y);
+ }
+
+ Vector operator*(float s) const
+ {
+ return Vector(x * s, y * s);
+ }
+
+ const Vector& operator +=(const Vector& other)
+ {
+ x += other.x;
+ y += other.y;
+ return *this;
+ }
+
+ // ... add the other operators as needed, I'm too lazy now ...
+
+ float x, y; // leave this public, get/set methods just give me headaches
+ // for such simple stuff :)
+};
+
+#endif
+
--- /dev/null
+#include "viewport.h"
+
+ViewPort::ViewPort()
+{
+}
+
+ViewPort::~ViewPort()
+{
+}
+
+void
+ViewPort::set_translation(const Vector& newtranslation)
+{
+ translation = newtranslation;
+}
+
--- /dev/null
+#ifndef __VIEWPORT_H__
+#define __VIEWPORT_H__
+
+#include "vector.h"
+#include "rectangle.h"
+
+class ViewPort
+{
+public:
+ ViewPort();
+ ~ViewPort();
+
+ Vector world2screen(const Vector& worldpos) const
+ {
+ return worldpos - translation;
+ }
+
+ /** returns the current translation (=scroll) vector of the viewport */
+ const Vector& get_translation() const
+ { return translation; }
+
+ void set_translation(const Vector& translation);
+
+private:
+ Vector translation;
+};
+
+#endif
+
#include "tile.h"
#include "resources.h"
#include "gameobjs.h"
+#include "viewport.h"
+#include "display_manager.h"
+#include "background.h"
Surface* img_distro[4];
get_level()->load_gfx();
activate_bad_guys();
- activate_objects();
+ // add background
activate_particle_systems();
+ Background* bg = new Background(displaymanager);
+ if(level->img_bkgd) {
+ bg->set_image(level->img_bkgd, level->bkgd_speed);
+ } else {
+ bg->set_gradient(level->bkgd_top, level->bkgd_bottom);
+ }
+ gameobjects.push_back(bg);
+ activate_objects();
get_level()->load_song();
apply_bonuses();
activate_bad_guys();
activate_objects();
activate_particle_systems();
+ Background* bg = new Background(displaymanager);
+ if(level->img_bkgd) {
+ bg->set_image(level->img_bkgd, level->bkgd_speed);
+ } else {
+ bg->set_gradient(level->bkgd_top, level->bkgd_bottom);
+ }
+ gameobjects.push_back(bg);
get_level()->load_song();
apply_bonuses();
for (Trampolines::iterator i = trampolines.begin(); i != trampolines.end(); ++i)
delete *i;
- for (ParticleSystems::iterator i = particle_systems.begin();
- i != particle_systems.end(); ++i)
- delete *i;
-
- for (std::vector<BouncyDistro*>::iterator i = bouncy_distros.begin();
- i != bouncy_distros.end(); ++i)
- delete *i;
-
- for (std::vector<BrokenBrick*>::iterator i = broken_bricks.begin();
- i != broken_bricks.end(); ++i)
- delete *i;
-
- for (std::vector<BouncyBrick*>::iterator i = bouncy_bricks.begin();
- i != bouncy_bricks.end(); ++i)
+ for (std::vector<_GameObject*>::iterator i = gameobjects.begin();
+ i != gameobjects.end(); ++i) {
+ Drawable* drawable = dynamic_cast<Drawable*> (*i);
+ if(drawable)
+ displaymanager.remove_drawable(drawable);
delete *i;
+ }
- for (std::vector<FloatingScore*>::iterator i = floating_scores.begin();
- i != floating_scores.end(); ++i)
- delete *i;
-
delete level;
}
{
if (level->particle_system == "clouds")
{
- particle_systems.push_back(new CloudParticleSystem);
+ gameobjects.push_back(new CloudParticleSystem(displaymanager));
}
else if (level->particle_system == "snow")
{
- particle_systems.push_back(new SnowParticleSystem);
+ gameobjects.push_back(new SnowParticleSystem(displaymanager));
}
else if (level->particle_system != "")
{
int y,x;
/* Draw the real background */
+#if 0
drawgradient(level->bkgd_top, level->bkgd_bottom);
if(level->img_bkgd)
level->draw_bg();
-
+#endif
/* Draw particle systems (background) */
- std::vector<ParticleSystem*>::iterator p;
- for(p = particle_systems.begin(); p != particle_systems.end(); ++p)
- {
- (*p)->draw(scroll_x, 0, 0);
- }
-
+ displaymanager.get_viewport().set_translation(Vector(scroll_x, scroll_y));
+ displaymanager.draw();
+
/* Draw background: */
for (y = 0; y < VISIBLE_TILES_Y && y < level->height; ++y)
{
}
}
- /* (Bouncy bricks): */
- for (unsigned int i = 0; i < bouncy_bricks.size(); ++i)
- bouncy_bricks[i]->draw();
-
for (BadGuys::iterator i = bad_guys.begin(); i != bad_guys.end(); ++i)
(*i)->draw();
for (unsigned int i = 0; i < bullets.size(); ++i)
bullets[i].draw();
- for (unsigned int i = 0; i < floating_scores.size(); ++i)
- floating_scores[i]->draw();
-
for (unsigned int i = 0; i < upgrades.size(); ++i)
upgrades[i].draw();
- for (unsigned int i = 0; i < bouncy_distros.size(); ++i)
- bouncy_distros[i]->draw();
-
- for (unsigned int i = 0; i < broken_bricks.size(); ++i)
- broken_bricks[i]->draw();
-
/* Draw foreground: */
for (y = 0; y < VISIBLE_TILES_Y && y < level->height; ++y)
{
level->fg_tiles[(int)y + (int)(scroll_y / 32)][(int)x + (int)(scroll_x / 32)]);
}
}
-
- /* Draw particle systems (foreground) */
- for(p = particle_systems.begin(); p != particle_systems.end(); ++p)
- {
- (*p)->draw(scroll_x, 0, 1);
- }
}
void
tux.check_bounds(level->back_scrolling, (bool)level->hor_autoscroll_speed);
scrolling(frame_ratio);
- /* Handle bouncy distros: */
- for (unsigned int i = 0; i < bouncy_distros.size(); i++)
- bouncy_distros[i]->action(frame_ratio);
-
- /* Handle broken bricks: */
- for (unsigned int i = 0; i < broken_bricks.size(); i++)
- broken_bricks[i]->action(frame_ratio);
-
- // Handle all kinds of game objects
- for (unsigned int i = 0; i < bouncy_bricks.size(); i++)
- bouncy_bricks[i]->action(frame_ratio);
-
- for (unsigned int i = 0; i < floating_scores.size(); i++)
- floating_scores[i]->action(frame_ratio);
-
for (unsigned int i = 0; i < bullets.size(); ++i)
bullets[i].action(frame_ratio);
(*i)->action(frame_ratio);
/* update particle systems */
- std::vector<ParticleSystem*>::iterator p;
- for(p = particle_systems.begin(); p != particle_systems.end(); ++p)
- {
- (*p)->simulate(frame_ratio);
- }
+ for(std::vector<_GameObject*>::iterator i = gameobjects.begin();
+ i != gameobjects.end(); ++i)
+ (*i)->action(frame_ratio);
/* Handle all possible collisions. */
collision_handler();
++i;
}
}
+
+ for(std::vector<_GameObject*>::iterator i = gameobjects.begin();
+ i != gameobjects.end(); /* nothing */) {
+ if((*i)->is_valid() == false) {
+ Drawable* drawable = dynamic_cast<Drawable*> (*i);
+ if(drawable)
+ displaymanager.remove_drawable(drawable);
+
+ delete *i;
+ i = gameobjects.erase(i);
+ } else {
+ ++i;
+ }
+ }
}
/* the space that it takes for the screen to start scrolling, regarding */
}
void
-World::add_score(float x, float y, int s)
+World::add_score(const Vector& pos, int s)
{
player_status.score += s;
- FloatingScore* new_floating_score = new FloatingScore();
- new_floating_score->init(x-scroll_x, y-scroll_y, s);
- floating_scores.push_back(new_floating_score);
+ gameobjects.push_back(new FloatingScore(displaymanager, pos, s));
}
void
-World::add_bouncy_distro(float x, float y)
+World::add_bouncy_distro(const Vector& pos)
{
- BouncyDistro* new_bouncy_distro = new BouncyDistro();
- new_bouncy_distro->init(x, y);
- bouncy_distros.push_back(new_bouncy_distro);
+ gameobjects.push_back(new BouncyDistro(displaymanager, pos));
}
void
-World::add_broken_brick(Tile* tile, float x, float y)
+World::add_broken_brick(const Vector& pos, Tile* tile)
{
- add_broken_brick_piece(tile, x, y, -1, -4);
- add_broken_brick_piece(tile, x, y + 16, -1.5, -3);
+ add_broken_brick_piece(pos, Vector(-1, -4), tile);
+ add_broken_brick_piece(pos + Vector(0, 16), Vector(-1.5, -3), tile);
- add_broken_brick_piece(tile, x + 16, y, 1, -4);
- add_broken_brick_piece(tile, x + 16, y + 16, 1.5, -3);
+ add_broken_brick_piece(pos + Vector(16, 0), Vector(1, -4), tile);
+ add_broken_brick_piece(pos + Vector(16, 16), Vector(1.5, -3), tile);
}
void
-World::add_broken_brick_piece(Tile* tile, float x, float y, float xm, float ym)
+World::add_broken_brick_piece(const Vector& pos, const Vector& movement,
+ Tile* tile)
{
- BrokenBrick* new_broken_brick = new BrokenBrick();
- new_broken_brick->init(tile, x, y, xm, ym);
- broken_bricks.push_back(new_broken_brick);
+ gameobjects.push_back(new BrokenBrick(displaymanager, tile, pos, movement));
}
void
-World::add_bouncy_brick(float x, float y)
+World::add_bouncy_brick(const Vector& pos)
{
- BouncyBrick* new_bouncy_brick = new BouncyBrick();
- new_bouncy_brick->init(x,y);
- bouncy_bricks.push_back(new_bouncy_brick);
+ gameobjects.push_back(new BouncyBrick(displaymanager, pos));
}
BadGuy*
if (tile->data > 0)
{
/* Get a distro from it: */
- add_bouncy_distro(((int)(x + 1) / 32) * 32,
- (int)(y / 32) * 32);
+ add_bouncy_distro(
+ Vector(((int)(x + 1) / 32) * 32, (int)(y / 32) * 32));
// TODO: don't handle this in a global way but per-tile...
if (!counting_distros)
plevel->change(x, y, TM_IA, tile->next_tile);
/* Replace it with broken bits: */
- add_broken_brick(tile,
+ add_broken_brick(Vector(
((int)(x + 1) / 32) * 32,
- (int)(y / 32) * 32);
+ (int)(y / 32) * 32), tile);
/* Get some score: */
play_sound(sounds[SND_BRICK], SOUND_CENTER_SPEAKER);
switch(tile->data)
{
case 1: // Box with a distro!
- add_bouncy_distro(posx, posy);
+ add_bouncy_distro(Vector(posx, posy));
play_sound(sounds[SND_DISTRO], SOUND_CENTER_SPEAKER);
player_status.score = player_status.score + SCORE_DISTRO;
player_status.distros++;
if (bounciness == BOUNCE)
{
- add_bouncy_distro(((int)(x + 1) / 32) * 32,
- (int)(y / 32) * 32);
+ add_bouncy_distro(Vector(((int)(x + 1) / 32) * 32,
+ (int)(y / 32) * 32));
}
player_status.score = player_status.score + SCORE_DISTRO;
#include "badguy.h"
#include "particlesystem.h"
#include "gameobjs.h"
+#include "display_manager.h"
class Level;
static World* current_;
public:
BadGuys bad_guys;
- std::vector<BouncyDistro*> bouncy_distros;
- std::vector<BrokenBrick*> broken_bricks;
- std::vector<BouncyBrick*> bouncy_bricks;
- std::vector<FloatingScore*> floating_scores;
std::vector<Upgrade> upgrades;
std::vector<Bullet> bullets;
- typedef std::vector<ParticleSystem*> ParticleSystems;
- ParticleSystems particle_systems;
+ std::vector<_GameObject*> gameobjects;
+
+ DisplayManager displaymanager;
public:
static World* current() { return current_; }
void activate_bad_guys();
void activate_objects();
- void add_score(float x, float y, int s);
- void add_bouncy_distro(float x, float y);
- void add_broken_brick(Tile* tile, float x, float y);
- void add_broken_brick_piece(Tile* tile, float x, float y, float xm, float ym);
- void add_bouncy_brick(float x, float y);
+ void add_score(const Vector& pos, int s);
+ void add_bouncy_distro(const Vector& pos);
+ void add_broken_brick(const Vector& pos, Tile* tile);
+ void add_broken_brick_piece(const Vector& pos,
+ const Vector& movement, Tile* tile);
+ void add_bouncy_brick(const Vector& pos);
BadGuy* add_bad_guy(float x, float y, BadGuyKind kind, bool stay_on_platform = false);
template <class T, class U> T* add_object(U data);