2 // Copyright (C) 2006 Matthias Braun <matze@braunis.de>
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "object/particlesystem_interactive.hpp"
19 #include "math/aatriangle.hpp"
20 #include "object/tilemap.hpp"
21 #include "supertux/collision.hpp"
22 #include "supertux/tile.hpp"
24 //TODO: Find a way to make rain collide with objects like bonus blocks
25 // Add an option to set rain strength
26 // Fix rain being "respawned" over solid tiles
27 ParticleSystem_Interactive::ParticleSystem_Interactive() :
33 virtual_width = SCREEN_WIDTH;
34 virtual_height = SCREEN_HEIGHT;
38 ParticleSystem_Interactive::~ParticleSystem_Interactive()
40 std::vector<Particle*>::iterator i;
41 for(i = particles.begin(); i != particles.end(); ++i) {
46 void ParticleSystem_Interactive::draw(DrawingContext& context)
48 context.push_transform();
50 std::vector<Particle*>::iterator i;
51 for(i = particles.begin(); i != particles.end(); ++i) {
52 Particle* particle = *i;
53 context.draw_surface(particle->texture, particle->pos, z_pos);
56 context.pop_transform();
60 ParticleSystem_Interactive::collision(Particle* object, Vector movement)
62 using namespace collision;
64 // calculate rectangle where the object will move
68 x2 = x1 + 32 + movement.x;
70 y2 = y1 + 32 + movement.y;
73 // test with all tiles in this rectangle
74 int starttilex = int(x1-1) / 32;
75 int starttiley = int(y1-1) / 32;
76 int max_x = int(x2+1);
77 int max_y = int(y2+1);
79 Rectf dest(x1, y1, x2, y2);
81 Constraints constraints;
83 for(std::list<TileMap*>::const_iterator i = Sector::current()->solid_tilemaps.begin(); i != Sector::current()->solid_tilemaps.end(); i++) {
85 // FIXME Handle a nonzero tilemap offset
86 for(int x = starttilex; x*32 < max_x; ++x) {
87 for(int y = starttiley; y*32 < max_y; ++y) {
88 const Tile* tile = solids->get_tile(x, y);
91 // skip non-solid tiles, except water
92 if(! (tile->getAttributes() & (Tile::WATER | Tile::SOLID)))
95 Rectf rect = solids->get_tile_bbox(x, y);
96 if(tile->is_slope ()) { // slope tile
97 AATriangle triangle = AATriangle(rect, tile->getData());
99 if(rectangle_aatriangle(&constraints, dest, triangle)) {
100 if(tile->getAttributes() & Tile::WATER)
103 } else { // normal rectangular tile
104 if(intersects(dest, rect)) {
105 if(tile->getAttributes() & Tile::WATER)
107 set_rectangle_rectangle_constraints(&constraints, dest, rect);
114 // TODO don't use magic numbers here...
116 // did we collide at all?
117 if(!constraints.has_constraints())
120 const CollisionHit& hit = constraints.hit;
122 return 0; //collision with water tile - don't draw splash
124 if (hit.right || hit.left) {
125 return 2; //collision from right
127 return 1; //collision from above