- fixed the bouncybrick artifact bug
authorIngo Ruhnke <grumbel@gmx.de>
Mon, 14 Jun 2004 22:08:01 +0000 (22:08 +0000)
committerIngo Ruhnke <grumbel@gmx.de>
Mon, 14 Jun 2004 22:08:01 +0000 (22:08 +0000)
- 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
src/defines.h
src/gameobjs.cpp
src/gameobjs.h
src/leveleditor.cpp
src/lispwriter.h
src/sector.cpp
src/tile.cpp
src/tile.h
src/tilemap.cpp
src/tilemap.h

index 9c6e6c5..9c11708 100644 (file)
@@ -23,6 +23,7 @@
 #include <vector>
 #include <cassert>
 
 #include <vector>
 #include <cassert>
 
+#include "defines.h"
 #include "vector.h"
 #include "game_object.h"
 #include "serializable.h"
 #include "vector.h"
 #include "game_object.h"
 #include "serializable.h"
@@ -51,7 +52,7 @@ public:
 
   virtual void draw(DrawingContext& context)
   {
 
   virtual void draw(DrawingContext& context)
   {
-    (void) context;
+    UNUSED_ARG(context);
   }
 
   void set_scrolling(int scroll_x, int scroll_y)
   }
 
   void set_scrolling(int scroll_x, int scroll_y)
index a2e8c16..c96fda4 100644 (file)
@@ -118,5 +118,7 @@ enum DyingType {
        #define DEBUG_MSG( msg ) {}
 #endif
 
        #define DEBUG_MSG( msg ) {}
 #endif
 
+#define UNUSED_ARG(a) do {/* null */} while (&a == 0)
+
 #endif /*SUPERTUX_DEFINES_H*/
 
 #endif /*SUPERTUX_DEFINES_H*/
 
index 3d9c20e..cd9d1c0 100644 (file)
@@ -80,9 +80,10 @@ BrokenBrick::draw(DrawingContext& context)
 }
 
 BouncyBrick::BouncyBrick(const Vector& pos)
 }
 
 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
 }
 
 void
@@ -96,14 +97,17 @@ BouncyBrick::action(float elapsed_time)
 
   /* Stop bouncing? */
   if (offset >= 0)
 
   /* Stop bouncing? */
   if (offset >= 0)
-    remove_me();
+    {
+      shape.hidden = false;
+      remove_me();
+    }
 }
 
 void
 BouncyBrick::draw(DrawingContext& context)
 {
   TileManager::instance()->
 }
 
 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)
 }
 
 FloatingScore::FloatingScore(const Vector& pos, int score)
index d9459f4..16106b4 100644 (file)
@@ -37,6 +37,8 @@
 #define NO_BOUNCE 0
 #define BOUNCE 1
 
 #define NO_BOUNCE 0
 #define BOUNCE 1
 
+struct TileId;
+
 class BouncyDistro : public GameObject
 {
 public:
 class BouncyDistro : public GameObject
 {
 public:
@@ -82,7 +84,7 @@ private:
   Vector position;
   float offset;   
   float offset_m;
   Vector position;
   float offset;   
   float offset_m;
-  int shape;      
+  TileId& shape;      
 };
 
 class FloatingScore : public GameObject
 };
 
 class FloatingScore : public GameObject
index 44a2345..71135d0 100644 (file)
@@ -491,7 +491,7 @@ void LevelEditor::init_menus()
       for(std::vector<int>::const_iterator sit = (*it).tiles.begin();
           sit != (*it).tiles.end(); ++sit, ++i)
       {
       for(std::vector<int>::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];
         Surface* image;
         if(tile.editor_images.size() > 0)
           image = tile.editor_images[0];
index 50023e0..e7f4c4c 100644 (file)
@@ -21,6 +21,7 @@
 #define SUPERTUX_LISPWRITER_H
 
 #include <iostream>
 #define SUPERTUX_LISPWRITER_H
 
 #include <iostream>
+#include <string>
 #include <vector>
 
 class LispWriter
 #include <vector>
 
 class LispWriter
index bd45014..dc24cbe 100644 (file)
@@ -18,6 +18,7 @@
 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include <memory>
 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include <memory>
+#include <algorithm>
 #include <stdexcept>
 #include <iostream>
 #include <fstream>
 #include <stdexcept>
 #include <iostream>
 #include <fstream>
@@ -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)
     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);
   }
     solids->change_at(pos,0);
     tile = solids->get_tile_at(pos);
   }
