From 403f2652505e814b645892bffaf89a584984f9b8 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Thu, 20 May 2004 23:07:25 +0000 Subject: [PATCH] -converted remaining classes to GameObject -remove old GameObject type -removed base_type.xm,ym and replaced code that was still using them SVN-Revision: 1284 --- src/background.h | 2 +- src/badguy.cpp | 24 ++++---- src/badguy.h | 1 + src/display_manager.cpp | 3 +- src/game_object.cpp | 4 +- src/game_object.h | 6 +- src/gameobjs.cpp | 37 ++++++++---- src/gameobjs.h | 59 ++++++-------------- src/level.cpp | 72 ++++++++++++------------ src/level.h | 2 - src/leveleditor.cpp | 10 +++- src/lispwriter.cpp | 18 +++--- src/lispwriter.h | 18 +++--- src/moving_object.cpp | 2 + src/moving_object.h | 2 +- src/particlesystem.h | 2 +- src/player.cpp | 44 +++++++-------- src/special.cpp | 134 +++++++++++++++++++------------------------- src/special.h | 55 +++++++++--------- src/sprite.cpp | 4 +- src/sprite.h | 4 ++ src/tilemap.h | 2 +- src/type.h | 37 ------------ src/world.cpp | 145 +++++++++++++++++++++--------------------------- src/world.h | 14 ++--- 25 files changed, 305 insertions(+), 396 deletions(-) diff --git a/src/background.h b/src/background.h index 22334db94..46335b960 100644 --- a/src/background.h +++ b/src/background.h @@ -12,7 +12,7 @@ enum { class DisplayManager; -class Background : public _GameObject, public Drawable +class Background : public GameObject, public Drawable { public: Background(DisplayManager& displaymanager); diff --git a/src/badguy.cpp b/src/badguy.cpp index 57f147aee..1f626a658 100644 --- a/src/badguy.cpp +++ b/src/badguy.cpp @@ -156,8 +156,6 @@ BadGuy::BadGuy(DisplayManager& display_manager, BadGuyKind kind_, lispreader.read_float("y", &base.y); base.width = 0; base.height = 0; - base.xm = 0; - base.ym = 0; kind = kind_; @@ -176,8 +174,6 @@ BadGuy::BadGuy(DisplayManager& display_manager, BadGuyKind kind_, base.y = y; base.width = 0; base.height = 0; - base.xm = 0; - base.ym = 0; stay_on_platform = false; kind = kind_; @@ -216,7 +212,7 @@ BadGuy::init() // hack so that the bomb doesn't hurt until it expldes... dying = DYING_SQUISHED; } else if(kind == BAD_FLAME) { - base.ym = 0; // we misuse base.ym as angle for the flame + angle = 0; physic.enable_gravity(false); set_sprite(img_flame, img_flame); } else if(kind == BAD_BOUNCINGSNOWBALL) { @@ -252,13 +248,13 @@ BadGuy::init() void BadGuy::write(LispWriter& writer) { - writer.startList(badguykind_to_string(kind)); + writer.start_list(badguykind_to_string(kind)); - writer.writeFloat("x", base.x); - writer.writeFloat("y", base.y); - writer.writeBool("stay-on-platform", stay_on_platform); + writer.write_float("x", base.x); + writer.write_float("y", base.y); + writer.write_bool("stay-on-platform", stay_on_platform); - writer.endList(badguykind_to_string(kind)); + writer.end_list(badguykind_to_string(kind)); } void @@ -584,10 +580,10 @@ BadGuy::action_flame(double elapsed_time) { static const float radius = 100; static const float speed = 0.02; - base.x = old_base.x + cos(base.ym) * radius; - base.y = old_base.y + sin(base.ym) * radius; + base.x = old_base.x + cos(angle) * radius; + base.y = old_base.y + sin(angle) * radius; - base.ym = fmodf(base.ym + elapsed_time * speed, 2*M_PI); + angle = fmodf(angle + elapsed_time * speed, 2*M_PI); } void @@ -847,7 +843,7 @@ BadGuy::draw(ViewPort& viewport, int) } Sprite* sprite = (dir == LEFT) ? sprite_left : sprite_right; - sprite->draw(base.x, base.y); + sprite->draw(viewport.world2screen(Vector(base.x, base.y))); if (debug_mode) fillrect(base.x - scroll_x, base.y - scroll_y, base.width, base.height, 75,0,75, 150); diff --git a/src/badguy.h b/src/badguy.h index b349c0288..6ffafda11 100644 --- a/src/badguy.h +++ b/src/badguy.h @@ -103,6 +103,7 @@ private: int squishcount; /// number of times this enemy was squiched Timer timer; Physic physic; + float angle; Sprite* sprite_left; Sprite* sprite_right; diff --git a/src/display_manager.cpp b/src/display_manager.cpp index 4559d59c1..162435cde 100644 --- a/src/display_manager.cpp +++ b/src/display_manager.cpp @@ -24,8 +24,7 @@ DisplayManager::add_drawable(Drawable* drawable, int layer) void DisplayManager::remove_drawable(Drawable* drawable) { - for(DisplayList::iterator i = displaylist.begin(); - i != displaylist.end(); ) { + for(DisplayList::iterator i = displaylist.begin(); i != displaylist.end();) { if(i->object == drawable) i = displaylist.erase(i); else diff --git a/src/game_object.cpp b/src/game_object.cpp index a3547849e..0ad837a21 100644 --- a/src/game_object.cpp +++ b/src/game_object.cpp @@ -1,11 +1,11 @@ #include "game_object.h" -_GameObject::_GameObject() +GameObject::GameObject() : wants_to_die(false) { } -_GameObject::~_GameObject() +GameObject::~GameObject() { } diff --git a/src/game_object.h b/src/game_object.h index e5df93bef..e934ac80b 100644 --- a/src/game_object.h +++ b/src/game_object.h @@ -17,11 +17,11 @@ class DisplayManager; * 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 +class GameObject // TODO rename this once the game has been converted { public: - _GameObject(); - virtual ~_GameObject(); + 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) diff --git a/src/gameobjs.cpp b/src/gameobjs.cpp index ffcadcbd6..480b7468b 100644 --- a/src/gameobjs.cpp +++ b/src/gameobjs.cpp @@ -156,13 +156,16 @@ void load_object_gfx() } } -void -Trampoline::init(float x, float y) +Trampoline::Trampoline(DisplayManager& displaymanager, LispReader& reader) { - base.x = x; - base.y = y; + displaymanager.add_drawable(this, LAYER_OBJECTS); + + reader.read_float("x", &base.x); + reader.read_float("y", &base.y); base.width = 32; base.height = 32; + power = 7.5; + reader.read_float("power", &power); frame = 0; mode = M_NORMAL; @@ -170,18 +173,26 @@ Trampoline::init(float x, float y) } void -Trampoline::draw() +Trampoline::write(LispWriter& writer) { - img_trampoline[frame]->draw((int)base.x, (int)base.y); + writer.start_list("trampoline"); - frame = 0; + writer.write_float("x", base.x); + writer.write_float("y", base.y); + writer.write_float("power", power); - if (debug_mode) - fillrect(base.x - scroll_x, base.y - scroll_y, base.width, base.height, 75, 75, 0, 150); + writer.end_list("trampoline"); } void -Trampoline::action(double frame_ratio) +Trampoline::draw(ViewPort& viewport, int ) +{ + img_trampoline[frame]->draw(viewport.world2screen(Vector(base.x, base.y))); + frame = 0; +} + +void +Trampoline::action(float frame_ratio) { // TODO: Remove if we're too far off the screen @@ -232,6 +243,12 @@ Trampoline::action(double frame_ratio) } void +Trampoline::collision(const MovingObject&, int) +{ + // comes later +} + +void Trampoline::collision(void *p_c_object, int c_object, CollisionType type) { Player* pplayer_c = NULL; diff --git a/src/gameobjs.h b/src/gameobjs.h index e303bbc4a..103defa85 100644 --- a/src/gameobjs.h +++ b/src/gameobjs.h @@ -30,31 +30,14 @@ #include "collision.h" #include "game_object.h" #include "drawable.h" - -enum ObjectType { OBJ_NONE, OBJ_BADGUY, OBJ_TRAMPOLINE }; - -template -struct ObjectData -{ - int x; - int y; - ObjectType type; - T type_specific; - - ObjectData(ObjectData* pobject) - : x((int)pobject->x), y((int)pobject->y), type(pobject->type), type_specific(pobject->type_specific) {}; - ObjectData(int x_, int y_, ObjectType type_, T type_specific_) - : x(x_), y(y_), type(type_), type_specific(type_specific_) {}; - - ObjectData() - : x(0), y(0), type(OBJ_NONE), type_specific() {}; -}; +#include "moving_object.h" +#include "lispwriter.h" /* Bounciness of distros: */ #define NO_BOUNCE 0 #define BOUNCE 1 -class BouncyDistro : public _GameObject, public Drawable +class BouncyDistro : public GameObject, public Drawable { public: BouncyDistro(DisplayManager& displaymanager, const Vector& pos); @@ -75,7 +58,7 @@ extern Surface* img_distro[4]; class Tile; -class BrokenBrick : public _GameObject, public Drawable +class BrokenBrick : public GameObject, public Drawable { public: BrokenBrick(DisplayManager& displaymanager, Tile* tile, @@ -94,7 +77,7 @@ private: Vector movement; }; -class BouncyBrick : public _GameObject, public Drawable +class BouncyBrick : public GameObject, public Drawable { public: BouncyBrick(DisplayManager& displaymanager, const Vector& pos); @@ -111,7 +94,7 @@ private: int shape; }; -class FloatingScore : public _GameObject, public Drawable +class FloatingScore : public GameObject, public Drawable { public: FloatingScore(DisplayManager& displaymanager, const Vector& pos, int s); @@ -127,28 +110,18 @@ private: Timer timer; }; - -/* Trampoline */ -struct TrampolineData -{ - float power; -}; - -class Trampoline : public GameObject +class Trampoline : public MovingObject, public Drawable, public Serializable { - public: - void init(float x, float y); - void action(double frame_ratio); - void draw(); - std::string type() { return "Trampoline"; }; - - Trampoline(ObjectData data) - { - power = data.type_specific.power; - - init(data.x, data.y); - }; +public: + Trampoline(DisplayManager& displaymanager, LispReader& reader); + + virtual void write(LispWriter& writer); + virtual void action(float frame_ratio); + virtual void draw(ViewPort& viewport, int layer); + virtual std::string type() const + { return "Trampoline"; }; + virtual void collision(const MovingObject& other, int); void collision(void *p_c_object, int c_object, CollisionType type); Physic physic; diff --git a/src/level.cpp b/src/level.cpp index e7ecdfd49..4bdf8854f 100644 --- a/src/level.cpp +++ b/src/level.cpp @@ -465,54 +465,54 @@ Level::save(const std::string& subset, int level, World* world) LispWriter writer(out); /* Write header: */ - writer.writeComment("SuperTux level made using the built-in leveleditor"); - writer.startList("supertux-level"); - - writer.writeInt("version", 1); - writer.writeString("name", name); - writer.writeString("author", author); - writer.writeString("music", song_title); - writer.writeString("background", bkgd_image); - writer.writeString("particle_system", particle_system); - writer.writeInt("bkgd_speed", bkgd_speed); - writer.writeInt("bkgd_red_top", bkgd_top.red); - writer.writeInt("bkgd_green_top", bkgd_top.green); - writer.writeInt("bkgd_blue_top", bkgd_top.blue); - writer.writeInt("bkgd_red_bottom", bkgd_bottom.red); - writer.writeInt("bkgd_green_bottom", bkgd_bottom.green); - writer.writeInt("bkgd_blue_bottom", bkgd_bottom.blue); - writer.writeInt("time", time_left); - writer.writeInt("width", width); - writer.writeInt("height", height); - writer.writeBool("back_scrolling", back_scrolling); - writer.writeFloat("hor_autoscroll_speed", hor_autoscroll_speed); - writer.writeFloat("gravity", gravity); - - writer.writeIntVector("background-tm", bg_tiles); - writer.writeIntVector("interactive-tm", ia_tiles); - writer.writeIntVector("foreground-tm", fg_tiles); - - writer.startList("reset-points"); + writer.write_comment("SuperTux level made using the built-in leveleditor"); + writer.start_list("supertux-level"); + + writer.write_int("version", 1); + writer.write_string("name", name); + writer.write_string("author", author); + writer.write_string("music", song_title); + writer.write_string("background", bkgd_image); + writer.write_string("particle_system", particle_system); + writer.write_int("bkgd_speed", bkgd_speed); + writer.write_int("bkgd_red_top", bkgd_top.red); + writer.write_int("bkgd_green_top", bkgd_top.green); + writer.write_int("bkgd_blue_top", bkgd_top.blue); + writer.write_int("bkgd_red_bottom", bkgd_bottom.red); + writer.write_int("bkgd_green_bottom", bkgd_bottom.green); + writer.write_int("bkgd_blue_bottom", bkgd_bottom.blue); + writer.write_int("time", time_left); + writer.write_int("width", width); + writer.write_int("height", height); + writer.write_bool("back_scrolling", back_scrolling); + writer.write_float("hor_autoscroll_speed", hor_autoscroll_speed); + writer.write_float("gravity", gravity); + + writer.write_int_vector("background-tm", bg_tiles); + writer.write_int_vector("interactive-tm", ia_tiles); + writer.write_int_vector("foreground-tm", fg_tiles); + + writer.start_list("reset-points"); for(std::vector::iterator i = reset_points.begin(); i != reset_points.end(); ++i) { - writer.startList("point"); - writer.writeInt("x", i->x); - writer.writeInt("y", i->y); + writer.start_list("point"); + writer.write_int("x", i->x); + writer.write_int("y", i->y); } - writer.endList("reset-points"); + writer.end_list("reset-points"); // write objects - writer.startList("objects"); + writer.start_list("objects"); // pick all objects that can be written into a levelfile - for(std::vector<_GameObject*>::iterator it = world->gameobjects.begin(); + for(std::vector::iterator it = world->gameobjects.begin(); it != world->gameobjects.end(); ++it) { Serializable* serializable = dynamic_cast (*it); if(serializable) serializable->write(writer); } - writer.endList("objects"); + writer.end_list("objects"); - writer.endList("supertux-level"); + writer.end_list("supertux-level"); out.close(); } diff --git a/src/level.h b/src/level.h index ed27b8e3f..28eb0b489 100644 --- a/src/level.h +++ b/src/level.h @@ -98,8 +98,6 @@ class Level bool back_scrolling; float hor_autoscroll_speed; - std::vector< ObjectData > trampoline_data; - /** A collection of points to which Tux can be reset after a lost live */ std::vector reset_points; public: diff --git a/src/leveleditor.cpp b/src/leveleditor.cpp index 1c7f3e3ad..f72328991 100644 --- a/src/leveleditor.cpp +++ b/src/leveleditor.cpp @@ -869,11 +869,13 @@ void le_drawinterface() if(TileManager::instance()->get(le_current.tile)->editor_images.size() > 0) TileManager::instance()->get(le_current.tile)->editor_images[0]->draw( screen->w - 32, screen->h - 32); } +#if 0 // XXX FIXME TODO if(le_current.IsObject() && MouseCursor::current() != mouse_select_object) { le_current.obj->draw_on_screen(screen->w - 32, screen->h - 32); le_current.obj->draw_on_screen(cursor_x,cursor_y); } +#endif if(mouse_select_object && selected_game_object != NULL) { @@ -950,10 +952,12 @@ void le_drawlevel() if(!TileManager::instance()->get(le_current.tile)->images.empty()) fillrect(cursor_x-pos_x,cursor_y-pos_y,TileManager::instance()->get(le_current.tile)->images[0]->w,TileManager::instance()->get(le_current.tile)->images[0]->h,50,50,50,50); } +#if 0 // XXX FIXME TODO if(le_current.IsObject()) { le_current.obj->move_to(cursor_x, cursor_y); } +#endif /* clearscreen(current_level.bkgd_red, current_level.bkgd_green, current_level.bkgd_blue); */ @@ -1001,7 +1005,7 @@ void le_drawlevel() } /* Draw the Bad guys: */ - for (std::vector<_GameObject*>::iterator it = le_world->gameobjects.begin(); + for (std::vector::iterator it = le_world->gameobjects.begin(); it != le_world->gameobjects.end(); ++it) { BadGuy* badguy = dynamic_cast (*it); @@ -1019,7 +1023,7 @@ void le_drawlevel() largetux.walk_right->draw( 100 - pos_x, 240 - pos_y); } -void le_change_object_properties(_GameObject *pobj) +void le_change_object_properties(GameObject *pobj) { Surface* cap_screen = Surface::CaptureScreen(); Menu* object_properties_menu = new Menu(); @@ -1475,7 +1479,7 @@ void le_checkevents() cursor_base.width = 32; cursor_base.height = 32; - for(std::vector<_GameObject*>::iterator it = + for(std::vector::iterator it = le_world->gameobjects.begin(); it != le_world->gameobjects.end(); ++it) { MovingObject* mobj = dynamic_cast (*it); diff --git a/src/lispwriter.cpp b/src/lispwriter.cpp index 4221f8157..13cb2633f 100644 --- a/src/lispwriter.cpp +++ b/src/lispwriter.cpp @@ -14,13 +14,13 @@ LispWriter::~LispWriter() } void -LispWriter::writeComment(const std::string& comment) +LispWriter::write_comment(const std::string& comment) { out << "; " << comment << "\n"; } void -LispWriter::startList(const std::string& listname) +LispWriter::start_list(const std::string& listname) { indent(); out << '(' << listname << '\n'; @@ -30,7 +30,7 @@ LispWriter::startList(const std::string& listname) } void -LispWriter::endList(const std::string& listname) +LispWriter::end_list(const std::string& listname) { if(lists.size() == 0) { std::cerr << "Trying to close list '" << listname @@ -50,35 +50,35 @@ LispWriter::endList(const std::string& listname) } void -LispWriter::writeInt(const std::string& name, int value) +LispWriter::write_int(const std::string& name, int value) { indent(); out << '(' << name << ' ' << value << ")\n"; } void -LispWriter::writeFloat(const std::string& name, float value) +LispWriter::write_float(const std::string& name, float value) { indent(); out << '(' << name << ' ' << value << ")\n"; } void -LispWriter::writeString(const std::string& name, const std::string& value) +LispWriter::write_string(const std::string& name, const std::string& value) { indent(); out << '(' << name << " \"" << value << "\")\n"; } void -LispWriter::writeBool(const std::string& name, bool value) +LispWriter::write_bool(const std::string& name, bool value) { indent(); out << '(' << name << ' ' << (value ? "#t" : "#f") << ")\n"; } void -LispWriter::writeIntVector(const std::string& name, +LispWriter::write_int_vector(const std::string& name, const std::vector& value) { indent(); @@ -89,7 +89,7 @@ LispWriter::writeIntVector(const std::string& name, } void -LispWriter::writeIntVector(const std::string& name, +LispWriter::write_int_vector(const std::string& name, const std::vector& value) { indent(); diff --git a/src/lispwriter.h b/src/lispwriter.h index 9443b3806..1f5e57d80 100644 --- a/src/lispwriter.h +++ b/src/lispwriter.h @@ -10,19 +10,19 @@ public: LispWriter(std::ostream& out); ~LispWriter(); - void writeComment(const std::string& comment); + void write_comment(const std::string& comment); - void startList(const std::string& listname); + void start_list(const std::string& listname); - void writeInt(const std::string& name, int value); - void writeFloat(const std::string& name, float value); - void writeString(const std::string& name, const std::string& value); - void writeBool(const std::string& name, bool value); - void writeIntVector(const std::string& name, const std::vector& value); - void writeIntVector(const std::string& name, const std::vector& value); + void write_int(const std::string& name, int value); + void write_float(const std::string& name, float value); + void write_string(const std::string& name, const std::string& value); + void write_bool(const std::string& name, bool value); + void write_int_vector(const std::string& name, const std::vector& value); + void write_int_vector(const std::string& name, const std::vector& value); // add more write-functions when needed... - void endList(const std::string& listname); + void end_list(const std::string& listname); private: void indent(); diff --git a/src/moving_object.cpp b/src/moving_object.cpp index 3c4d566f8..d06f9bb3f 100644 --- a/src/moving_object.cpp +++ b/src/moving_object.cpp @@ -2,6 +2,8 @@ MovingObject::MovingObject() { + base.x = base.y = base.width = base.height = 0; + old_base = base; } MovingObject::~MovingObject() diff --git a/src/moving_object.h b/src/moving_object.h index d8be47df1..e2691c2ba 100644 --- a/src/moving_object.h +++ b/src/moving_object.h @@ -10,7 +10,7 @@ * Base class for all dynamic/moving game objects. This class contains things * for handling the bounding boxes and collision feedback. */ -class MovingObject : public _GameObject +class MovingObject : public GameObject { public: MovingObject(); diff --git a/src/particlesystem.h b/src/particlesystem.h index f0b86b751..4f21a5c62 100644 --- a/src/particlesystem.h +++ b/src/particlesystem.h @@ -42,7 +42,7 @@ class DisplayManager; * initialize particles in the constructor and move them in the simulate * function. */ -class ParticleSystem : public _GameObject, public Drawable +class ParticleSystem : public GameObject, public Drawable { public: ParticleSystem(DisplayManager& displaymanager); diff --git a/src/player.cpp b/src/player.cpp index 0ab9d26a3..790d42bdb 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -89,8 +89,6 @@ Player::init() base.x = plevel->start_pos_x; base.y = plevel->start_pos_y; - base.xm = 0; - base.ym = 0; previous_base = old_base = base; dir = RIGHT; old_dir = dir; @@ -154,8 +152,6 @@ Player::level_begin() { base.x = 100; base.y = 170; - base.xm = 0; - base.ym = 0; previous_base = old_base = base; duck = false; @@ -478,7 +474,8 @@ Player::handle_input() if (input.fire == DOWN && input.old_fire == UP && got_power != NONE_POWER) { holding_something = true; - World::current()->add_bullet(base.x, base.y + (base.height/2), physic.get_velocity_x(), dir); + World::current()->add_bullet(Vector(base.x, base.y + (base.height/2)), + physic.get_velocity_x(), dir); input.old_fire = DOWN; } @@ -578,14 +575,13 @@ Player::grabdistros() void Player::draw(ViewPort& viewport, int ) { - float scroll_x = viewport.get_translation().x; - float scroll_y = viewport.get_translation().y; + Vector pos = viewport.world2screen(Vector(base.x, base.y)); if (!safe_timer.started() || (global_frame_counter % 2) == 0) { if (dying == DYING_SQUISHED) { - smalltux_gameover->draw(base.x, base.y); + smalltux_gameover->draw(pos); } else { @@ -603,46 +599,46 @@ Player::draw(ViewPort& viewport, int ) if (duck && size != SMALL) { if (dir == RIGHT) - sprite->duck_right->draw(base.x, base.y); + sprite->duck_right->draw(pos); else - sprite->duck_left->draw(base.x, base.y); + sprite->duck_left->draw(pos); } else if (skidding_timer.started()) { if (dir == RIGHT) - sprite->skid_right->draw(base.x, base.y); + sprite->skid_right->draw(pos); else - sprite->skid_left->draw(base.x, base.y); + sprite->skid_left->draw(pos); } else if (kick_timer.started()) { if (dir == RIGHT) - sprite->kick_right->draw(base.x, base.y); + sprite->kick_right->draw(pos); else - sprite->kick_left->draw(base.x, base.y); + sprite->kick_left->draw(pos); } else if (physic.get_velocity_y() != 0) { if (dir == RIGHT) - sprite->jump_right->draw(base.x, base.y); + sprite->jump_right->draw(pos); else - sprite->jump_left->draw(base.x, base.y); + sprite->jump_left->draw(pos); } else { if (fabsf(physic.get_velocity_x()) < 1.0f) // standing { if (dir == RIGHT) - sprite->stand_right->draw( base.x, base.y); + sprite->stand_right->draw(pos); else - sprite->stand_left->draw( base.x, base.y); + sprite->stand_left->draw(pos); } else // moving { if (dir == RIGHT) - sprite->walk_right->draw(base.x, base.y); + sprite->walk_right->draw(pos); else - sprite->walk_left->draw(base.x, base.y); + sprite->walk_left->draw(pos); } } @@ -650,9 +646,9 @@ Player::draw(ViewPort& viewport, int ) if (holding_something && physic.get_velocity_y() == 0) { if (dir == RIGHT) - sprite->grab_right->draw(base.x, base.y); + sprite->grab_right->draw(pos); else - sprite->grab_left->draw(base.x, base.y); + sprite->grab_left->draw(pos); } // Draw blinking star overlay @@ -660,9 +656,9 @@ Player::draw(ViewPort& viewport, int ) (invincible_timer.get_left() > TUX_INVINCIBLE_TIME_WARNING || global_frame_counter % 3)) { if (size == SMALL || duck) - smalltux_star->draw(base.x, base.y); + smalltux_star->draw(pos); else - largetux_star->draw(base.x, base.y); + largetux_star->draw(pos); } } } diff --git a/src/special.cpp b/src/special.cpp index 26c30c71d..8ba35ccac 100644 --- a/src/special.cpp +++ b/src/special.cpp @@ -44,72 +44,56 @@ Sprite* img_1up; #define BULLET_STARTING_YM 0 #define BULLET_XM 6 -void -Bullet::init(float x, float y, float xm, Direction dir, int kind_) +Bullet::Bullet(DisplayManager& display_manager, const Vector& pos, float xm, + int dir, int kind_) { + display_manager.add_drawable(this, LAYER_OBJECTS); + life_count = 3; base.width = 4; base.height = 4; if (dir == RIGHT) { - base.x = x + 32; - base.xm = BULLET_XM + xm; + base.x = pos.x + 32; + physic.set_velocity_x(BULLET_XM + xm); } else { - base.x = x; - base.xm = -BULLET_XM + xm; + base.x = pos.x; + physic.set_velocity_x(-BULLET_XM + xm); } - base.y = y + base.height/2; - base.ym = BULLET_STARTING_YM; + base.y = pos.y + base.height/2; + physic.set_velocity_y(-BULLET_STARTING_YM); old_base = base; kind = kind_; } void -Bullet::remove_me() +Bullet::action(float elapsed_time) { - std::vector& bullets = World::current()->bullets; - for(std::vector::iterator i = bullets.begin(); - i != bullets.end(); ++i) { - if( & (*i) == this) { - bullets.erase(i); - return; - } - } - - assert(false); -} - -void -Bullet::action(double frame_ratio) -{ - frame_ratio *= 0.5f; + elapsed_time *= 0.5f; float old_y = base.y; - base.x = base.x + base.xm * frame_ratio; - base.y = base.y + base.ym * frame_ratio; - + physic.apply(elapsed_time, base.x, base.y); collision_swept_object_map(&old_base,&base); if (issolid(base.x, base.y + 4) || issolid(base.x, base.y)) { base.y = old_y; - base.ym = -base.ym; - if (base.ym > 9) - base.ym = 9; - else if (base.ym < -9) - base.ym = -9; + physic.set_velocity_y(-physic.get_velocity_y()); life_count -= 1; } if(kind == FIRE_BULLET) - base.ym = base.ym + 0.5 * frame_ratio; - else if(kind == ICE_BULLET) - base.ym = 0; + // @not framerate independant :-/ + physic.set_velocity_y(physic.get_velocity_y() - 0.5 * elapsed_time); + if(physic.get_velocity_y() > 9) + physic.set_velocity_y(9); + else if(physic.get_velocity_y() < -9) + physic.set_velocity_y(-9); if (base.x < scroll_x || base.x > scroll_x + screen->w || @@ -120,20 +104,21 @@ Bullet::action(double frame_ratio) { remove_me(); } - } void -Bullet::draw() +Bullet::draw(ViewPort& viewport, int ) { - if (base.x >= scroll_x - base.width && - base.x <= scroll_x + screen->w) - { - if(kind == FIRE_BULLET) - img_firebullet->draw(base.x, base.y); - else if(kind == ICE_BULLET) - img_icebullet->draw(base.x, base.y); - } + if(kind == FIRE_BULLET) + img_firebullet->draw(viewport.world2screen(Vector(base.x, base.y))); + else if(kind == ICE_BULLET) + img_icebullet->draw(viewport.world2screen(Vector(base.x, base.y))); +} + +void +Bullet::collision(const MovingObject& , int) +{ + // later } void @@ -144,16 +129,20 @@ Bullet::collision(int c_object) } } -void -Upgrade::init(float x_, float y_, Direction dir_, UpgradeKind kind_) +//--------------------------------------------------------------------------- + +Upgrade::Upgrade(DisplayManager& display_manager, const Vector& pos, + Direction dir_, UpgradeKind kind_) { + display_manager.add_drawable(this, LAYER_OBJECTS); + kind = kind_; dir = dir_; base.width = 32; base.height = 0; - base.x = x_; - base.y = y_; + base.x = pos.x; + base.y = pos.y; old_base = base; physic.reset(); @@ -172,29 +161,18 @@ Upgrade::init(float x_, float y_, Direction dir_, UpgradeKind kind_) } } -void -Upgrade::remove_me() +Upgrade::~Upgrade() { - std::vector& upgrades = World::current()->upgrades; - for(std::vector::iterator i = upgrades.begin(); - i != upgrades.end(); ++i) { - if( & (*i) == this) { - upgrades.erase(i); - return; - } - } - - assert(false); } void -Upgrade::action(double frame_ratio) +Upgrade::action(float elapsed_time) { if (kind == UPGRADE_ICEFLOWER || kind == UPGRADE_FIREFLOWER || kind == UPGRADE_GROWUP) { if (base.height < 32) { /* Rise up! */ - base.height = base.height + 0.7 * frame_ratio; + base.height = base.height + 0.7 * elapsed_time; if(base.height > 32) base.height = 32; @@ -213,7 +191,7 @@ Upgrade::action(double frame_ratio) } /* Move around? */ - physic.apply(frame_ratio, base.x, base.y); + physic.apply(elapsed_time, base.x, base.y); if(kind == UPGRADE_GROWUP) { collision_swept_object_map(&old_base, &base); } @@ -255,7 +233,7 @@ Upgrade::action(double frame_ratio) } void -Upgrade::draw() +Upgrade::draw(ViewPort& viewport, int) { SDL_Rect dest; @@ -263,8 +241,8 @@ Upgrade::draw() { /* Rising up... */ - dest.x = (int)(base.x); - dest.y = (int)(base.y + 32 - base.height); + dest.x = (int)(base.x - viewport.get_translation().x); + dest.y = (int)(base.y + 32 - base.height - viewport.get_translation().y); dest.w = 32; dest.h = (int)base.height; @@ -283,27 +261,23 @@ Upgrade::draw() { if (kind == UPGRADE_GROWUP) { - img_growup->draw( - base.x, base.y); + img_growup->draw(viewport.world2screen(Vector(base.x, base.y))); } else if (kind == UPGRADE_ICEFLOWER) { - img_iceflower->draw( - base.x, base.y); + img_iceflower->draw(viewport.world2screen(Vector(base.x, base.y))); } else if (kind == UPGRADE_FIREFLOWER) { - img_fireflower->draw( - base.x, base.y); + img_fireflower->draw(viewport.world2screen(Vector(base.x, base.y))); } else if (kind == UPGRADE_HERRING) { - img_star->draw( - base.x, base.y); + img_star->draw(viewport.world2screen(Vector(base.x, base.y))); } else if (kind == UPGRADE_1UP) { - img_1up->draw( base.x, base.y); + img_1up->draw(viewport.world2screen(Vector(base.x, base.y))); } } } @@ -329,6 +303,12 @@ Upgrade::bump(Player* player) } void +Upgrade::collision(const MovingObject& , int) +{ + // later +} + +void Upgrade::collision(void* p_c_object, int c_object, CollisionType type) { Player* pplayer = NULL; diff --git a/src/special.h b/src/special.h index a28c7421f..5ea0d59c2 100644 --- a/src/special.h +++ b/src/special.h @@ -41,28 +41,27 @@ enum UpgradeKind { void load_special_gfx(); void free_special_gfx(); -class Upgrade : public GameObject +class Upgrade : public MovingObject, public Drawable { public: UpgradeKind kind; Direction dir; Physic physic; - void init(float x, float y, Direction dir, UpgradeKind kind); - void action(double frame_ratio); - void draw(); - void collision(void* p_c_object, int c_object, CollisionType type); - std::string type() { return "Upgrade"; }; + Upgrade(DisplayManager& display_manager, const Vector& pos, Direction dir, + UpgradeKind kind); + virtual ~Upgrade(); - ~Upgrade() {}; + virtual void action(float frame_ratio); + virtual void draw(ViewPort& viewport, int layer); -private: - /** removes the Upgrade from the global upgrade list. Note that after this - * call the class doesn't exist anymore! So don't use any member variables - * anymore then - */ - void remove_me(); + virtual void collision(const MovingObject& other, int); + void collision(void* p_c_object, int c_object, CollisionType type); + virtual std::string type() const + { return "Upgrade"; }; + +private: void bump(Player* player); }; @@ -71,27 +70,25 @@ enum BulletsKind { ICE_BULLET }; -class Bullet : public GameObject +class Bullet : public MovingObject, public Drawable { - public: - int life_count; - base_type base; - base_type old_base; - - int kind; +public: + Bullet(DisplayManager& manager, const Vector& pos, float xm, int dir, + int kind); - void init(float x, float y, float xm, Direction dir, int kind_); - void action(double frame_ratio); - void draw(); + virtual void action(float frame_ratio); + virtual void draw(ViewPort& viewport, int layer); void collision(int c_object); - std::string type() { return "Bullet"; }; + virtual void collision(const MovingObject& other_object, int type); + virtual std::string type() const + { return "Bullet"; }; + + int kind; + private: - /** removes the Upgrade from the global upgrade list. Note that after this - * call the class doesn't exist anymore! So don't use any member variables - * anymore then - */ - void remove_me(); + int life_count; + Physic physic; }; #endif /*SUPERTUX_SPECIAL_H*/ diff --git a/src/sprite.cpp b/src/sprite.cpp index 7d23c1dc2..bb31251a8 100644 --- a/src/sprite.cpp +++ b/src/sprite.cpp @@ -79,7 +79,7 @@ Sprite::draw(float x, float y) unsigned int frame = get_current_frame(); if (frame < surfaces.size()) - surfaces[frame]->draw(x - x_hotspot - scroll_x, y - y_hotspot - scroll_y); + surfaces[frame]->draw(x - x_hotspot, y - y_hotspot); } void @@ -89,7 +89,7 @@ Sprite::draw_part(float sx, float sy, float x, float y, float w, float h) unsigned int frame = get_current_frame(); if (frame < surfaces.size()) - surfaces[frame]->draw_part(sx, sy, x - x_hotspot - scroll_x, y - y_hotspot - scroll_y , w, h); + surfaces[frame]->draw_part(sx, sy, x - x_hotspot, y - y_hotspot, w, h); } void diff --git a/src/sprite.h b/src/sprite.h index ce5889a57..0671e270c 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -24,6 +24,7 @@ #include #include "lispreader.h" #include "texture.h" +#include "vector.h" class Sprite { @@ -59,6 +60,9 @@ class Sprite void draw_part(float sx, float sy, float x, float y, float w, float h); int get_current_frame() const; + void draw(const Vector& pos) + { draw(pos.x, pos.y); } + std::string get_name() const { return name; } int get_width() const; int get_height() const; diff --git a/src/tilemap.h b/src/tilemap.h index 682e76d83..364dabc43 100644 --- a/src/tilemap.h +++ b/src/tilemap.h @@ -9,7 +9,7 @@ class Level; /** * This class is reponsible for drawing the level tiles */ -class TileMap : public _GameObject, public Drawable +class TileMap : public GameObject, public Drawable { public: TileMap(DisplayManager& manager, Level* level); diff --git a/src/type.h b/src/type.h index f018f3bbf..34b320633 100644 --- a/src/type.h +++ b/src/type.h @@ -31,47 +31,10 @@ struct base_type { float x; float y; - float xm; - float ym; float width; float height; }; - -/* Base class for all dynamic game object. */ -class GameObject -{ - -public: - GameObject() {}; - virtual ~GameObject() {}; - virtual void action(double frame_ratio) = 0; - virtual void draw() = 0; - virtual std::string type() = 0; - /* Draw ignoring the scroll_x value. FIXME: Hack? Should be discussed. @tobgle*/ - void draw_on_screen(float x = -1, float y = -1) - { - base_type btmp = base; - if(x != -1 || y != -1) - { - btmp = base; - if(x != -1) - base.x = x; - if(y != -1) - base.y = y; - } - float tmp = scroll_x; - scroll_x = 0; draw(); - scroll_x = tmp; - base = btmp; - }; - - void move_to(float x, float y) { base.x = x; base.y = y; }; - - base_type base; - base_type old_base; -}; - struct string_list_type { int num_items; diff --git a/src/world.cpp b/src/world.cpp index f3a91425b..11bc77cbc 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -69,7 +69,6 @@ World::World(const std::string& filename) // add tilemap gameobjects.push_back(new TileMap(displaymanager, get_level())); - activate_objects(); get_level()->load_song(); apply_bonuses(); @@ -92,7 +91,6 @@ World::World(const std::string& subset, int level_nr) set_defaults(); get_level()->load_gfx(); - activate_objects(); activate_particle_systems(); Background* bg = new Background(displaymanager); if(level->img_bkgd) { @@ -134,7 +132,7 @@ World::~World() for (Trampolines::iterator i = trampolines.begin(); i != trampolines.end(); ++i) delete *i; - for (std::vector<_GameObject*>::iterator i = gameobjects.begin(); + for (std::vector::iterator i = gameobjects.begin(); i != gameobjects.end(); ++i) { Drawable* drawable = dynamic_cast (*i); if(drawable) @@ -162,12 +160,21 @@ World::set_defaults() } void -World::add_object(_GameObject* object) +World::add_object(GameObject* object) { // XXX hack for now until new collision code is ready BadGuy* badguy = dynamic_cast (object); if(badguy) bad_guys.push_back(badguy); + Bullet* bullet = dynamic_cast (object); + if(bullet) + bullets.push_back(bullet); + Upgrade* upgrade = dynamic_cast (object); + if(upgrade) + upgrades.push_back(upgrade); + Trampoline* trampoline = dynamic_cast (object); + if(trampoline) + trampolines.push_back(trampoline); gameobjects.push_back(object); } @@ -177,35 +184,22 @@ World::parse_objects(lisp_object_t* cur) { while(!lisp_nil_p(cur)) { lisp_object_t* data = lisp_car(cur); - std::string object_type = ""; + std::string object_type = lisp_symbol(lisp_car(data)); LispReader reader(lisp_cdr(data)); - reader.read_string("type", &object_type); - if(object_type == "badguy" || object_type == "") - { - BadGuyKind kind = badguykind_from_string( - lisp_symbol(lisp_car(data))); + if(object_type == "trampoline") { + add_object(new Trampoline(displaymanager, reader)); + } else { + BadGuyKind kind = badguykind_from_string(object_type); add_object(new BadGuy(displaymanager, kind, reader)); } - // TODO add parsing code for trampolines - + cur = lisp_cdr(cur); } } void -World::activate_objects() -{ - for (std::vector< ObjectData >::iterator i = level->trampoline_data.begin(); - i != level->trampoline_data.end(); - ++i) - { - add_object >(*i); - } -} - -void World::activate_particle_systems() { if (level->particle_system == "clouds") @@ -228,15 +222,6 @@ World::draw() /* Draw objects */ displaymanager.get_viewport().set_translation(Vector(scroll_x, scroll_y)); displaymanager.draw(); - - for (Trampolines::iterator i = trampolines.begin(); i != trampolines.end(); ++i) - (*i)->draw(); - - for (unsigned int i = 0; i < bullets.size(); ++i) - bullets[i].draw(); - - for (unsigned int i = 0; i < upgrades.size(); ++i) - upgrades[i].draw(); } void @@ -245,15 +230,6 @@ World::action(double frame_ratio) tux->check_bounds(level->back_scrolling, (bool)level->hor_autoscroll_speed); scrolling(frame_ratio); - for (unsigned int i = 0; i < bullets.size(); ++i) - bullets[i].action(frame_ratio); - - for (unsigned int i = 0; i < upgrades.size(); i++) - upgrades[i].action(frame_ratio); - - for (Trampolines::iterator i = trampolines.begin(); i != trampolines.end(); ++i) - (*i)->action(frame_ratio); - /* update objects (don't use iterators here, because the list might change * during the iteration) */ @@ -264,7 +240,7 @@ World::action(double frame_ratio) collision_handler(); /** cleanup marked objects */ - for(std::vector<_GameObject*>::iterator i = gameobjects.begin(); + for(std::vector::iterator i = gameobjects.begin(); i != gameobjects.end(); /* nothing */) { if((*i)->is_valid() == false) { Drawable* drawable = dynamic_cast (*i); @@ -272,8 +248,27 @@ World::action(double frame_ratio) displaymanager.remove_drawable(drawable); BadGuy* badguy = dynamic_cast (*i); if(badguy) { - std::remove(bad_guys.begin(), bad_guys.end(), badguy); - } + bad_guys.erase(std::remove(bad_guys.begin(), bad_guys.end(), badguy), + bad_guys.end()); + } + Bullet* bullet = dynamic_cast (*i); + if(bullet) { + bullets.erase( + std::remove(bullets.begin(), bullets.end(), bullet), + bullets.end()); + } + Upgrade* upgrade = dynamic_cast (*i); + if(upgrade) { + upgrades.erase( + std::remove(upgrades.begin(), upgrades.end(), upgrade), + upgrades.end()); + } + Trampoline* trampoline = dynamic_cast (*i); + if(trampoline) { + trampolines.erase( + std::remove(trampolines.begin(), trampolines.end(), trampoline), + trampolines.end()); + } delete *i; i = gameobjects.erase(i); @@ -403,14 +398,12 @@ World::collision_handler() if((*j)->dying != DYING_NOT) continue; - if(rectcollision(bullets[i].base, (*j)->base)) + if(rectcollision(bullets[i]->base, (*j)->base)) { // We have detected a collision and now call the // collision functions of the collided objects. - // collide with bad_guy first, since bullet_collision will - // delete the bullet - (*j)->collision(&bullets[i], CO_BULLET); - bullets[i].collision(CO_BADGUY); + (*j)->collision(&bullets[i], CO_BULLET, COLLISION_NORMAL); + bullets[i]->collision(CO_BADGUY); break; // bullet is invalid now, so break } } @@ -469,11 +462,11 @@ World::collision_handler() // CO_UPGRADE & CO_PLAYER check for(unsigned int i = 0; i < upgrades.size(); ++i) { - if(rectcollision(upgrades[i].base, tux->base)) + if(rectcollision(upgrades[i]->base, tux->base)) { // We have detected a collision and now call the collision // functions of the collided objects. - upgrades[i].collision(tux, CO_PLAYER, COLLISION_NORMAL); + upgrades[i]->collision(tux, CO_PLAYER, COLLISION_NORMAL); } } @@ -542,28 +535,14 @@ World::add_bad_guy(float x, float y, BadGuyKind kind) return badguy; } -template -T* -World::add_object(U data) -{ - T* tobject = new T(data); - - if (data.type == OBJ_TRAMPOLINE) - trampolines.push_back(tobject); - - return tobject; -} - void -World::add_upgrade(float x, float y, Direction dir, UpgradeKind kind) +World::add_upgrade(const Vector& pos, Direction dir, UpgradeKind kind) { - Upgrade new_upgrade; - new_upgrade.init(x,y,dir,kind); - upgrades.push_back(new_upgrade); + add_object(new Upgrade(displaymanager, pos, dir, kind)); } void -World::add_bullet(float x, float y, float xm, Direction dir) +World::add_bullet(const Vector& pos, float xm, Direction dir) { if(tux->got_power == Player::FIRE_POWER) { @@ -576,12 +555,14 @@ World::add_bullet(float x, float y, float xm, Direction dir) return; } - Bullet new_bullet; + Bullet* new_bullet = 0; if(tux->got_power == Player::FIRE_POWER) - new_bullet.init(x,y,xm,dir, FIRE_BULLET); + new_bullet = new Bullet(displaymanager, pos, xm, dir, FIRE_BULLET); else if(tux->got_power == Player::ICE_POWER) - new_bullet.init(x,y,xm,dir, ICE_BULLET); - bullets.push_back(new_bullet); + new_bullet = new Bullet(displaymanager, pos, xm, dir, ICE_BULLET); + else + st_abort("wrong bullet type.", ""); + add_object(new_bullet); play_sound(sounds[SND_SHOOT], SOUND_CENTER_SPEAKER); } @@ -697,26 +678,26 @@ World::tryemptybox(float x, float y, Direction col_side) case 2: // Add a fire flower upgrade! if (tux->size == SMALL) /* Tux is small, add mints! */ - add_upgrade(posx, posy, col_side, UPGRADE_GROWUP); + add_upgrade(Vector(posx, posy), col_side, UPGRADE_GROWUP); else /* Tux is big, add a fireflower: */ - add_upgrade(posx, posy, col_side, UPGRADE_FIREFLOWER); + add_upgrade(Vector(posx, posy), col_side, UPGRADE_FIREFLOWER); play_sound(sounds[SND_UPGRADE], SOUND_CENTER_SPEAKER); break; case 5: // Add an ice flower upgrade! if (tux->size == SMALL) /* Tux is small, add mints! */ - add_upgrade(posx, posy, col_side, UPGRADE_GROWUP); + add_upgrade(Vector(posx, posy), col_side, UPGRADE_GROWUP); else /* Tux is big, add an iceflower: */ - add_upgrade(posx, posy, col_side, UPGRADE_ICEFLOWER); + add_upgrade(Vector(posx, posy), col_side, UPGRADE_ICEFLOWER); play_sound(sounds[SND_UPGRADE], SOUND_CENTER_SPEAKER); break; case 3: // Add a golden herring - add_upgrade(posx, posy, col_side, UPGRADE_HERRING); + add_upgrade(Vector(posx, posy), col_side, UPGRADE_HERRING); break; case 4: // Add a 1up extra - add_upgrade(posx, posy, col_side, UPGRADE_1UP); + add_upgrade(Vector(posx, posy), col_side, UPGRADE_1UP); break; default: break; @@ -764,11 +745,11 @@ World::trybumpbadguy(float x, float y) // Upgrades: for (unsigned int i = 0; i < upgrades.size(); i++) { - if (upgrades[i].base.height == 32 && - upgrades[i].base.x >= x - 32 && upgrades[i].base.x <= x + 32 && - upgrades[i].base.y >= y - 16 && upgrades[i].base.y <= y + 16) + if (upgrades[i]->base.height == 32 && + upgrades[i]->base.x >= x - 32 && upgrades[i]->base.x <= x + 32 && + upgrades[i]->base.y >= y - 16 && upgrades[i]->base.y <= y + 16) { - upgrades[i].collision(tux, CO_PLAYER, COLLISION_BUMP); + upgrades[i]->collision(tux, CO_PLAYER, COLLISION_BUMP); } } } diff --git a/src/world.h b/src/world.h index e68ed4134..04e00c614 100644 --- a/src/world.h +++ b/src/world.h @@ -56,9 +56,9 @@ private: public: BadGuys bad_guys; - std::vector upgrades; - std::vector bullets; - std::vector<_GameObject*> gameobjects; + std::vector upgrades; + std::vector bullets; + std::vector gameobjects; DisplayManager displaymanager; @@ -74,7 +74,7 @@ public: Level* get_level() { return level; } Player* get_tux() { return tux; } - void add_object(_GameObject* object); + void add_object(GameObject* object); void set_defaults(); @@ -93,7 +93,6 @@ public: void parse_objects(lisp_object_t* cur); void activate_particle_systems(); - void activate_objects(); void add_score(const Vector& pos, int s); void add_bouncy_distro(const Vector& pos); @@ -103,10 +102,9 @@ public: void add_bouncy_brick(const Vector& pos); BadGuy* add_bad_guy(float x, float y, BadGuyKind kind); - template T* add_object(U data); - void add_upgrade(float x, float y, Direction dir, UpgradeKind kind); - void add_bullet(float x, float y, float xm, Direction dir); + void add_upgrade(const Vector& pos, Direction dir, UpgradeKind kind); + void add_bullet(const Vector& pos, float xm, Direction dir); /** Try to grab the coin at the given coordinates */ void trygrabdistro(float x, float y, int bounciness); -- 2.11.0