+++ /dev/null
-// $Id: particlesystem.cpp 2470 2005-05-11 14:49:28Z wansti $
-//
-// SuperTux
-// Copyright (C) 2004 Matthias Braun <matze@braunis.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 <iostream>
-#include <cmath>
-
-#include "particlesystem_absolute.h"
-#include "video/drawing_context.h"
-#include "lisp/parser.h"
-#include "lisp/lisp.h"
-#include "lisp/writer.h"
-#include "resources.h"
-#include "main.h"
-
-#include "tile.h"
-#include "tilemap.h"
-#include "math/aatriangle.h"
-#include "collision.h"
-#include "collision_hit.h"
-#include "object/camera.h"
-#include "badguy/bomb.h"
-
-//TODO: Dynamically create splashes at collision spots
-// Find a way to make rain collide with objects like bonus blocks
-// Add an option to set rain strength
-ParticleSystem_Absolute::ParticleSystem_Absolute()
-{
- virtual_width = SCREEN_WIDTH;
- virtual_height = SCREEN_HEIGHT;
- layer = LAYER_TILES;
-}
-
-ParticleSystem_Absolute::~ParticleSystem_Absolute()
-{
- std::vector<Particle*>::iterator i;
- for(i = particles.begin(); i != particles.end(); ++i) {
- delete *i;
- }
-}
-
-void ParticleSystem_Absolute::draw(DrawingContext& context)
-{
- context.push_transform();
-
- std::vector<Particle*>::iterator i;
- for(i = particles.begin(); i != particles.end(); ++i) {
- Particle* particle = *i;
- context.draw_surface(particle->texture, particle->pos, layer);
- }
-
- context.pop_transform();
-}
-
-bool
-ParticleSystem_Absolute::collision(Particle* object, Vector movement)
-{
- TileMap* solids = Sector::current()->solids;
- // calculate rectangle where the object will move
- float x1, x2;
- float y1, y2;
- x1 = object->pos.x;
- x2 = x1 + 32 + movement.x;
- y1 = object->pos.y;
- y2 = y1 + 32 + movement.y;
-
- // test with all tiles in this rectangle
- int starttilex = int(x1-1) / 32;
- int starttiley = int(y1-1) / 32;
- int max_x = int(x2+1);
- int max_y = int(y2+1);
-
- CollisionHit temphit, hit;
- Rect dest = Rect(x1, y1, x2, y2);
- dest.move(movement);
- hit.time = -1; // represents an invalid value
- for(int x = starttilex; x*32 < max_x; ++x) {
- for(int y = starttiley; y*32 < max_y; ++y) {
- const Tile* tile = solids->get_tile(x, y);
- if(!tile)
- continue;
- // skip non-solid tiles
- if(!(tile->getAttributes() & Tile::SOLID))
- continue;
-
- if(tile->getAttributes() & Tile::SLOPE) { // slope tile
- AATriangle triangle;
- Vector p1(x*32, y*32);
- Vector p2((x+1)*32, (y+1)*32);
- triangle = AATriangle(p1, p2, tile->getData());
-
- if(Collision::rectangle_aatriangle(temphit, dest, movement,
- triangle)) {
- if(temphit.time > hit.time)
- hit = temphit;
- }
- } else { // normal rectangular tile
- Rect rect(x*32, y*32, (x+1)*32, (y+1)*32);
- if(Collision::rectangle_rectangle(temphit, dest,
- movement, rect)) {
- if(temphit.time > hit.time)
- hit = temphit;
- }
- }
- }
- }
-
- // did we collide at all?
- if(hit.time < 0)
- return false; else return true;
-}
-
-RainParticleSystem::RainParticleSystem()
-{
- rainimages[0] = new Surface(datadir+"/images/objects/particles/rain0.png", true);
- rainimages[1] = new Surface(datadir+"/images/objects/particles/rain1.png", true);
-
- virtual_width = SCREEN_WIDTH * 2;
-
- // create some random raindrops
- size_t raindropcount = size_t(virtual_width/6.0);
- for(size_t i=0; i<raindropcount; ++i) {
- RainParticle* particle = new RainParticle;
- particle->pos.x = rand() % int(virtual_width);
- particle->pos.y = rand() % int(virtual_height);
- int rainsize = rand() % 2;
- particle->texture = rainimages[rainsize];
- do {
- particle->speed = (rainsize+1)*45 + (float(rand()%10)*.4);
- } while(particle->speed < 1);
- particle->speed *= 10; // gravity
-
- particles.push_back(particle);
- }
-}
-
-void
-RainParticleSystem::parse(const lisp::Lisp& reader)
-{
- reader.get("layer", layer);
-}
-
-void
-RainParticleSystem::write(lisp::Writer& writer)
-{
- writer.start_list("particles-rain");
- writer.write_int("layer", layer);
- writer.end_list("particles-rain");
-}
-
-RainParticleSystem::~RainParticleSystem()
-{
- for(int i=0;i<2;++i)
- delete rainimages[i];
-}
-
-void RainParticleSystem::update(float elapsed_time)
-{
- std::vector<Particle*>::iterator i;
- for(
- i = particles.begin(); i != particles.end(); ++i) {
- RainParticle* particle = (RainParticle*) *i;
- float movement = particle->speed * elapsed_time;
- float abs_x = Sector::current()->camera->get_translation().x;
- float abs_y = Sector::current()->camera->get_translation().y;
- particle->pos.y += movement;
- particle->pos.x -= movement;
- if ((particle->pos.y > SCREEN_HEIGHT + abs_y) || (collision(particle, Vector(-movement, movement)))) {
- int new_x = (rand() % int(virtual_width)) + int(abs_x);
- int new_y = 0;
- //FIXME: Don't move particles over solid tiles
- particle->pos.x = new_x;
- particle->pos.y = new_y;
- }
- }
-}
-
-CometParticleSystem::CometParticleSystem()
-{
- cometimages[0] = new Surface(datadir+"/images/creatures/mr_bomb/exploding-left-0.png", true);
- cometimages[1] = new Surface(datadir+"/images/creatures/mr_bomb/exploding-left-0.png", true);
-
- virtual_width = SCREEN_WIDTH * 2;
-
- // create some random comets
- size_t cometcount = 2;
- for(size_t i=0; i<cometcount; ++i) {
- CometParticle* particle = new CometParticle;
- particle->pos.x = rand() % int(virtual_width);
- particle->pos.y = rand() % int(virtual_height);
- int cometsize = rand() % 2;
- particle->texture = cometimages[cometsize];
- do {
- particle->speed = (cometsize+1)*30 + (float(rand()%10)*.4);
- } while(particle->speed < 1);
- particle->speed *= 10; // gravity
-
- particles.push_back(particle);
- }
-}
-
-void
-CometParticleSystem::parse(const lisp::Lisp& reader)
-{
- reader.get("layer", layer);
-}
-
-void
-CometParticleSystem::write(lisp::Writer& writer)
-{
- writer.start_list("particles-comets");
- writer.write_int("layer", layer);
- writer.end_list("particles-comets");
-}
-
-CometParticleSystem::~CometParticleSystem()
-{
- for(int i=0;i<2;++i)
- delete cometimages[i];
-}
-
-void CometParticleSystem::update(float elapsed_time)
-{
- std::vector<Particle*>::iterator i;
- for(
- i = particles.begin(); i != particles.end(); ++i) {
- CometParticle* particle = (CometParticle*) *i;
- float movement = particle->speed * elapsed_time;
- float abs_x = Sector::current()->camera->get_translation().x;
- float abs_y = Sector::current()->camera->get_translation().y;
- particle->pos.y += movement;
- particle->pos.x -= movement;
- if ((particle->pos.y > SCREEN_HEIGHT + abs_y) || (collision(particle, Vector(-movement, movement)))) {
- if (particle->pos.y <= SCREEN_HEIGHT + abs_y) {
- Sector::current()->add_object(new Bomb(particle->pos, LEFT));
- }
- int new_x = (rand() % int(virtual_width)) + int(abs_x);
- int new_y = 0;
- //FIXME: Don't move particles over solid tiles
- particle->pos.x = new_x;
- particle->pos.y = new_y;
- }
- }
-}
+++ /dev/null
-// $Id: ParticleSystem_Absolute.h 2462 2005-05-10 15:38:16Z wansti $
-//
-// SuperTux
-// Copyright (C) 2004 Matthias Braun <matze@braunis.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 SUPERTUX_PARTICLESYSTEM_ABSOLUTE_H
-#define SUPERTUX_PARTICLESYSTEM_ABSOLUTE_H
-
-#include <vector>
-
-#include "video/surface.h"
-#include "game_object.h"
-#include "serializable.h"
-#include "sector.h"
-#include "math/vector.h"
-
-namespace lisp {
-class Lisp;
-}
-
-class DisplayManager;
-
-/**
- * This is an alternative class for particle systems. It is responsible for storing a
- * set of particles with each having an x- and y-coordinate the number of the
- * layer where it should be drawn and a texture.
- * This version of the particle system class doesn't use virtual screen coordinates,
- * but absolute ones. Particle systems which need absolute levels coordinates, such
- * as rain, should be implemented here.
- * Classes that implement a particle system should subclass from this class,
- * initialize particles in the constructor and move them in the simulate
- * function.
- */
-class ParticleSystem_Absolute : public GameObject
-{
-public:
- ParticleSystem_Absolute();
- virtual ~ParticleSystem_Absolute();
-
- virtual void draw(DrawingContext& context);
-
-protected:
- int layer;
-
- class Particle
- {
- public:
- virtual ~Particle()
- { }
-
- Vector pos;
- Surface* texture;
- };
-
- std::vector<Particle*> particles;
- float virtual_width, virtual_height;
- bool collision(Particle* particle, Vector movement);
-};
-
-class RainParticleSystem : public ParticleSystem_Absolute, public Serializable
-{
-public:
- RainParticleSystem();
- virtual ~RainParticleSystem();
-
- void parse(const lisp::Lisp& lisp);
- void write(lisp::Writer& writer);
-
- virtual void update(float elapsed_time);
-
- std::string type() const
- { return "RainParticleSystem"; }
-
-private:
- class RainParticle : public Particle
- {
- public:
- float speed;
- };
-
- Surface* rainimages[2];
-};
-
-class CometParticleSystem : public ParticleSystem_Absolute, public Serializable
-{
-public:
- CometParticleSystem();
- virtual ~CometParticleSystem();
-
- void parse(const lisp::Lisp& lisp);
- void write(lisp::Writer& writer);
-
- virtual void update(float elapsed_time);
-
- std::string type() const
- { return "CometParticleSystem"; }
-
-private:
- class CometParticle : public Particle
- {
- public:
- float speed;
- };
-
- Surface* cometimages[2];
-};
-
-#endif
-
--- /dev/null
+// $Id: particlesystem.cpp 2470 2005-05-11 14:49:28Z wansti $
+//
+// SuperTux
+// Copyright (C) 2004 Matthias Braun <matze@braunis.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 <iostream>
+#include <cmath>
+
+#include "particlesystem_interactive.h"
+#include "video/drawing_context.h"
+#include "lisp/parser.h"
+#include "lisp/lisp.h"
+#include "lisp/writer.h"
+#include "resources.h"
+#include "main.h"
+
+#include "tile.h"
+#include "tilemap.h"
+#include "math/aatriangle.h"
+#include "collision.h"
+#include "collision_hit.h"
+#include "object/camera.h"
+#include "badguy/bomb.h"
+
+//TODO: Dynamically create splashes at collision spots
+// Find a way to make rain collide with objects like bonus blocks
+// Add an option to set rain strength
+ParticleSystem_Interactive::ParticleSystem_Interactive()
+{
+ virtual_width = SCREEN_WIDTH;
+ virtual_height = SCREEN_HEIGHT;
+ layer = LAYER_TILES;
+}
+
+ParticleSystem_Interactive::~ParticleSystem_Interactive()
+{
+ std::vector<Particle*>::iterator i;
+ for(i = particles.begin(); i != particles.end(); ++i) {
+ delete *i;
+ }
+}
+
+void ParticleSystem_Interactive::draw(DrawingContext& context)
+{
+ context.push_transform();
+
+ std::vector<Particle*>::iterator i;
+ for(i = particles.begin(); i != particles.end(); ++i) {
+ Particle* particle = *i;
+ context.draw_surface(particle->texture, particle->pos, layer);
+ }
+
+ context.pop_transform();
+}
+
+bool
+ParticleSystem_Interactive::collision(Particle* object, Vector movement)
+{
+ TileMap* solids = Sector::current()->solids;
+ // calculate rectangle where the object will move
+ float x1, x2;
+ float y1, y2;
+ x1 = object->pos.x;
+ x2 = x1 + 32 + movement.x;
+ y1 = object->pos.y;
+ y2 = y1 + 32 + movement.y;
+
+ // test with all tiles in this rectangle
+ int starttilex = int(x1-1) / 32;
+ int starttiley = int(y1-1) / 32;
+ int max_x = int(x2+1);
+ int max_y = int(y2+1);
+
+ CollisionHit temphit, hit;
+ Rect dest = Rect(x1, y1, x2, y2);
+ dest.move(movement);
+ hit.time = -1; // represents an invalid value
+ for(int x = starttilex; x*32 < max_x; ++x) {
+ for(int y = starttiley; y*32 < max_y; ++y) {
+ const Tile* tile = solids->get_tile(x, y);
+ if(!tile)
+ continue;
+ // skip non-solid tiles
+ if(!(tile->getAttributes() & Tile::SOLID))
+ continue;
+
+ if(tile->getAttributes() & Tile::SLOPE) { // slope tile
+ AATriangle triangle;
+ Vector p1(x*32, y*32);
+ Vector p2((x+1)*32, (y+1)*32);
+ triangle = AATriangle(p1, p2, tile->getData());
+
+ if(Collision::rectangle_aatriangle(temphit, dest, movement,
+ triangle)) {
+ if(temphit.time > hit.time)
+ hit = temphit;
+ }
+ } else { // normal rectangular tile
+ Rect rect(x*32, y*32, (x+1)*32, (y+1)*32);
+ if(Collision::rectangle_rectangle(temphit, dest,
+ movement, rect)) {
+ if(temphit.time > hit.time)
+ hit = temphit;
+ }
+ }
+ }
+ }
+
+ // did we collide at all?
+ if(hit.time < 0)
+ return false; else return true;
+}
+
+RainParticleSystem::RainParticleSystem()
+{
+ rainimages[0] = new Surface(datadir+"/images/objects/particles/rain0.png", true);
+ rainimages[1] = new Surface(datadir+"/images/objects/particles/rain1.png", true);
+
+ virtual_width = SCREEN_WIDTH * 2;
+
+ // create some random raindrops
+ size_t raindropcount = size_t(virtual_width/6.0);
+ for(size_t i=0; i<raindropcount; ++i) {
+ RainParticle* particle = new RainParticle;
+ particle->pos.x = rand() % int(virtual_width);
+ particle->pos.y = rand() % int(virtual_height);
+ int rainsize = rand() % 2;
+ particle->texture = rainimages[rainsize];
+ do {
+ particle->speed = (rainsize+1)*45 + (float(rand()%10)*.4);
+ } while(particle->speed < 1);
+ particle->speed *= 10; // gravity
+
+ particles.push_back(particle);
+ }
+}
+
+void
+RainParticleSystem::parse(const lisp::Lisp& reader)
+{
+ reader.get("layer", layer);
+}
+
+void
+RainParticleSystem::write(lisp::Writer& writer)
+{
+ writer.start_list("particles-rain");
+ writer.write_int("layer", layer);
+ writer.end_list("particles-rain");
+}
+
+RainParticleSystem::~RainParticleSystem()
+{
+ for(int i=0;i<2;++i)
+ delete rainimages[i];
+}
+
+void RainParticleSystem::update(float elapsed_time)
+{
+ std::vector<Particle*>::iterator i;
+ for(
+ i = particles.begin(); i != particles.end(); ++i) {
+ RainParticle* particle = (RainParticle*) *i;
+ float movement = particle->speed * elapsed_time;
+ float abs_x = Sector::current()->camera->get_translation().x;
+ float abs_y = Sector::current()->camera->get_translation().y;
+ particle->pos.y += movement;
+ particle->pos.x -= movement;
+ if ((particle->pos.y > SCREEN_HEIGHT + abs_y) || (collision(particle, Vector(-movement, movement)))) {
+ int new_x = (rand() % int(virtual_width)) + int(abs_x);
+ int new_y = 0;
+ //FIXME: Don't move particles over solid tiles
+ particle->pos.x = new_x;
+ particle->pos.y = new_y;
+ }
+ }
+}
+
+CometParticleSystem::CometParticleSystem()
+{
+ cometimages[0] = new Surface(datadir+"/images/creatures/mr_bomb/exploding-left-0.png", true);
+ cometimages[1] = new Surface(datadir+"/images/creatures/mr_bomb/exploding-left-0.png", true);
+
+ virtual_width = SCREEN_WIDTH * 2;
+
+ // create some random comets
+ size_t cometcount = 2;
+ for(size_t i=0; i<cometcount; ++i) {
+ CometParticle* particle = new CometParticle;
+ particle->pos.x = rand() % int(virtual_width);
+ particle->pos.y = rand() % int(virtual_height);
+ int cometsize = rand() % 2;
+ particle->texture = cometimages[cometsize];
+ do {
+ particle->speed = (cometsize+1)*30 + (float(rand()%10)*.4);
+ } while(particle->speed < 1);
+ particle->speed *= 10; // gravity
+
+ particles.push_back(particle);
+ }
+}
+
+void
+CometParticleSystem::parse(const lisp::Lisp& reader)
+{
+ reader.get("layer", layer);
+}
+
+void
+CometParticleSystem::write(lisp::Writer& writer)
+{
+ writer.start_list("particles-comets");
+ writer.write_int("layer", layer);
+ writer.end_list("particles-comets");
+}
+
+CometParticleSystem::~CometParticleSystem()
+{
+ for(int i=0;i<2;++i)
+ delete cometimages[i];
+}
+
+void CometParticleSystem::update(float elapsed_time)
+{
+ std::vector<Particle*>::iterator i;
+ for(
+ i = particles.begin(); i != particles.end(); ++i) {
+ CometParticle* particle = (CometParticle*) *i;
+ float movement = particle->speed * elapsed_time;
+ float abs_x = Sector::current()->camera->get_translation().x;
+ float abs_y = Sector::current()->camera->get_translation().y;
+ particle->pos.y += movement;
+ particle->pos.x -= movement;
+ if ((particle->pos.y > SCREEN_HEIGHT + abs_y) || (collision(particle, Vector(-movement, movement)))) {
+ if (particle->pos.y <= SCREEN_HEIGHT + abs_y) {
+ Sector::current()->add_object(new Bomb(particle->pos, LEFT));
+ }
+ int new_x = (rand() % int(virtual_width)) + int(abs_x);
+ int new_y = 0;
+ //FIXME: Don't move particles over solid tiles
+ particle->pos.x = new_x;
+ particle->pos.y = new_y;
+ }
+ }
+}
--- /dev/null
+// $Id: ParticleSystem_Interactive.h 2462 2005-05-10 15:38:16Z wansti $
+//
+// SuperTux
+// Copyright (C) 2004 Matthias Braun <matze@braunis.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 SUPERTUX_PARTICLESYSTEM_INTERACTIVE_H
+#define SUPERTUX_PARTICLESYSTEM_INTERACTIVE_H
+
+#include <vector>
+
+#include "video/surface.h"
+#include "game_object.h"
+#include "serializable.h"
+#include "sector.h"
+#include "math/vector.h"
+
+namespace lisp {
+class Lisp;
+}
+
+class DisplayManager;
+
+/**
+ * This is an alternative class for particle systems. It is responsible for storing a
+ * set of particles with each having an x- and y-coordinate the number of the
+ * layer where it should be drawn and a texture.
+ * This version of the particle system class doesn't use virtual screen coordinates,
+ * but Interactive ones. Particle systems which need Interactive levels coordinates, such
+ * as rain, should be implemented here.
+ * Classes that implement a particle system should subclass from this class,
+ * initialize particles in the constructor and move them in the simulate
+ * function.
+ */
+class ParticleSystem_Interactive : public GameObject
+{
+public:
+ ParticleSystem_Interactive();
+ virtual ~ParticleSystem_Interactive();
+
+ virtual void draw(DrawingContext& context);
+
+protected:
+ int layer;
+
+ class Particle
+ {
+ public:
+ virtual ~Particle()
+ { }
+
+ Vector pos;
+ Surface* texture;
+ };
+
+ std::vector<Particle*> particles;
+ float virtual_width, virtual_height;
+ bool collision(Particle* particle, Vector movement);
+};
+
+class RainParticleSystem : public ParticleSystem_Interactive, public Serializable
+{
+public:
+ RainParticleSystem();
+ virtual ~RainParticleSystem();
+
+ void parse(const lisp::Lisp& lisp);
+ void write(lisp::Writer& writer);
+
+ virtual void update(float elapsed_time);
+
+ std::string type() const
+ { return "RainParticleSystem"; }
+
+private:
+ class RainParticle : public Particle
+ {
+ public:
+ float speed;
+ };
+
+ Surface* rainimages[2];
+};
+
+class CometParticleSystem : public ParticleSystem_Interactive, public Serializable
+{
+public:
+ CometParticleSystem();
+ virtual ~CometParticleSystem();
+
+ void parse(const lisp::Lisp& lisp);
+ void write(lisp::Writer& writer);
+
+ virtual void update(float elapsed_time);
+
+ std::string type() const
+ { return "CometParticleSystem"; }
+
+private:
+ class CometParticle : public Particle
+ {
+ public:
+ float speed;
+ };
+
+ Surface* cometimages[2];
+};
+
+#endif
+
#include "object/camera.h"
#include "object/background.h"
#include "object/particlesystem.h"
-#include "object/particlesystem_absolute.h"
+#include "object/particlesystem_interactive.h"
#include "object/tilemap.h"
#include "lisp/parser.h"
#include "lisp/lisp.h"