From b4b8af638ac4ed8dbe0f081b453f568f585899de Mon Sep 17 00:00:00 2001 From: Christoph Sommer Date: Mon, 18 Feb 2008 20:07:06 +0000 Subject: [PATCH] Resolves issue 0000269: Moving tilemaps have improper physics SVN-Revision: 5331 --- data/levels/test/tileplatforms.stl | 160 +++++++++++++++++++++++++++++++++++++ src/collision.cpp | 6 +- src/collision.hpp | 4 +- src/object/tilemap.cpp | 8 +- src/object/tilemap.hpp | 6 ++ src/sector.cpp | 9 ++- 6 files changed, 182 insertions(+), 11 deletions(-) create mode 100644 data/levels/test/tileplatforms.stl diff --git a/data/levels/test/tileplatforms.stl b/data/levels/test/tileplatforms.stl new file mode 100644 index 000000000..0f2d86b24 --- /dev/null +++ b/data/levels/test/tileplatforms.stl @@ -0,0 +1,160 @@ +;;Uses 01 - Welcome to Antartica.stl as base +(supertux-level + (version 2) + (name (_ "Demonstrates two tilemap platforms.")) + (author "Mathnerd314") + (sector + (name "main") + (music "music/chipdisko.ogg") + (init-script "platform1.start_moving();platform2.start_moving();") ;needed for some reason (they don't move initially) + (ambient-light 1 1 1) + (spawnpoint + (name "main") + (x 100) + (y 100) + ) + (background + (speed 0.5) + (image "images/background/arctis.jpg") + ) + (tilemap + (z-pos -100) + (solid #f) + (speed 1) + (width 27) + (height 19) + (tiles +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + ) + ) + (tilemap + (z-pos 0) + (solid #t) + (speed 1) + (width 27) + (height 19) + (tiles +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 126 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 0 0 0 0 0 0 +13 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 15 0 0 0 0 0 0 +10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 12 0 0 0 0 0 0 + ) + ) + (tilemap + (z-pos 100) + (solid #f) + (speed 1) + (width 27) + (height 19) + (tiles +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + ) + ) + (tilemap + (name "platform1") + (z-pos 1) + (solid #t) + (speed 1) + (speed-y 1) + (path + (mode "circular") + (node + (x 224) + (y 192) + (time 5) + ) + (node + (x 224) + (y 472) + (time 5) + ) + ) + (width 5) + (height 3) + (tiles + 7 8 8 8 9 + 13 14 14 14 15 + 16 17 17 17 18 + ) + ) + (tilemap + (name "platform2") + (z-pos 2) + (solid #t) + (speed 1) + (speed-y 1) + (path + (mode "circular") + (node + (x 86) + (y 450) + (time 1) + ) + (node + (x 200) + (y 450) + (time 1) + ) + ) + (width 5) + (height 1) + (tiles + 27 28 28 28 29 + ) + ) + (camera + (mode "normal") + ) + ) +) diff --git a/src/collision.cpp b/src/collision.cpp index f96fdea53..6ff22952b 100644 --- a/src/collision.cpp +++ b/src/collision.cpp @@ -61,7 +61,7 @@ namespace { } bool rectangle_aatriangle(Constraints* constraints, const Rect& rect, - const AATriangle& triangle) + const AATriangle& triangle, const Vector& addl_ground_movement) { if(!intersects(rect, (const Rect&) triangle)) return false; @@ -146,6 +146,7 @@ bool rectangle_aatriangle(Constraints* constraints, const Rect& rect, if(outvec.y < 0) { constraints->bottom = rect.get_bottom() + outvec.y; constraints->hit.bottom = true; + constraints->ground_movement += addl_ground_movement; } else { constraints->top = rect.get_top() + outvec.y; constraints->hit.top = true; @@ -157,7 +158,7 @@ bool rectangle_aatriangle(Constraints* constraints, const Rect& rect, } void set_rectangle_rectangle_constraints(Constraints* constraints, - const Rect& r1, const Rect& r2) + const Rect& r1, const Rect& r2, const Vector& addl_ground_movement) { float itop = r1.get_bottom() - r2.get_top(); float ibottom = r2.get_bottom() - r1.get_top(); @@ -170,6 +171,7 @@ void set_rectangle_rectangle_constraints(Constraints* constraints, if(itop < ibottom) { constraints->bottom = std::min(constraints->bottom, r2.get_top()); constraints->hit.bottom = true; + constraints->ground_movement += addl_ground_movement; } else { constraints->top = std::max(constraints->top, r2.get_bottom()); constraints->hit.top = true; diff --git a/src/collision.hpp b/src/collision.hpp index ba6b6f8d9..a31878c88 100644 --- a/src/collision.hpp +++ b/src/collision.hpp @@ -63,10 +63,10 @@ bool intersects(const Rect& r1, const Rect& r2); * Returns true in case of a collision and fills in the hit structure then. */ bool rectangle_aatriangle(Constraints* constraints, const Rect& rect, - const AATriangle& triangle); + const AATriangle& triangle, const Vector& addl_ground_movement = Vector(0,0)); void set_rectangle_rectangle_constraints(Constraints* constraints, - const Rect& r1, const Rect& r2); + const Rect& r1, const Rect& r2, const Vector& addl_ground_movement = Vector(0,0)); } diff --git a/src/object/tilemap.cpp b/src/object/tilemap.cpp index 1c4e49031..d24cacab9 100644 --- a/src/object/tilemap.cpp +++ b/src/object/tilemap.cpp @@ -44,7 +44,7 @@ TileMap::TileMap(const TileSet *new_tileset) : tileset(new_tileset), solid(false), speed_x(1), speed_y(1), width(0), - height(0), z_pos(0), x_offset(0), y_offset(0), drawing_effect(NO_EFFECT), + height(0), z_pos(0), x_offset(0), y_offset(0), movement(Vector(0,0)), drawing_effect(NO_EFFECT), alpha(1.0), current_alpha(1.0), remaining_fade_time(0), draw_target(DrawingContext::NORMAL) { @@ -52,7 +52,7 @@ TileMap::TileMap(const TileSet *new_tileset) TileMap::TileMap(const lisp::Lisp& reader) : solid(false), speed_x(1), speed_y(1), width(-1), - height(-1), z_pos(0), x_offset(0), y_offset(0), drawing_effect(NO_EFFECT), + height(-1), z_pos(0), x_offset(0), y_offset(0), movement(Vector(0,0)), drawing_effect(NO_EFFECT), alpha(1.0), current_alpha(1.0), remaining_fade_time(0), draw_target(DrawingContext::NORMAL) { @@ -110,7 +110,7 @@ TileMap::TileMap(const lisp::Lisp& reader) TileMap::TileMap(const TileSet *new_tileset, std::string name, int z_pos, bool solid, size_t width, size_t height) : tileset(new_tileset), solid(solid), speed_x(1), speed_y(1), width(0), - height(0), z_pos(z_pos), x_offset(0), y_offset(0), + height(0), z_pos(z_pos), x_offset(0), y_offset(0), movement(Vector(0,0)), drawing_effect(NO_EFFECT), alpha(1.0), current_alpha(1.0), remaining_fade_time(0), draw_target(DrawingContext::NORMAL) { @@ -157,9 +157,11 @@ TileMap::update(float elapsed_time) if ((alpha > 0.75) && (current_alpha > 0.75)) set_solid(true); } + movement = Vector(0,0); // if we have a path to follow, follow it if (walker.get()) { Vector v = walker->advance(elapsed_time); + movement = Vector(v.x-get_x_offset(), std::max(0.0f,v.y-get_y_offset())); set_x_offset(v.x); set_y_offset(v.y); } diff --git a/src/object/tilemap.hpp b/src/object/tilemap.hpp index d6ee518de..d67049d78 100644 --- a/src/object/tilemap.hpp +++ b/src/object/tilemap.hpp @@ -90,6 +90,11 @@ public: float get_y_offset() const { return y_offset; } + const Vector& get_movement() const + { + return movement; + } + void set_x_offset(float x_offset) { this->x_offset = x_offset; } @@ -162,6 +167,7 @@ private: int z_pos; float x_offset; float y_offset; + Vector movement; /**< The movement that happened last frame */ DrawingEffect drawing_effect; float alpha; /**< requested tilemap opacity */ diff --git a/src/sector.cpp b/src/sector.cpp index 253212bc4..686efc9dc 100644 --- a/src/sector.cpp +++ b/src/sector.cpp @@ -887,7 +887,7 @@ static const float SHIFT_DELTA = 7.0f; /** r1 is supposed to be moving, r2 a solid object */ void check_collisions(collision::Constraints* constraints, const Vector& movement, const Rect& r1, const Rect& r2, - GameObject* object = NULL, MovingObject* other = NULL) + GameObject* object = NULL, MovingObject* other = NULL, const Vector& addl_ground_movement = Vector(0,0)) { if(!collision::intersects(r1, r2)) return; @@ -924,6 +924,7 @@ void check_collisions(collision::Constraints* constraints, } } + constraints->ground_movement += addl_ground_movement; if(other != NULL) { HitResponse response = other->collision(*object, dummy); if(response == PASSTHROUGH) @@ -931,7 +932,7 @@ void check_collisions(collision::Constraints* constraints, if(other->get_movement() != Vector(0, 0)) { // TODO what todo when we collide with 2 moving objects?!? - constraints->ground_movement = other->get_movement(); + constraints->ground_movement += other->get_movement(); } } @@ -998,10 +999,10 @@ Sector::collision_tilemap(collision::Constraints* constraints, Vector p2((x+1)*32 + solids->get_x_offset(), (y+1)*32 + solids->get_y_offset()); triangle = AATriangle(p1, p2, tile->getData()); - collision::rectangle_aatriangle(constraints, dest, triangle); + collision::rectangle_aatriangle(constraints, dest, triangle, solids->get_movement()); } else { // normal rectangular tile Rect rect(x*32 + solids->get_x_offset(), y*32 + solids->get_y_offset(), (x+1)*32 + solids->get_x_offset(), (y+1)*32 + solids->get_y_offset()); - check_collisions(constraints, movement, dest, rect); + check_collisions(constraints, movement, dest, rect, NULL, NULL, solids->get_movement()); } } } -- 2.11.0