src/object/particlesystem_interactive.cpp

Go to the documentation of this file.
00001 //  SuperTux
00002 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
00003 //
00004 //  This program is free software: you can redistribute it and/or modify
00005 //  it under the terms of the GNU General Public License as published by
00006 //  the Free Software Foundation, either version 3 of the License, or
00007 //  (at your option) any later version.
00008 //
00009 //  This program is distributed in the hope that it will be useful,
00010 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 //  GNU General Public License for more details.
00013 //
00014 //  You should have received a copy of the GNU General Public License
00015 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016 
00017 #include "object/particlesystem_interactive.hpp"
00018 
00019 #include "math/aatriangle.hpp"
00020 #include "object/tilemap.hpp"
00021 #include "supertux/collision.hpp"
00022 #include "supertux/tile.hpp"
00023 
00024 //TODO: Find a way to make rain collide with objects like bonus blocks
00025 //      Add an option to set rain strength
00026 //      Fix rain being "respawned" over solid tiles
00027 ParticleSystem_Interactive::ParticleSystem_Interactive() :
00028   z_pos(),
00029   particles(),
00030   virtual_width(),
00031   virtual_height()
00032 {
00033   virtual_width = SCREEN_WIDTH;
00034   virtual_height = SCREEN_HEIGHT;
00035   z_pos = 0;
00036 }
00037 
00038 ParticleSystem_Interactive::~ParticleSystem_Interactive()
00039 {
00040   std::vector<Particle*>::iterator i;
00041   for(i = particles.begin(); i != particles.end(); ++i) {
00042     delete *i;
00043   }
00044 }
00045 
00046 void ParticleSystem_Interactive::draw(DrawingContext& context)
00047 {
00048   context.push_transform();
00049 
00050   std::vector<Particle*>::iterator i;
00051   for(i = particles.begin(); i != particles.end(); ++i) {
00052     Particle* particle = *i;
00053     context.draw_surface(particle->texture, particle->pos, z_pos);
00054   }
00055 
00056   context.pop_transform();
00057 }
00058 
00059 int
00060 ParticleSystem_Interactive::collision(Particle* object, Vector movement)
00061 {
00062   using namespace collision;
00063 
00064   // calculate rectangle where the object will move
00065   float x1, x2;
00066   float y1, y2;
00067   x1 = object->pos.x;
00068   x2 = x1 + 32 + movement.x;
00069   y1 = object->pos.y;
00070   y2 = y1 + 32 + movement.y;
00071   bool water = false;
00072 
00073   // test with all tiles in this rectangle
00074   int starttilex = int(x1-1) / 32;
00075   int starttiley = int(y1-1) / 32;
00076   int max_x = int(x2+1);
00077   int max_y = int(y2+1);
00078 
00079   Rectf dest(x1, y1, x2, y2);
00080   dest.move(movement);
00081   Constraints constraints;
00082 
00083   for(std::list<TileMap*>::const_iterator i = Sector::current()->solid_tilemaps.begin(); i != Sector::current()->solid_tilemaps.end(); i++) {
00084     TileMap* solids = *i;
00085     // FIXME Handle a nonzero tilemap offset
00086     for(int x = starttilex; x*32 < max_x; ++x) {
00087       for(int y = starttiley; y*32 < max_y; ++y) {
00088         const Tile* tile = solids->get_tile(x, y);
00089         if(!tile)
00090           continue;
00091         // skip non-solid tiles, except water
00092         if(! (tile->getAttributes() & (Tile::WATER | Tile::SOLID)))
00093           continue;
00094 
00095         Rectf rect = solids->get_tile_bbox(x, y);
00096         if(tile->is_slope ()) { // slope tile
00097           AATriangle triangle = AATriangle(rect, tile->getData());
00098 
00099           if(rectangle_aatriangle(&constraints, dest, triangle)) {
00100             if(tile->getAttributes() & Tile::WATER)
00101               water = true;
00102           }
00103         } else { // normal rectangular tile
00104           if(intersects(dest, rect)) {
00105             if(tile->getAttributes() & Tile::WATER)
00106               water = true;
00107             set_rectangle_rectangle_constraints(&constraints, dest, rect);
00108           }
00109         }
00110       }
00111     }
00112   }
00113 
00114   // TODO don't use magic numbers here...
00115 
00116   // did we collide at all?
00117   if(!constraints.has_constraints())
00118     return -1;
00119 
00120   const CollisionHit& hit = constraints.hit;
00121   if (water) {
00122     return 0; //collision with water tile - don't draw splash
00123   } else {
00124     if (hit.right || hit.left) {
00125       return 2; //collision from right
00126     } else {
00127       return 1; //collision from above
00128     }
00129   }
00130 
00131   return 0;
00132 }
00133 
00134 /* EOF */

Generated on Mon Apr 14 03:38:22 2014 for SuperTux by  doxygen 1.5.1