index 87c3f81..674cf78 100644 (file)
@@ -84,13 +84,27 @@ Tile::read(LispReader& reader)
   std::vector<std::string> editor_filenames;
   reader.read_string_vector("editor-images", editor_filenames);
 
   std::vector<std::string> editor_filenames;
   reader.read_string_vector("editor-images", editor_filenames);
 
+  std::vector<int> grid;
+  reader.read_int_vector("grid", grid);
+
   // read images
   for(std::vector<std::string>::iterator i = filenames.begin();
   // read images
   for(std::vector<std::string>::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<std::string>::iterator i = editor_filenames.begin();
       i != editor_filenames.end(); ++i) {
     Surface* surface 
   for(std::vector<std::string>::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;
 
   if(c == 0)
     return;
 
-  Tile* tile = get(c);
-  if(!tile)
-    return;
+  Tile& tile = get(c);
 
 
-  if(!tile->images.size())
+  if(!tile.images.size())
     return;
 
     return;
 
-  if(tile->images.size() > 1)
+  if(tile.images.size() > 1)
   {
     size_t frame 
   {
     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);
   }
 }
 
   }
 }
 
index 978ed3a..80de062 100644 (file)
@@ -141,17 +141,18 @@ class TileManager
       const Vector& pos, int layer);
   
   static std::set<TileGroup>* tilegroups() { if(!instance_) { instance_ = new TileManager(); } return tilegroups_ ? tilegroups_ : tilegroups_ = new std::set<TileGroup>; }
       const Vector& pos, int layer);
   
   static std::set<TileGroup>* tilegroups() { if(!instance_) { instance_ = new TileManager(); } return tilegroups_ ? tilegroups_ : tilegroups_ = new std::set<TileGroup>; }
-  Tile* get(unsigned int id) {
+  Tile& get(unsigned int id) {
+
     if(id < tiles.size())
       {
     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
       }
     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]; 
       } 
   }
 };
       } 
   }
 };
index 3ed4fa9..571a6f3 100644 (file)
@@ -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.");
   if(!reader.read_int("width", width) ||
      !reader.read_int("height", height))
     throw std::runtime_error("No width or height specified in tilemap.");
+
+  std::vector<unsigned int> 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.");
     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.");
 }
   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_float("speed", speed);
   writer.write_int("width", width);
   writer.write_int("height", height);
-  writer.write_int_vector("tiles", tiles);
+
+  std::vector<unsigned int> 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");
 }
   
   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) {
   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<unsigned int>&newt,
 {
   assert(int(newt.size()) == newwidth * newheight);
 
 {
   assert(int(newt.size()) == newwidth * newheight);
 
-  width = newwidth;
+  width  = newwidth;
   height = newheight;
   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
 }
 
 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) {
     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];
         }
         } 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)
 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*
 }
 
 Tile*
@@ -187,11 +212,12 @@ TileMap::get_tile_at(const Vector& pos) const
   return get_tile(int(pos.x)/32, int(pos.y)/32);
 }
 
   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;
 {
   int x = int(pos.x)/32;
   int y = int(pos.y)/32;
+  
   return tiles[y*width + x];
 }
 
   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);
 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
 }
 
 void
index 18340aa..6f82642 100644 (file)
@@ -31,6 +31,15 @@ class TileManager;
 class LispReader;
 class Tile;
 
 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
  */
 /**
  * This class is reponsible for drawing the level tiles
  */
@@ -63,7 +72,7 @@ public:
   bool is_solid() const
   { return solid; }
 
   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;
 
   /// 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);
 
 
   void change_at(const Vector& pos, unsigned int newtile);
 
-public:
-  std::vector<unsigned int> tiles;
+private:
+  std::vector<TileId> tiles;
   
 private:
   TileManager* tilemanager;
   
 private:
   TileManager* tilemanager;