Experiments with a new abstract base class for Moving Objects that are Sprites
authorChristoph Sommer <mail@christoph-sommer.de>
Fri, 12 May 2006 01:41:09 +0000 (01:41 +0000)
committerChristoph Sommer <mail@christoph-sommer.de>
Fri, 12 May 2006 01:41:09 +0000 (01:41 +0000)
SVN-Revision: 3506

src/object/coin.cpp
src/object/coin.hpp
src/object/moving_sprite.cpp [new file with mode: 0644]
src/object/moving_sprite.hpp [new file with mode: 0644]
src/object/path_walker.hpp
src/object/platform.cpp
src/object/platform.hpp
src/object/powerup.cpp
src/object/powerup.hpp
src/object/weak_block.cpp
src/object/weak_block.hpp

index 7e263aa..566d294 100644 (file)
 #include "timer.hpp"
 
 Coin::Coin(const Vector& pos)
+       : MovingSprite(pos, "images/objects/coin/coin.sprite", LAYER_TILES, COLGROUP_TOUCHABLE)
 {
-  bbox.set_pos(pos);
-  bbox.set_size(32, 32);
-  sprite = sprite_manager->create("images/objects/coin/coin.sprite");
-  set_group(COLGROUP_TOUCHABLE);
 }
 
 Coin::Coin(const lisp::Lisp& reader)
+       : MovingSprite(reader, "images/objects/coin/coin.sprite", LAYER_TILES, COLGROUP_TOUCHABLE)
 {
-  reader.get("x", bbox.p1.x);
-  reader.get("y", bbox.p1.y);
-  bbox.set_size(32, 32);
-  sprite = sprite_manager->create("images/objects/coin/coin.sprite");
-  set_group(COLGROUP_TOUCHABLE);
-}
-
-Coin::~Coin()
-{
-  delete sprite;
-}
-
-void
-Coin::update(float )
-{
-}
-
-void
-Coin::draw(DrawingContext& context)
-{
-  sprite->draw(context, get_pos(), LAYER_TILES);
 }
 
 void
index 3bd2743..c595865 100644 (file)
 #ifndef __COIN_H__
 #define __COIN_H__
 
-#include "moving_object.hpp"
+#include "moving_sprite.hpp"
 #include "lisp/lisp.hpp"
 
-class Sprite;
-
-class Coin : public MovingObject
+class Coin : public MovingSprite
 {
 public:
   Coin(const Vector& pos);
   Coin(const lisp::Lisp& reader);
-  ~Coin();
+  virtual Coin* clone() const { return new Coin(*this); }
 
   HitResponse collision(GameObject& other, const CollisionHit& hit);
-  void update(float elapsed_time);
-  void draw(DrawingContext& context);
 
   void collect();
-
-private:
-  Sprite* sprite;
 };
 
 #endif
