[Super-tux-commit] supertux/src display_manager.cpp,NONE,1.1 display_manager.h,NONE,1.1 drawable.h,N
Brought to you by:
wkendrick
Update of /cvsroot/super-tux/supertux/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv27263 Modified Files: Makefile.am badguy.cpp gameloop.cpp gameobjs.cpp gameobjs.h particlesystem.cpp particlesystem.h text.h texture.h tile.h world.cpp world.h Added Files: display_manager.cpp display_manager.h drawable.h game_object.cpp game_object.h vector.h viewport.cpp viewport.h Log Message: -Added new object system and converted some GameObjects to it. Please take a look if you like this new interface and complain as soon as possible :) -Currently you experience some stuff is drawn at the wrong layer, that is because not everything is using the new displaymanager yet. Index: tile.h =================================================================== RCS file: /cvsroot/super-tux/supertux/src/tile.h,v retrieving revision 1.20 retrieving revision 1.21 diff -u -d -r1.20 -r1.21 --- tile.h 17 May 2004 06:26:41 -0000 1.20 +++ tile.h 20 May 2004 12:12:38 -0000 1.21 @@ -28,6 +28,7 @@ #include "globals.h" #include "lispreader.h" #include "setup.h" +#include "vector.h" /** Tile Class @@ -86,6 +87,11 @@ /** 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 Index: world.h =================================================================== RCS file: /cvsroot/super-tux/supertux/src/world.h,v retrieving revision 1.41 retrieving revision 1.42 diff -u -d -r1.41 -r1.42 --- world.h 18 May 2004 16:43:37 -0000 1.41 +++ world.h 20 May 2004 12:12:39 -0000 1.42 @@ -30,6 +30,7 @@ #include "badguy.h" #include "particlesystem.h" #include "gameobjs.h" +#include "display_manager.h" class Level; @@ -54,15 +55,12 @@ 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_; } @@ -95,11 +93,12 @@ 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); Index: Makefile.am =================================================================== RCS file: /cvsroot/super-tux/supertux/src/Makefile.am,v retrieving revision 1.21 retrieving revision 1.22 diff -u -d -r1.21 -r1.22 --- Makefile.am 25 Apr 2004 18:38:03 -0000 1.21 +++ Makefile.am 20 May 2004 12:12:37 -0000 1.22 @@ -74,6 +74,14 @@ 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 # Index: particlesystem.cpp =================================================================== RCS file: /cvsroot/super-tux/supertux/src/particlesystem.cpp,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- particlesystem.cpp 20 Apr 2004 11:09:34 -0000 1.6 +++ particlesystem.cpp 20 May 2004 12:12:38 -0000 1.7 @@ -25,11 +25,15 @@ #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() @@ -40,13 +44,16 @@ } } -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); @@ -68,7 +75,8 @@ } } -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); @@ -82,7 +90,7 @@ 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 { @@ -100,7 +108,7 @@ 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) { @@ -113,7 +121,8 @@ } } -CloudParticleSystem::CloudParticleSystem() +CloudParticleSystem::CloudParticleSystem(DisplayManager& displaymanager) + : ParticleSystem(displaymanager) { cloudimage = new Surface(datadir + "/images/shared/cloud.png", USE_ALPHA); @@ -124,7 +133,7 @@ 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; @@ -137,7 +146,7 @@ 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) { --- NEW FILE: viewport.h --- #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 --- NEW FILE: display_manager.cpp --- #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); } --- NEW FILE: game_object.cpp --- #include "game_object.h" _GameObject::_GameObject() : wants_to_die(false) { } _GameObject::~_GameObject() { } Index: gameobjs.h =================================================================== RCS file: /cvsroot/super-tux/supertux/src/gameobjs.h,v retrieving revision 1.18 retrieving revision 1.19 diff -u -d -r1.18 -r1.19 --- gameobjs.h 18 May 2004 19:17:33 -0000 1.18 +++ gameobjs.h 20 May 2004 12:12:38 -0000 1.19 @@ -28,6 +28,8 @@ #include "scene.h" #include "physic.h" #include "collision.h" +#include "game_object.h" +#include "drawable.h" enum ObjectType { OBJ_NONE, OBJ_BADGUY, OBJ_TRAMPOLINE }; @@ -52,14 +54,18 @@ #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]; @@ -69,41 +75,56 @@ 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; }; Index: gameloop.cpp =================================================================== RCS file: /cvsroot/super-tux/supertux/src/gameloop.cpp,v retrieving revision 1.133 retrieving revision 1.134 diff -u -d -r1.133 -r1.134 --- gameloop.cpp 19 May 2004 10:29:39 -0000 1.133 +++ gameloop.cpp 20 May 2004 12:12:38 -0000 1.134 @@ -657,8 +657,8 @@ /* 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); } Index: particlesystem.h =================================================================== RCS file: /cvsroot/super-tux/supertux/src/particlesystem.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- particlesystem.h 20 Apr 2004 11:09:34 -0000 1.3 +++ particlesystem.h 20 May 2004 12:12:38 -0000 1.4 @@ -22,6 +22,10 @@ #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 @@ -38,15 +42,13 @@ * 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 @@ -67,10 +69,13 @@ 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 @@ -85,10 +90,13 @@ 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 --- NEW FILE: vector.h --- #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 --- NEW FILE: display_manager.h --- #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 --- NEW FILE: viewport.cpp --- #include "viewport.h" ViewPort::ViewPort() { } ViewPort::~ViewPort() { } void ViewPort::set_translation(const Vector& newtranslation) { translation = newtranslation; } Index: badguy.cpp =================================================================== RCS file: /cvsroot/super-tux/supertux/src/badguy.cpp,v retrieving revision 1.80 retrieving revision 1.81 diff -u -d -r1.80 -r1.81 --- badguy.cpp 18 May 2004 18:12:16 -0000 1.80 +++ badguy.cpp 20 May 2004 12:12:38 -0000 1.81 @@ -864,8 +864,8 @@ { 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++; @@ -884,7 +884,8 @@ 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(); @@ -936,7 +937,8 @@ 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... @@ -977,8 +979,8 @@ /* 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); Index: gameobjs.cpp =================================================================== RCS file: /cvsroot/super-tux/supertux/src/gameobjs.cpp,v retrieving revision 1.28 retrieving revision 1.29 diff -u -d -r1.28 -r1.29 --- gameobjs.cpp 19 May 2004 18:22:48 -0000 1.28 +++ gameobjs.cpp 20 May 2004 12:12:38 -0000 1.29 @@ -27,73 +27,51 @@ #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; @@ -101,8 +79,8 @@ 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; @@ -110,107 +88,56 @@ 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 */ @@ -364,6 +291,7 @@ void ObjectManager::load_badguys(std::string filename) { + (void) filename; /* lisp_object_t* root_obj = lisp_read_from_file(filename); --- NEW FILE: game_object.h --- #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 Index: world.cpp =================================================================== RCS file: /cvsroot/super-tux/supertux/src/world.cpp,v retrieving revision 1.99 retrieving revision 1.100 diff -u -d -r1.99 -r1.100 --- world.cpp 19 May 2004 03:20:50 -0000 1.99 +++ world.cpp 20 May 2004 12:12:38 -0000 1.100 @@ -33,6 +33,9 @@ #include "tile.h" #include "resources.h" #include "gameobjs.h" +#include "viewport.h" +#include "display_manager.h" +#include "background.h" Surface* img_distro[4]; @@ -51,8 +54,16 @@ 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(); @@ -75,6 +86,13 @@ 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(); @@ -112,26 +130,14 @@ 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; } @@ -177,11 +183,11 @@ { 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 != "") { @@ -195,18 +201,16 @@ 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) { @@ -227,10 +231,6 @@ } } - /* (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(); @@ -242,18 +242,9 @@ 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) { @@ -263,12 +254,6 @@ 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 @@ -278,21 +263,6 @@ 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); @@ -306,11 +276,9 @@ (*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(); @@ -325,6 +293,20 @@ ++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 */ @@ -541,47 +523,40 @@ } 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* @@ -674,8 +649,8 @@ 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) @@ -705,9 +680,9 @@ 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); @@ -739,7 +714,7 @@ 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++; @@ -788,8 +763,8 @@ 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; --- NEW FILE: drawable.h --- #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 Index: texture.h =================================================================== RCS file: /cvsroot/super-tux/supertux/src/texture.h,v retrieving revision 1.23 retrieving revision 1.24 diff -u -d -r1.23 -r1.24 --- texture.h 9 May 2004 18:08:02 -0000 1.23 +++ texture.h 20 May 2004 12:12:38 -0000 1.24 @@ -29,6 +29,7 @@ #include <list> #include "screen.h" +#include "vector.h" SDL_Surface* sdl_surface_from_sdl_surface(SDL_Surface* sdl_surf, int use_alpha); @@ -92,6 +93,12 @@ 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 Index: text.h =================================================================== RCS file: /cvsroot/super-tux/supertux/src/text.h,v retrieving revision 1.15 retrieving revision 1.16 diff -u -d -r1.15 -r1.16 --- text.h 28 Apr 2004 14:58:24 -0000 1.15 +++ text.h 20 May 2004 12:12:38 -0000 1.16 @@ -23,6 +23,7 @@ #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); @@ -64,6 +65,13 @@ 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*/ |