(speed 0.5))
(spawnpoint (name "main") (x 150) (y 100))
(rock (x 50) (y 50))
- ;;(rock (x 50) (y 100))
- ;;(rock (x 50) (y 150))
+ ;(rock (x 50) (y 100))
+ ;(rock (x 50) (y 150))
(tilemap
(layer "background")
(solid #f)
static const float DELTA = .0001;
bool
+Collision::intersects(const Rect& r1, const Rect& r2)
+{
+ if(r1.p2.x < r2.p1.x || r1.p1.x > r2.p2.x)
+ return false;
+ if(r1.p2.y < r2.p1.y || r1.p1.y > r2.p2.y)
+ return false;
+
+ return true;
+}
+
+bool
Collision::rectangle_rectangle(CollisionHit& hit, const Rect& r1,
const Vector& movement, const Rect& r2)
{
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
-
#ifndef __COLLISION_H__
#define __COLLISION_H__
class Collision
{
public:
+ /** checks if 2 rectangle intersect each other */
+ static bool intersects(const Rect& r1, const Rect& r2);
+
/** does collision detection between 2 rectangles. Returns true in case of
* collision and fills in the hit structure then.
*/
Vector pos = get_pos() +
Vector(dir == LEFT ? -bbox.get_width()-1 : bbox.get_width()+1,
bbox.get_height()*0.66666 - 32);
- MovingObject* moving_object = dynamic_cast<MovingObject*> (grabbed_object);
- if(moving_object) {
- moving_object->set_pos(pos);
- } else {
+ Rect dest(pos, pos + Vector(32, 32));
+ if(Sector::current()->is_free_space(dest)) {
+ MovingObject* moving_object = dynamic_cast<MovingObject*> (grabbed_object);
+ if(moving_object) {
+ moving_object->set_pos(pos);
+ } else {
#ifdef DEBUG
- std::cout << "Non MovingObjetc grabbed?!?\n";
+ std::cout << "Non MovingObjetc grabbed?!?\n";
#endif
+ }
+ grabbed_object = 0;
}
- grabbed_object = 0;
}
if(!dying && !deactivated)
}
bool
+Sector::is_free_space(const Rect& rect) const
+{
+ // test with all tiles in this rectangle
+ int starttilex = int(rect.p1.x) / 32;
+ int starttiley = int(rect.p1.y) / 32;
+ int max_x = int(rect.p2.x);
+ int max_y = int(rect.p2.y);
+
+ 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;
+ if(tile->getAttributes() & Tile::SOLID)
+ return false;
+ }
+ }
+
+ for(MovingObjects::const_iterator i = moving_objects.begin();
+ i != moving_objects.end(); ++i) {
+ const MovingObject* moving_object = *i;
+ if(moving_object->get_group() != COLGROUP_STATIC
+ || !moving_object->is_valid())
+ continue;
+
+ if(Collision::intersects(rect, moving_object->get_bbox()))
+ return false;
+ }
+
+ return true;
+}
+
+bool
Sector::add_bullet(const Vector& pos, float xm, Direction dir)
{
// TODO remove this function and move these checks elsewhere...
void collision_tilemap(MovingObject* object, CollisionHit& hit) const;
uint32_t collision_tile_attributes(MovingObject* object) const;
+ /** Checks if at the specified rectangle are gameobjects with STATIC flag set
+ * (or solid tiles from the tilemap)
+ */
+ bool is_free_space(const Rect& rect) const;
+
private:
void collision_object(MovingObject* object1, MovingObject* object2) const;
GameObject* parse_object(const std::string& name, const lisp::Lisp& lisp);