diff --git a/src/object/moving_sprite.cpp b/src/object/moving_sprite.cpp
new file mode 100644 (file)
index 0000000..3b3e7d7
--- /dev/null
@@ -0,0 +1,112 @@
+//  $Id$
+//
+//  SuperTux - MovingSprite Base Class
+//  Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
+//
+//  This program is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU General Public License
+//  as published by the Free Software Foundation; either version 2
+//  of the License, or (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#include <config.h>
+
+#include "moving_sprite.hpp"
+#include "video/drawing_context.hpp"
+#include "sprite/sprite_manager.hpp"
+#include "player.hpp"
+#include "sector.hpp"
+#include "player_status.hpp"
+#include "gameobjs.hpp"
+#include "statistics.hpp"
+#include "object_factory.hpp"
+#include "level.hpp"
+#include "random_generator.hpp"
+#include "audio/sound_source.hpp"
+#include "audio/sound_manager.hpp"
+#include "timer.hpp"
+
+MovingSprite::MovingSprite(const Vector& pos, const std::string& sprite_name, int layer, CollisionGroup collision_group)
+       : sprite_name(sprite_name), layer(layer)
+{
+  bbox.set_pos(pos);
+  sprite = sprite_manager->create(sprite_name);
+  bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
+  set_group(collision_group);
+}
+
+MovingSprite::MovingSprite(const lisp::Lisp& reader, const Vector& pos, int layer, CollisionGroup collision_group)
+       : layer(layer)
+{
+  bbox.set_pos(pos);
+  if (!reader.get("sprite", sprite_name)) throw std::runtime_error("no sprite name set");
+  sprite = sprite_manager->create(sprite_name);
+  bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
+  set_group(collision_group);
+}
+
+MovingSprite::MovingSprite(const lisp::Lisp& reader, const std::string& sprite_name, int layer, CollisionGroup collision_group)
+       : sprite_name(sprite_name), layer(layer)
+{
+  if (!reader.get("x", bbox.p1.x)) throw std::runtime_error("no x position set");
+  if (!reader.get("y", bbox.p1.y)) throw std::runtime_error("no y position set");
+  sprite = sprite_manager->create(sprite_name);
+  bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
+  set_group(collision_group);
+}
+
+MovingSprite::MovingSprite(const lisp::Lisp& reader, int layer, CollisionGroup collision_group)
+       : layer(layer)
+{
+  if (!reader.get("x", bbox.p1.x)) throw std::runtime_error("no x position set");
+  if (!reader.get("y", bbox.p1.y)) throw std::runtime_error("no y position set");
+  if (!reader.get("sprite", sprite_name)) throw std::runtime_error("no sprite name set");
+  sprite = sprite_manager->create(sprite_name);
+  bbox.set_size(sprite->get_current_hitbox_width(), sprite->get_current_hitbox_height());
+  set_group(collision_group);
+}
+
+MovingSprite::MovingSprite(const MovingSprite& other)
+       : MovingObject(other), layer(other.layer)
+{
+  sprite = new Sprite(*other.sprite);
+}
+
+MovingSprite& 
+MovingSprite::operator=(const MovingSprite& other)
+{
+  if (this == &other) return *this;
+
+  delete sprite;
+  sprite = new Sprite(*other.sprite);
+
+  layer = other.layer;
+
+  return *this;
+}
+
+MovingSprite::~MovingSprite()
+{
+  delete sprite;
+}
+
+void
+MovingSprite::draw(DrawingContext& context)
+{
+  sprite->draw(context, get_pos(), layer);
+}
+
+void 
+MovingSprite::update(float )
+{
+}
+
+
diff --git a/src/object/moving_sprite.hpp b/src/object/moving_sprite.hpp
new file mode 100644 (file)
index 0000000..ae80634
--- /dev/null
@@ -0,0 +1,55 @@
+//  $Id$
+//
+//  SuperTux - MovingSprite Base Class
+//  Copyright (C) 2006 Christoph Sommer <christoph.sommer@2006.expires.deltadevelopment.de>
+//
+//  This program is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU General Public License
+//  as published by the Free Software Foundation; either version 2
+//  of the License, or (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+#ifndef __MOVING_SPRITE_H__
+#define __MOVING_SPRITE_H__
+
+#include <string>
+#include "moving_object.hpp"
+#include "sprite/sprite.hpp"
+#include "video/drawing_context.hpp"
+
+/**
+ * Abstract base class for MovingObjects that are represented by a Sprite
+ */
+class MovingSprite : public MovingObject
+{
+public:
+  MovingSprite(const Vector& pos, const std::string& sprite_name, int layer = LAYER_OBJECTS, CollisionGroup collision_group = COLGROUP_MOVING);
+  MovingSprite(const lisp::Lisp& reader, const Vector& pos, int layer = LAYER_OBJECTS, CollisionGroup collision_group = COLGROUP_MOVING);
+  MovingSprite(const lisp::Lisp& reader, const std::string& sprite_name, int layer = LAYER_OBJECTS, CollisionGroup collision_group = COLGROUP_MOVING);
+  MovingSprite(const lisp::Lisp& reader, int layer = LAYER_OBJECTS, CollisionGroup collision_group = COLGROUP_MOVING);
+  MovingSprite(const MovingSprite& moving_sprite);
+  MovingSprite& operator=(const MovingSprite& moving_sprite);
+  ~MovingSprite();
+
+  virtual void draw(DrawingContext& context);
+  virtual void update(float elapsed_time);
+
+  virtual MovingSprite* clone() const = 0;
+
+protected:
+  std::string sprite_name;
+  Sprite* sprite;
+  int layer; /**< Sprite's z-position. Refer to video/drawing_context.hpp for sensible values. */
+
+};
+
+#endif
+
index 44d947a..9f237ef 100644 (file)
@@ -41,12 +41,12 @@ public:
    */
   virtual Vector advance(float elapsed_time);
 
