From: Matthias Braun Date: Sat, 31 Dec 2005 16:40:13 +0000 (+0000) Subject: check that place is free before releasing a grabbed object X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=a0802811844e5343aed735f091106e20ab2cabc0;p=supertux.git check that place is free before releasing a grabbed object SVN-Revision: 2971 --- diff --git a/data/levels/test/simple.stl b/data/levels/test/simple.stl index a4adb6f13..e53acb5ea 100644 --- a/data/levels/test/simple.stl +++ b/data/levels/test/simple.stl @@ -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) diff --git a/src/collision.cpp b/src/collision.cpp index ad87f8918..be4226854 100644 --- a/src/collision.cpp +++ b/src/collision.cpp @@ -34,6 +34,17 @@ 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) { diff --git a/src/collision.hpp b/src/collision.hpp index d4f58825a..d32de1ba3 100644 --- a/src/collision.hpp +++ b/src/collision.hpp @@ -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. */ diff --git a/src/object/player.cpp b/src/object/player.cpp index 2c4f58017..e1f96b0fb 100644 --- a/src/object/player.cpp +++ b/src/object/player.cpp @@ -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 (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 (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) diff --git a/src/sector.cpp b/src/sector.cpp index ceb80a3d6..69ab89da6 100644 --- a/src/sector.cpp +++ b/src/sector.cpp @@ -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... diff --git a/src/sector.hpp b/src/sector.hpp index 6d9e2f47e..0806cf209 100644 --- a/src/sector.hpp +++ b/src/sector.hpp @@ -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);