Coins follow tilemaps or can be given paths
authormathnerd314 <mathnerd314@837edb03-e0f3-0310-88ca-d4d4e8b29345>
Sat, 28 Aug 2010 19:49:13 +0000 (19:49 +0000)
committermathnerd314 <mathnerd314@837edb03-e0f3-0310-88ca-d4d4e8b29345>
Sat, 28 Aug 2010 19:49:13 +0000 (19:49 +0000)
git-svn-id: http://supertux.lethargik.org/svn/supertux/trunk/supertux@6653 837edb03-e0f3-0310-88ca-d4d4e8b29345

data/levels/test/tileplatforms.stl
src/object/coin.cpp
src/object/coin.hpp
src/object/path_walker.cpp
src/object/path_walker.hpp
src/object/tilemap.hpp
src/supertux/flip_level_transformer.cpp
src/supertux/sector.cpp

index a2f0b16..bd2afd5 100644 (file)
@@ -64,8 +64,9 @@
         )
       )
       (width 5)
-      (height 3)
+      (height 4)
       (tiles
+        0  0  44 0  0
         7  8  8  8  9 
         13 14 14 14 15
         16 17 17 17 18
index 9977ff8..6fd8924 100644 (file)
 #include "audio/sound_manager.hpp"
 #include "object/bouncy_coin.hpp"
 #include "object/player.hpp"
+#include "object/tilemap.hpp"
 #include "supertux/level.hpp"
 #include "supertux/object_factory.hpp"
 #include "supertux/sector.hpp"
 
 Coin::Coin(const Vector& pos)
-  : MovingSprite(pos, "images/objects/coin/coin.sprite", LAYER_TILES, COLGROUP_TOUCHABLE)
+  : MovingSprite(pos, "images/objects/coin/coin.sprite", LAYER_TILES, COLGROUP_TOUCHABLE),
+    path(),
+    walker(),
+    offset(),
+    from_tilemap(false)
 {
   sound_manager->preload("sounds/coin.wav");
 }
 
+Coin::Coin(const Vector& pos, TileMap* tilemap)
+  : MovingSprite(pos, "images/objects/coin/coin.sprite", LAYER_TILES, COLGROUP_TOUCHABLE),
+    path(boost::shared_ptr<Path>(tilemap->get_path())),
+    walker(boost::shared_ptr<PathWalker>(tilemap->get_walker())),
+    offset(),
+    from_tilemap(true)
+{
+  if(walker.get()) {
+    Vector v = path->get_base();
+    offset = pos - v;
+  }
+
+  sound_manager->preload("sounds/coin.wav");
+}
+
 Coin::Coin(const Reader& reader)
-  : MovingSprite(reader, "images/objects/coin/coin.sprite", LAYER_TILES, COLGROUP_TOUCHABLE)
+  : MovingSprite(reader, "images/objects/coin/coin.sprite", LAYER_TILES, COLGROUP_TOUCHABLE),
+    path(),
+    walker(),
+    offset(),
+    from_tilemap(false)
 {
+  const lisp::Lisp* pathLisp = reader.get_lisp("path");
+  if (pathLisp) {
+    path.reset(new Path());
+    path->read(*pathLisp);
+    walker.reset(new PathWalker(path.get()));
+    Vector v = path->get_base();
+    set_pos(v);
+  }
+
   sound_manager->preload("sounds/coin.wav");
 }
 
 void
+Coin::update(float elapsed_time)
+{
+  // if we have a path to follow, follow it
+  if (walker.get()) {
+    Vector v = from_tilemap ? offset + walker->get_pos() : walker->advance(elapsed_time);
+    movement = v - get_pos();
+  }
+}
+
+void
 Coin::collect()
 {
   // TODO: commented out musical code. Maybe fork this for a special "MusicalCoin" object?
index c28dfff..467830a 100644 (file)
 
 #include "object/moving_sprite.hpp"
 
+class TileMap;
+
 class Coin : public MovingSprite
 {
 public:
   Coin(const Vector& pos);
+  Coin(const Vector& pos, TileMap* tilemap);
   Coin(const Reader& reader);
 
   HitResponse collision(GameObject& other, const CollisionHit& hit);
 
   void collect();
+  virtual void update(float elapsed_time);
+
+private:
+  boost::shared_ptr<Path> path;
+  boost::shared_ptr<PathWalker> walker;
+  Vector offset;
+  bool from_tilemap;
 };
 
 #endif
index cf668c9..840e924 100644 (file)
@@ -65,9 +65,16 @@ PathWalker::advance(float elapsed_time)
     }
   }
 