+  const Path* path;
+
 private:
   void advance_node();
   void goback_node();
   
-  const Path* path;
-
   size_t current_node_nr;
   size_t next_node_nr;
 
index b0b2a3b..6f405c8 100644 (file)
 #include "player.hpp"
 #include "path.hpp"
 #include "path_walker.hpp"
-#include "sprite/sprite_manager.hpp"
+#include "sprite/sprite.hpp"
 #include "lisp/lisp.hpp"
 #include "object_factory.hpp"
 
 Platform::Platform(const lisp::Lisp& reader)
+       : MovingSprite(reader, Vector(0,0), LAYER_OBJECTS, COLGROUP_STATIC), speed(Vector(0,0))
 {
-  std::string sprite_name;
-  reader.get("sprite", sprite_name);
-  if(sprite_name == "")
-    throw std::runtime_error("No sprite specified in platform object"); 
-  sprite.reset(sprite_manager->create(sprite_name));
-
   const lisp::Lisp* pathLisp = reader.get_lisp("path");
   if(pathLisp == NULL)
     throw std::runtime_error("No path specified for platform");
   path.reset(new Path());
   path->read(*pathLisp);
   walker.reset(new PathWalker(path.get()));
-
-  bbox.p1 = path->get_base();
-  bbox.set_size(sprite->get_width(), sprite->get_height());
-  
-  set_group(COLGROUP_STATIC);
+  bbox.set_pos(path->get_base());
   flags |= FLAG_SOLID;
 }
 
-Platform::~Platform()
+Platform::Platform(const Platform& other)
+       : MovingSprite(other), speed(other.speed)
 {
+  path.reset(new Path(*other.path));
+  walker.reset(new PathWalker(*other.walker));
+  walker->path = &*path;
 }
 
 //TODO: Squish Tux when standing between platform and solid tile/object
@@ -86,10 +82,4 @@ Platform::update(float elapsed_time)
   speed = movement / elapsed_time;
 }
 
-void
-Platform::draw(DrawingContext& context)
-{
-  sprite->draw(context, get_pos(), LAYER_OBJECTS);
-}
-
 IMPLEMENT_FACTORY(Platform, "platform");
index a41f4e1..8e981e5 100644 (file)
 #define __PLATFORM_H__
 
 #include <memory>
-#include "moving_object.hpp"
-#include "sprite/sprite.hpp"
+#include "object/moving_sprite.hpp"
 #include "object/path.hpp"
 #include "object/path_walker.hpp"
 
 /**
  * This class is the base class for platforms that tux can stand on
  */
-class Platform : public MovingObject
+class Platform : public MovingSprite
 {
 public:
   Platform(const lisp::Lisp& reader);
-  ~Platform();
+  Platform(const Platform& platform);
+  virtual Platform* clone() const { return new Platform(*this); }
 
   virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
   virtual void update(float elapsed_time);
-  virtual void draw(DrawingContext& context);
   const Vector& get_speed() const
   {
     return speed;
   }
 
 private:
-  std::auto_ptr<Sprite> sprite;
   std::auto_ptr<Path> path;
   std::auto_ptr<PathWalker> walker;
   Vector speed;
+
 };
 
 #endif
index 4e14f93..f274d48 100644 (file)
 #include "powerup.hpp"
 #include "resources.hpp"
 #include "player.hpp"
-#include "sprite/sprite_manager.hpp"
 #include "audio/sound_manager.hpp"
 #include "object_factory.hpp"
 #include "sector.hpp"
 #include "log.hpp"
 
 PowerUp::PowerUp(const lisp::Lisp& lisp)
