From: Christoph Sommer Date: Fri, 12 May 2006 01:41:09 +0000 (+0000) Subject: Experiments with a new abstract base class for Moving Objects that are Sprites X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=7eedaa580901ec970795fe66d6e7fa56349fb0a0;p=supertux.git Experiments with a new abstract base class for Moving Objects that are Sprites SVN-Revision: 3506 --- diff --git a/src/object/coin.cpp b/src/object/coin.cpp index 7e263aa04..566d29489 100644 --- a/src/object/coin.cpp +++ b/src/object/coin.cpp @@ -36,36 +36,13 @@ #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 diff --git a/src/object/coin.hpp b/src/object/coin.hpp index 3bd2743f5..c59586541 100644 --- a/src/object/coin.hpp +++ b/src/object/coin.hpp @@ -20,26 +20,19 @@ #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 index 000000000..3b3e7d73b --- /dev/null +++ b/src/object/moving_sprite.cpp @@ -0,0 +1,112 @@ +// $Id$ +// +// SuperTux - MovingSprite Base Class +// Copyright (C) 2006 Christoph Sommer +// +// 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 + +#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 index 000000000..ae80634a3 --- /dev/null +++ b/src/object/moving_sprite.hpp @@ -0,0 +1,55 @@ +// $Id$ +// +// SuperTux - MovingSprite Base Class +// Copyright (C) 2006 Christoph Sommer +// +// 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 +#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 + diff --git a/src/object/path_walker.hpp b/src/object/path_walker.hpp index 44d947adb..9f237eff6 100644 --- a/src/object/path_walker.hpp +++ b/src/object/path_walker.hpp @@ -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; diff --git a/src/object/platform.cpp b/src/object/platform.cpp index b0b2a3b1c..6f405c8f6 100644 --- a/src/object/platform.cpp +++ b/src/object/platform.cpp @@ -28,34 +28,30 @@ #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"); diff --git a/src/object/platform.hpp b/src/object/platform.hpp index a41f4e118..8e981e5ae 100644 --- a/src/object/platform.hpp +++ b/src/object/platform.hpp @@ -21,33 +21,32 @@ #define __PLATFORM_H__ #include -#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; std::auto_ptr path; std::auto_ptr walker; Vector speed; + }; #endif diff --git a/src/object/powerup.cpp b/src/object/powerup.cpp index 4e14f93db..f274d485e 100644 --- a/src/object/powerup.cpp +++ b/src/object/powerup.cpp @@ -25,31 +25,18 @@ #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"); diff --git a/src/object/powerup.hpp b/src/object/powerup.hpp index 91d673827..59922a722 100644 --- a/src/object/powerup.hpp +++ b/src/object/powerup.hpp @@ -20,25 +20,21 @@ #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; diff --git a/src/object/weak_block.cpp b/src/object/weak_block.cpp index 8f33f3c15..a528f0790 100644 --- a/src/object/weak_block.cpp +++ b/src/object/weak_block.cpp @@ -26,26 +26,15 @@ #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) { diff --git a/src/object/weak_block.hpp b/src/object/weak_block.hpp index 41a83ae01..2a081795f 100644 --- a/src/object/weak_block.hpp +++ b/src/object/weak_block.hpp @@ -21,24 +21,22 @@ #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