-  const Path::Node* next_node = & (path->nodes[next_node_nr]);
   node_time += elapsed_time * node_mult;
 
+  return get_pos();
+}
+
+Vector
+PathWalker::get_pos()
+{
+  const Path::Node* current_node = & (path->nodes[current_node_nr]);
+  const Path::Node* next_node = & (path->nodes[next_node_nr]);
   Vector new_pos = current_node->position +
     (next_node->position - current_node->position) * node_time;
 
index c76383e..d85b97c 100644 (file)
@@ -31,11 +31,13 @@ public:
   virtual ~PathWalker();
 
   /**
-   * advances the path walker on the path and returns the position delta
-   * to the last position
+   * advances the path walker on the path and returns its new position
    */
   virtual Vector advance(float elapsed_time);
 
+  /** current position of path walker */
+  Vector get_pos();
+
   /** advance until at given node, then stop */
   void goto_node(int node_no);
 
index 8b3939b..428c5f4 100644 (file)
@@ -17,6 +17,8 @@
 #ifndef HEADER_SUPERTUX_OBJECT_TILEMAP_HPP
 #define HEADER_SUPERTUX_OBJECT_TILEMAP_HPP
 
+#include <boost/shared_ptr.hpp>
+
 #include "object/path_walker.hpp"
 #include "supertux/game_object.hpp"
 #include "supertux/script_interface.hpp"
@@ -88,8 +90,11 @@ public:
     }
   }
 
-  Path *get_path()
-  { return path.get(); }
+  boost::shared_ptr<Path> get_path()
+  { return path; }
+
+  boost::shared_ptr<PathWalker> get_walker()
+  { return walker; }
 
   void set_offset(const Vector &offset)
   { this->offset = offset; }
@@ -188,8 +193,8 @@ private:
   float current_alpha; /**< current tilemap opacity */
   float remaining_fade_time; /**< seconds until requested tilemap opacity is reached */
 
-  std::auto_ptr<Path> path;
-  std::auto_ptr<PathWalker> walker;
+  boost::shared_ptr<Path> path;
+  boost::shared_ptr<PathWalker> walker;
 
   DrawingContext::Target draw_target; /**< set to LIGHTMAP to draw to lightmap */
 
index 4d2445f..4bed1f9 100644 (file)
@@ -111,7 +111,7 @@ FlipLevelTransformer::transform_tilemap(float height, TileMap* tilemap)
   Vector offset = tilemap->get_offset();
   offset.y = height - offset.y - tilemap->get_bbox().get_height();
   tilemap->set_offset(offset);
-  Path *path = tilemap->get_path();
+  Path* path = tilemap->get_path().get();
   if (path)
     transform_path(height, tilemap->get_bbox().get_height(), *path);
 }
index dd75355..c52a03c 100644 (file)
@@ -415,7 +415,7 @@ Sector::fix_old_tiles()
           add_object(new InvisibleBlock(pos));
           solids->change(x, y, 0);
         } else if(tile->getAttributes() & Tile::COIN) {
-          add_object(new Coin(pos));
+          add_object(new Coin(pos, solids));
           solids->change(x, y, 0);
         } else if(tile->getAttributes() & Tile::FULLBOX) {
           add_object(new BonusBlock(pos, tile->getData()));