check that place is free before releasing a grabbed object
authorMatthias Braun <matze@braunis.de>
Sat, 31 Dec 2005 16:40:13 +0000 (16:40 +0000)
committerMatthias Braun <matze@braunis.de>
Sat, 31 Dec 2005 16:40:13 +0000 (16:40 +0000)
SVN-Revision: 2971

data/levels/test/simple.stl
src/collision.cpp
src/collision.hpp
src/object/player.cpp
src/sector.cpp
src/sector.hpp

index a4adb6f..e53acb5 100644 (file)
@@ -11,8 +11,8 @@
                 (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)
index ad87f89..be42268 100644 (file)
 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)
 {
index d4f5882..d32de1b 100644 (file)
@@ -17,7 +17,6 @@
 //  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__
 
@@ -29,6 +28,9 @@ class CollisionHit;
 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.
    */
index 2c4f580..e1f96b0 100644 (file)
@@ -158,15 +158,18 @@ Player::update(float elapsed_time)
     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)
index ceb80a3..69ab89d 100644 (file)
@@ -857,6 +857,39 @@ Sector::handle_collisions()
 }
 
 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...
index 6d9e2f4..0806cf2 100644 (file)
@@ -106,6 +106,11 @@ public:
   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);