+       : MovingSprite(lisp, LAYER_OBJECTS, COLGROUP_MOVING)
 {
-  lisp.get("x", bbox.p1.x);
-  lisp.get("y", bbox.p1.y);
-  if (!lisp.get("sprite", sprite_name))
-    throw std::runtime_error("no sprite file set for powerup");
   lisp.get("script", script);
   no_physics = false;
   lisp.get("disable-physics", no_physics);
-  bbox.set_size(32, 32);   
-  sprite = sprite_manager->create(sprite_name);
   physic.enable_gravity(true);
-
-  set_group(COLGROUP_MOVING);
-}
-
-PowerUp::~PowerUp()
-{
-  delete sprite;
 }
 
 HitResponse
@@ -99,11 +86,5 @@ PowerUp::update(float elapsed_time)
     movement = physic.get_movement(elapsed_time);
 }
 
-void
-PowerUp::draw(DrawingContext& context)
-{
-  sprite->draw(context, get_pos(), LAYER_OBJECTS);
-}
-
 IMPLEMENT_FACTORY(PowerUp, "powerup");
 
index 91d6738..59922a7 100644 (file)
 #ifndef __POWERUP_H__
 #define __POWERUP_H__
 
-#include "moving_object.hpp"
+#include "object/moving_sprite.hpp"
 #include "lisp/lisp.hpp"
-#include "sprite/sprite.hpp"
 #include "collision_hit.hpp"
 #include "physic.hpp"
 
-class PowerUp : public MovingObject
+class PowerUp : public MovingSprite
 {
 public:
   PowerUp(const lisp::Lisp& lisp);
-  ~PowerUp();
+  virtual PowerUp* clone() const { return new PowerUp(*this); }
 
   virtual void update(float elapsed_time);
-  virtual void draw(DrawingContext& context);
   virtual HitResponse collision(GameObject& other, const CollisionHit& hit);
   
 private:
-  std::string sprite_name;
-  Sprite* sprite;
   Physic physic;
   std::string script;
   bool no_physics;
index 8f33f3c..a528f07 100644 (file)
 #include "player.hpp"
 #include "sector.hpp"
 #include "resources.hpp"
-#include "sprite/sprite_manager.hpp"
 #include "sprite/sprite.hpp"
 #include "random_generator.hpp"
 #include "object/bullet.hpp"
 
 WeakBlock::WeakBlock(const lisp::Lisp& lisp)
-  : state(STATE_NORMAL)
+  : MovingSprite(lisp, "images/objects/strawbox/strawbox.sprite", LAYER_TILES, COLGROUP_STATIC), state(STATE_NORMAL)
 {
-  lisp.get("x", bbox.p1.x);
-  lisp.get("y", bbox.p1.y);
-  bbox.set_size(32, 32);
-  sprite = sprite_manager->create("images/objects/strawbox/strawbox.sprite");
   sprite->set_action("normal");
   flags |= FLAG_SOLID;
-  set_group(COLGROUP_STATIC);
-}
-
-WeakBlock::~WeakBlock()
-{
-  delete sprite;
 }
 
 HitResponse
@@ -77,13 +66,6 @@ WeakBlock::collision(GameObject& other, const CollisionHit& )
 }
 
 void
-WeakBlock::draw(DrawingContext& context)
-{
-  Vector pos = get_pos();
-  sprite->draw(context, pos, LAYER_TILES);
-}
-
-void
 WeakBlock::update(float )
 {
   switch (state) {
index 41a83ae..2a08179 100644 (file)
 #ifndef __WEAK_BLOCK_H__
 #define __WEAK_BLOCK_H__
 
-#include "moving_object.hpp"
+#include "object/moving_sprite.hpp"
 #include "lisp/lisp.hpp"
 #include "physic.hpp"
 #include "timer.hpp"
-#include "sprite/sprite.hpp"
 
 /** 
  * A block that can be destroyed by Bullet hits
  */
-class WeakBlock : public MovingObject
+class WeakBlock : public MovingSprite
 {
 public:
   WeakBlock(const lisp::Lisp& lisp);
-  ~WeakBlock();
+  virtual WeakBlock* clone() const { return new WeakBlock(*this); }
 
   HitResponse collision(GameObject& other, const CollisionHit& hit);
   void update(float elapsed_time);
-  void draw(DrawingContext& context);
 
 private:
   enum State {
@@ -49,7 +47,6 @@ private:
   State state;
 
   Physic physic;
-  Sprite* sprite;
 };
 
 #endif