From: Florian Forster Date: Sat, 30 Jan 2010 17:36:43 +0000 (+0000) Subject: Bug 562: Collision detection for unisolid tiles doesn't handle tilemap offset X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=70bccc4fcdd6c652e53786e52b3c6774dc79a3ac;p=supertux.git Bug 562: Collision detection for unisolid tiles doesn't handle tilemap offset - Use the new TileMap::get_tile_bbox function, which handles offset. Cleanups: - Get the bottom from the original MovingObject rather than subtracting movement from dest (an ugly kludge). - Apply De Morgan's law so the test more clearly corresponds to the comment. Resolves #562. Thanks to Matt McCutchen for updating the patch. SVN-Revision: 6299 --- diff --git a/src/supertux/sector.cpp b/src/supertux/sector.cpp index 8c96095a3..f0387f660 100644 --- a/src/supertux/sector.cpp +++ b/src/supertux/sector.cpp @@ -954,7 +954,8 @@ void check_collisions(collision::Constraints* constraints, void Sector::collision_tilemap(collision::Constraints* constraints, - const Vector& movement, const Rectf& dest) const + const Vector& movement, const Rectf& dest, + MovingObject& object) const { // calculate rectangle where the object will move float x1 = dest.get_left(); @@ -976,14 +977,15 @@ Sector::collision_tilemap(collision::Constraints* constraints, // skip non-solid tiles if((tile->getAttributes() & Tile::SOLID) == 0) continue; + Rectf rect = solids->get_tile_bbox(x, y); + // only handle unisolid when the player is falling down and when he was // above the tile before if(tile->getAttributes() & Tile::UNISOLID) { - if(movement.y <= 0 || dest.get_bottom() - movement.y - SHIFT_DELTA > y*32) + if(!(movement.y > 0 && object.get_bbox().get_bottom() - SHIFT_DELTA <= rect.get_top())) continue; } - Rectf rect = solids->get_tile_bbox(x, y); if(tile->getAttributes() & Tile::SLOPE) { // slope tile AATriangle triangle; int slope_data = tile->getData(); @@ -1110,9 +1112,9 @@ Sector::collision_object(MovingObject* object1, MovingObject* object2) const void Sector::collision_static(collision::Constraints* constraints, const Vector& movement, const Rectf& dest, - GameObject& object) + MovingObject& object) { - collision_tilemap(constraints, movement, dest); + collision_tilemap(constraints, movement, dest, object); // collision with other (static) objects for(MovingObjects::iterator i = moving_objects.begin(); diff --git a/src/supertux/sector.hpp b/src/supertux/sector.hpp index 595d85735..f154766c9 100644 --- a/src/supertux/sector.hpp +++ b/src/supertux/sector.hpp @@ -129,7 +129,8 @@ public: } void collision_tilemap(collision::Constraints* constraints, - const Vector& movement, const Rectf& dest) const; + const Vector& movement, const Rectf& dest, + MovingObject &object) const; /** * Checks if the specified rectangle is free of (solid) tiles. @@ -227,7 +228,7 @@ private: * (because of ABORT_MOVE in the collision response or no collisions) */ void collision_static(collision::Constraints* constraints, - const Vector& movement, const Rectf& dest, GameObject& object); + const Vector& movement, const Rectf& dest, MovingObject& object); void collision_static_constrains(MovingObject& object);