4 // Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
22 #include "collision.h"
29 bool rectcollision(base_type* one, base_type* two)
31 return (one->x >= two->x - one->width + 1 &&
32 one->x <= two->x + two->width - 1 &&
33 one->y >= two->y - one->height + 1 &&
34 one->y <= two->y + two->height - 1);
37 bool rectcollision_offset(base_type* one, base_type* two, float off_x, float off_y)
39 return (one->x >= two->x - one->width +off_x + 1 &&
40 one->x <= two->x + two->width + off_x - 1 &&
41 one->y >= two->y - one->height + off_y + 1 &&
42 one->y <= two->y + two->height + off_y - 1);
45 bool collision_object_map(base_type* pbase)
47 int v = (int)pbase->height / 16;
48 int h = (int)pbase->width / 16;
50 if(issolid(pbase->x + 1, pbase->y + 1) ||
51 issolid(pbase->x + pbase->width -1, pbase->y + 1) ||
52 issolid(pbase->x +1, pbase->y + pbase->height -1) ||
53 issolid(pbase->x + pbase->width -1, pbase->y + pbase->height - 1))
56 for(int i = 1; i < h; ++i)
58 if(issolid(pbase->x + i*16,pbase->y + 1))
62 for(int i = 1; i < h; ++i)
64 if( issolid(pbase->x + i*16,pbase->y + pbase->height - 1))
68 for(int i = 1; i < v; ++i)
70 if( issolid(pbase->x + 1, pbase->y + i*16))
73 for(int i = 1; i < v; ++i)
75 if( issolid(pbase->x + pbase->width - 1, pbase->y + i*16))
83 void collision_swept_object_map(base_type* old, base_type* current)
85 int steps; /* Used to speed up the collision tests, by stepping every 16pixels in the path. */
87 float lpath; /* Holds the longest path, which is either in X or Y direction. */
88 float xd,yd; /* Hold the smallest steps in X and Y directions. */
89 float temp, xt, yt; /* Temporary variable. */
95 if(old->x == current->x && old->y == current->y)
99 else if(old->x == current->x && old->y != current->y)
101 lpath = current->y - old->y;
115 else if(old->x != current->x && old->y == current->y)
117 lpath = current->x - old->x;
132 lpath = current->x - old->x;
135 if(current->y - old->y > lpath || old->y - current->y > lpath)
136 lpath = current->y - old->y;
140 xd = (current->x - old->x) / lpath;
141 yd = (current->y - old->y) / lpath;
144 steps = (int)(lpath / (float)16);
149 for(float i = 0; i <= lpath; old->x += xd, old->y += yd, ++i)
158 if(collision_object_map(old))
163 current->y = old->y - yd;
164 while(collision_object_map(current))
168 current->x = old->x - xd;
169 while(collision_object_map(current))
175 current->x = old->x - xd;
176 current->y = old->y - yd;
177 while(collision_object_map(current))
185 if(!collision_object_map(current))
191 if(!collision_object_map(current))
198 while(!collision_object_map(current))
216 Tile* gettile(float x, float y)
218 return TileManager::instance()->get(World::current()->get_level()->gettileid(x, y));
221 bool issolid(float x, float y)
223 Tile* tile = gettile(x,y);
224 return tile && tile->solid;
227 bool isbrick(float x, float y)
229 Tile* tile = gettile(x,y);
230 return tile && tile->brick;
233 bool isice(float x, float y)
235 Tile* tile = gettile(x,y);
236 return tile && tile->ice;
239 bool isfullbox(float x, float y)
241 Tile* tile = gettile(x,y);
242 return tile && tile->fullbox;
245 bool isdistro(float x, float y)
247 Tile* tile = gettile(x,y);
248 return tile && tile->distro;