From f9c5c22959ac3020274f3be3531d176e413b0220 Mon Sep 17 00:00:00 2001 From: Ingo Ruhnke Date: Mon, 14 Jun 2004 22:08:01 +0000 Subject: [PATCH] - fixed the bouncybrick artifact bug - replaced plain tile-id integer with a hopefully lightwight struct - replaced a few Tile* with Tile& to make it more clear that Tilemap::get() always returns a valid tile - added support for (grid x y width height) for the .stgt file format, can be used to load multiple tiles from a single image SVN-Revision: 1488 --- src/camera.h | 3 ++- src/defines.h | 2 ++ src/gameobjs.cpp | 14 +++++++++----- src/gameobjs.h | 4 +++- src/leveleditor.cpp | 2 +- src/lispwriter.h | 1 + src/sector.cpp | 3 ++- src/tile.cpp | 40 ++++++++++++++++++++++++++-------------- src/tile.h | 7 ++++--- src/tilemap.cpp | 52 +++++++++++++++++++++++++++++++++++++++------------- src/tilemap.h | 15 ++++++++++++--- 11 files changed, 101 insertions(+), 42 deletions(-) diff --git a/src/camera.h b/src/camera.h index 9c6e6c514..9c1170880 100644 --- a/src/camera.h +++ b/src/camera.h @@ -23,6 +23,7 @@ #include #include +#include "defines.h" #include "vector.h" #include "game_object.h" #include "serializable.h" @@ -51,7 +52,7 @@ public: virtual void draw(DrawingContext& context) { - (void) context; + UNUSED_ARG(context); } void set_scrolling(int scroll_x, int scroll_y) diff --git a/src/defines.h b/src/defines.h index a2e8c1681..c96fda4fc 100644 --- a/src/defines.h +++ b/src/defines.h @@ -118,5 +118,7 @@ enum DyingType { #define DEBUG_MSG( msg ) {} #endif +#define UNUSED_ARG(a) do {/* null */} while (&a == 0) + #endif /*SUPERTUX_DEFINES_H*/ diff --git a/src/gameobjs.cpp b/src/gameobjs.cpp index 3d9c20e68..cd9d1c0b1 100644 --- a/src/gameobjs.cpp +++ b/src/gameobjs.cpp @@ -80,9 +80,10 @@ BrokenBrick::draw(DrawingContext& context) } BouncyBrick::BouncyBrick(const Vector& pos) - : position(pos), offset(0), offset_m(-BOUNCY_BRICK_SPEED) -{ - shape = Sector::current()->solids->get_tile_id_at(pos); + : position(pos), offset(0), offset_m(-BOUNCY_BRICK_SPEED), + shape(Sector::current()->solids->get_tile_id_at(pos)) +{ + shape.hidden = true; } void @@ -96,14 +97,17 @@ BouncyBrick::action(float elapsed_time) /* Stop bouncing? */ if (offset >= 0) - remove_me(); + { + shape.hidden = false; + remove_me(); + } } void BouncyBrick::draw(DrawingContext& context) { TileManager::instance()-> - draw_tile(context, shape, position + Vector(0, offset), LAYER_TILES+1); + draw_tile(context, shape.id, position + Vector(0, offset), LAYER_TILES+1); } FloatingScore::FloatingScore(const Vector& pos, int score) diff --git a/src/gameobjs.h b/src/gameobjs.h index d9459f491..16106b4ff 100644 --- a/src/gameobjs.h +++ b/src/gameobjs.h @@ -37,6 +37,8 @@ #define NO_BOUNCE 0 #define BOUNCE 1 +struct TileId; + class BouncyDistro : public GameObject { public: @@ -82,7 +84,7 @@ private: Vector position; float offset; float offset_m; - int shape; + TileId& shape; }; class FloatingScore : public GameObject diff --git a/src/leveleditor.cpp b/src/leveleditor.cpp index 44a2345be..71135d0ec 100644 --- a/src/leveleditor.cpp +++ b/src/leveleditor.cpp @@ -491,7 +491,7 @@ void LevelEditor::init_menus() for(std::vector::const_iterator sit = (*it).tiles.begin(); sit != (*it).tiles.end(); ++sit, ++i) { - Tile& tile = *(TileManager::instance()->get(*sit)); + Tile& tile = TileManager::instance()->get(*sit); Surface* image; if(tile.editor_images.size() > 0) image = tile.editor_images[0]; diff --git a/src/lispwriter.h b/src/lispwriter.h index 50023e034..e7f4c4c22 100644 --- a/src/lispwriter.h +++ b/src/lispwriter.h @@ -21,6 +21,7 @@ #define SUPERTUX_LISPWRITER_H #include +#include #include class LispWriter diff --git a/src/sector.cpp b/src/sector.cpp index bd450142f..dc24cbed1 100644 --- a/src/sector.cpp +++ b/src/sector.cpp @@ -18,6 +18,7 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include +#include #include #include #include @@ -761,7 +762,7 @@ Sector::trygrabdistro(const Vector& pos, int bounciness) throw SuperTuxException(errmsg, __FILE__, __LINE__); */ //Bad tiles (i.e. tiles that are not defined in supertux.stgt but appear in the map) are changed to ID 0 (blank tile) - std::cout << "Warning: Undefined tile at " <<(int)pos.x/32 << "/" << (int)pos.y/32 << " (ID: " << (int)solids->get_tile_id_at(pos) << ")" << std::endl; + std::cout << "Warning: Undefined tile at " <<(int)pos.x/32 << "/" << (int)pos.y/32 << " (ID: " << (int)solids->get_tile_id_at(pos).id << ")" << std::endl; solids->change_at(pos,0); tile = solids->get_tile_at(pos); } diff --git a/src/tile.cpp b/src/tile.cpp index 87c3f81f9..674cf7892 100644 --- a/src/tile.cpp +++ b/src/tile.cpp @@ -84,13 +84,27 @@ Tile::read(LispReader& reader) std::vector editor_filenames; reader.read_string_vector("editor-images", editor_filenames); + std::vector grid; + reader.read_int_vector("grid", grid); + // read images for(std::vector::iterator i = filenames.begin(); - i != filenames.end(); ++i) { - Surface* surface - = new Surface(datadir + "/images/tilesets/" + *i, USE_ALPHA); - images.push_back(surface); - } + i != filenames.end(); ++i) + { + if (grid.size() == 4) + { + Surface* surface = new Surface(datadir + "/images/tilesets/" + *i, + grid[0], grid[1], grid[2], grid[3], + USE_ALPHA); + images.push_back(surface); + } + else + { + Surface* surface = new Surface(datadir + "/images/tilesets/" + *i, USE_ALPHA); + images.push_back(surface); + } + } + for(std::vector::iterator i = editor_filenames.begin(); i != editor_filenames.end(); ++i) { Surface* surface @@ -210,22 +224,20 @@ TileManager::draw_tile(DrawingContext& context, unsigned int c, if(c == 0) return; - Tile* tile = get(c); - if(!tile) - return; + Tile& tile = get(c); - if(!tile->images.size()) + if(!tile.images.size()) return; - if(tile->images.size() > 1) + if(tile.images.size() > 1) { size_t frame - = ((global_frame_counter*25) / tile->anim_speed) % tile->images.size(); - context.draw_surface(tile->images[frame], pos, layer); + = ((global_frame_counter*25) / tile.anim_speed) % tile.images.size(); + context.draw_surface(tile.images[frame], pos, layer); } - else if (tile->images.size() == 1) + else if (tile.images.size() == 1) { - context.draw_surface(tile->images[0], pos, layer); + context.draw_surface(tile.images[0], pos, layer); } } diff --git a/src/tile.h b/src/tile.h index 978ed3a52..80de06274 100644 --- a/src/tile.h +++ b/src/tile.h @@ -141,17 +141,18 @@ class TileManager const Vector& pos, int layer); static std::set* tilegroups() { if(!instance_) { instance_ = new TileManager(); } return tilegroups_ ? tilegroups_ : tilegroups_ = new std::set; } - Tile* get(unsigned int id) { + Tile& get(unsigned int id) { + if(id < tiles.size()) { - return tiles[id]; + return *tiles[id]; } else { // Never return 0, but return the 0th tile instead so that // user code doesn't have to check for NULL pointers all over // the place - return tiles[0]; + return *tiles[0]; } } }; diff --git a/src/tilemap.cpp b/src/tilemap.cpp index 3ed4fa9ef..571a6f3af 100644 --- a/src/tilemap.cpp +++ b/src/tilemap.cpp @@ -65,9 +65,19 @@ TileMap::TileMap(LispReader& reader) if(!reader.read_int("width", width) || !reader.read_int("height", height)) throw std::runtime_error("No width or height specified in tilemap."); + + std::vector tmp_tiles; - if(!reader.read_int_vector("tiles", tiles)) + if(!reader.read_int_vector("tiles", tmp_tiles)) throw std::runtime_error("No tiles in tilemap."); + + tiles.resize(tmp_tiles.size()); + for(unsigned int i = 0; i < tmp_tiles.size(); ++i) + { + tiles[i].hidden = false; + tiles[i].id = tmp_tiles[i]; + } + if(int(tiles.size()) != width*height) throw std::runtime_error("wrong number of tiles in tilemap."); } @@ -95,7 +105,14 @@ TileMap::write(LispWriter& writer) writer.write_float("speed", speed); writer.write_int("width", width); writer.write_int("height", height); - writer.write_int_vector("tiles", tiles); + + std::vector tmp_tiles; + tmp_tiles.resize(tiles.size()); + for(unsigned int i = 0; i < tmp_tiles.size(); ++i) + { + tmp_tiles[i] = tiles[i].id; + } + writer.write_int_vector("tiles", tmp_tiles); writer.end_list("tilemap"); } @@ -123,7 +140,8 @@ TileMap::draw(DrawingContext& context) int tx, ty; for(pos.x = start_x, tx = tsx; pos.x < end_x; pos.x += 32, ++tx) { for(pos.y = start_y, ty = tsy; pos.y < end_y; pos.y += 32, ++ty) { - tilemanager->draw_tile(context, tiles[ty*width + tx], pos, layer); + if (!tiles[ty*width + tx].hidden) + tilemanager->draw_tile(context, tiles[ty*width + tx].id, pos, layer); } } } @@ -134,11 +152,18 @@ TileMap::set(int newwidth, int newheight, const std::vector&newt, { assert(int(newt.size()) == newwidth * newheight); - width = newwidth; + width = newwidth; height = newheight; - tiles = newt; - layer = newlayer; - solid = newsolid; + + tiles.resize(newt.size()); + for(unsigned int i = 0; i < newt.size(); ++i) + { + tiles[i].hidden = false; + tiles[i].id = newt[i]; + } + + layer = newlayer; + solid = newsolid; } void @@ -160,7 +185,7 @@ TileMap::resize(int new_width, int new_height) for(int y = std::min(height, new_height)-1; y >= 0; --y) { for(int x = new_width-1; x >= 0; --x) { if(x >= width) { - tiles[y * new_width + x] = 0; + tiles[y * new_width + x] = TileId(); } else { tiles[y * new_width + x] = tiles[y * width + x]; } @@ -176,9 +201,9 @@ Tile* TileMap::get_tile(int x, int y) const { if(x < 0 || x >= width || y < 0 || y >= height) - return tilemanager->get(0); + return &tilemanager->get(0); - return tilemanager->get(tiles[y*width + x]); + return &tilemanager->get(tiles[y*width + x].id); } Tile* @@ -187,11 +212,12 @@ TileMap::get_tile_at(const Vector& pos) const return get_tile(int(pos.x)/32, int(pos.y)/32); } -unsigned int -TileMap::get_tile_id_at(const Vector& pos) const +TileId& +TileMap::get_tile_id_at(const Vector& pos) { int x = int(pos.x)/32; int y = int(pos.y)/32; + return tiles[y*width + x]; } @@ -199,7 +225,7 @@ void TileMap::change(int x, int y, unsigned int newtile) { assert(x >= 0 && x < width && y >= 0 && y < height); - tiles[y*width + x] = newtile; + tiles[y*width + x].id = newtile; } void diff --git a/src/tilemap.h b/src/tilemap.h index 18340aae8..6f826421b 100644 --- a/src/tilemap.h +++ b/src/tilemap.h @@ -31,6 +31,15 @@ class TileManager; class LispReader; class Tile; +struct TileId +{ + TileId() : id(0), hidden(0) {} + explicit TileId(unsigned int i, bool hidden_ = false) : id(i), hidden(hidden_) {} + + unsigned id :31; + unsigned hidden :1; +}; + /** * This class is reponsible for drawing the level tiles */ @@ -63,7 +72,7 @@ public: bool is_solid() const { return solid; } - unsigned int get_tile_id_at(const Vector& pos) const; + TileId& get_tile_id_at(const Vector& pos); /// returns tile in row y and column y (of the tilemap) Tile* get_tile(int x, int y) const; @@ -74,8 +83,8 @@ public: void change_at(const Vector& pos, unsigned int newtile); -public: - std::vector tiles; +private: + std::vector tiles; private: TileManager* tilemanager; -- 2.11.0