From: Wolfgang Becker Date: Sat, 15 Jul 2006 23:01:06 +0000 (+0000) Subject: Fake solid for trampoline. X-Git-Url: https://git.octo.it/?a=commitdiff_plain;h=5c21e01c30deee6285d7c08a226f5265390dc0d7;p=supertux.git Fake solid for trampoline. SVN-Revision: 4025 --- diff --git a/data/levels/test/trampoline.stl b/data/levels/test/trampoline.stl index c49f1c098..84ae104ff 100644 --- a/data/levels/test/trampoline.stl +++ b/data/levels/test/trampoline.stl @@ -53,7 +53,6 @@ (trampoline (x 320) (y 1056) - (portable #f) ) (trampoline (x 288) diff --git a/src/object/player.cpp b/src/object/player.cpp index 039add7d9..85dca25ca 100644 --- a/src/object/player.cpp +++ b/src/object/player.cpp @@ -973,7 +973,7 @@ Player::collision(GameObject& other, const CollisionHit& hit) return CONTINUE; } - return FORCE_MOVE; + return CONTINUE; } void diff --git a/src/object/trampoline.cpp b/src/object/trampoline.cpp index 496e5ab33..7df1e312d 100644 --- a/src/object/trampoline.cpp +++ b/src/object/trampoline.cpp @@ -27,10 +27,10 @@ /* Trampoline will accelerate player to to VY_INITIAL, if * he jumps on it to VY_MIN. */ -namespace{ - static const std::string TRAMPOLINE_SOUND = "sounds/trampoline.wav"; - static const float VY_MIN = -1000; //negative, upwards - static const float VY_INITIAL = -500; +namespace { + const std::string TRAMPOLINE_SOUND = "sounds/trampoline.wav"; + const float VY_MIN = -900; //negative, upwards + const float VY_INITIAL = -500; } Trampoline::Trampoline(const lisp::Lisp& lisp) @@ -76,25 +76,28 @@ Trampoline::collision(GameObject& other, const CollisionHit& hit ) Player* player = dynamic_cast (&other); if ( player ) { float vy = player->physic.get_velocity_y(); - //player is falling down on trampolin holding "jump" + //player is falling down on trampoline if(hit.top && vy > 0) { if(player->get_controller()->hold(Controller::JUMP)) { vy = VY_MIN; } else { vy = VY_INITIAL; } - player->physic.set_velocity_y( vy ); sound_manager->play( TRAMPOLINE_SOUND ); sprite->set_action("swinging", 1); - //sprite->set_animation_loops(2); //TODO: 2 is not working - return SOLID; + return FORCE_MOVE; } } - - return SOLID; //TODO: Nobody should be able to walk through the trampoline. - // but to make this work we have to be in COLGROUP_STATIC which would - // break jumping and grabbing. + //Fake being solid for moving_object. + MovingObject* moving_object = dynamic_cast (&other); + if( moving_object ){ + CollisionHit hit_other = hit; + std::swap(hit_other.left, hit_other.right); + std::swap(hit_other.top, hit_other.bottom); + moving_object->collision_solid( hit_other ); + } + return FORCE_MOVE; } void diff --git a/src/sector.cpp b/src/sector.cpp index f488acead..247a3dec3 100644 --- a/src/sector.cpp +++ b/src/sector.cpp @@ -928,10 +928,18 @@ Sector::collision_object(MovingObject* object1, MovingObject* object2) const std::swap(hit.left, hit.right); std::swap(hit.top, hit.bottom); HitResponse response2 = object2->collision(*object1, hit); - if(response1 == CONTINUE || response2 == CONTINUE) { + assert( response1 != SOLID && response1 != PASSTHROUGH ); + assert( response2 != SOLID && response2 != PASSTHROUGH ); + if(response1 == CONTINUE && response2 == CONTINUE) { normal *= (0.5 + DELTA); object1->dest.move(-normal); object2->dest.move(normal); + } else if (response1 == CONTINUE && response2 == FORCE_MOVE) { + normal *= (1 + DELTA); + object1->dest.move(-normal); + } else if (response1 == FORCE_MOVE && response2 == CONTINUE) { + normal *= (1 + DELTA); + object2->dest.move(normal); } } } @@ -956,6 +964,98 @@ Sector::collision_static(collision::Constraints* constraints, } } +void +Sector::collision_static_constrains(MovingObject& object) +{ + using namespace collision; + + Constraints constraints; + Vector movement = object.get_movement(); + Rect& dest = object.dest; + float owidth = object.get_bbox().get_width(); + float oheight = object.get_bbox().get_height(); + + for(int i = 0; i < 2; ++i) { + collision_static(&constraints, Vector(0, movement.y), dest, object); + if(!constraints.has_constraints()) + break; + + // apply calculated horizontal constraints + if(constraints.bottom < INFINITY) { + float height = constraints.bottom - constraints.top; + if(height < oheight) { + // we're crushed, but ignore this for now, we'll get this again + // later if we're really crushed or things will solve itself when + // looking at the vertical constraints + } + dest.p2.y = constraints.bottom - DELTA; + dest.p1.y = dest.p2.y - oheight; + } else if(constraints.top > -INFINITY) { + dest.p1.y = constraints.top + DELTA; + dest.p2.y = dest.p1.y + oheight; + } + } + if(constraints.has_constraints()) { + if(constraints.hit.bottom) { + dest.move(constraints.ground_movement); + } + if(constraints.hit.top || constraints.hit.bottom) { + constraints.hit.left = false; + constraints.hit.right = false; + object.collision_solid(constraints.hit); + } + } + + constraints = Constraints(); + for(int i = 0; i < 2; ++i) { + collision_static(&constraints, movement, dest, object); + if(!constraints.has_constraints()) + break; + + // apply calculated vertical constraints + if(constraints.right < INFINITY) { + float width = constraints.right - constraints.left; + if(width + SHIFT_DELTA < owidth) { + printf("Object %p crushed horizontally... L:%f R:%f\n", &object, + constraints.left, constraints.right); + CollisionHit h; + h.left = true; + h.right = true; + h.crush = true; + object.collision_solid(h); + } else { + dest.p2.x = constraints.right - DELTA; + dest.p1.x = dest.p2.x - owidth; + } + } else if(constraints.left > -INFINITY) { + dest.p1.x = constraints.left + DELTA; + dest.p2.x = dest.p1.x + owidth; + } + } + + if(constraints.has_constraints()) { + if( constraints.hit.left || constraints.hit.right + || constraints.hit.top || constraints.hit.bottom + || constraints.hit.crush ) + object.collision_solid(constraints.hit); + } + + // an extra pass to make sure we're not crushed horizontally + constraints = Constraints(); + collision_static(&constraints, movement, dest, object); + if(constraints.bottom < INFINITY) { + float height = constraints.bottom - constraints.top; + if(height + SHIFT_DELTA < oheight) { + printf("Object %p crushed vertically...\n", &object); + CollisionHit h; + h.top = true; + h.bottom = true; + h.crush = true; + object.collision_solid(h); + } + } +} + void Sector::handle_collisions() { @@ -969,7 +1069,7 @@ Sector::handle_collisions() moving_object->dest = moving_object->get_bbox(); moving_object->dest.move(moving_object->get_movement()); } - + // part1: COLGROUP_MOVING vs COLGROUP_STATIC and tilemap for(MovingObjects::iterator i = moving_objects.begin(); i != moving_objects.end(); ++i) { @@ -979,94 +1079,10 @@ Sector::handle_collisions() || !moving_object->is_valid()) continue; - Constraints constraints; - Vector movement = moving_object->get_movement(); - Rect& dest = moving_object->dest; - float owidth = moving_object->get_bbox().get_width(); - float oheight = moving_object->get_bbox().get_height(); - - for(int i = 0; i < 2; ++i) { - collision_static(&constraints, Vector(0, movement.y), dest, *moving_object); - if(!constraints.has_constraints()) - break; - - // apply calculated horizontal constraints - if(constraints.bottom < INFINITY) { - float height = constraints.bottom - constraints.top; - if(height < oheight) { - // we're crushed, but ignore this for now, we'll get this again - // later if we're really crushed or things will solve itself when - // looking at the vertical constraints - } - dest.p2.y = constraints.bottom - DELTA; - dest.p1.y = dest.p2.y - oheight; - } else if(constraints.top > -INFINITY) { - dest.p1.y = constraints.top + DELTA; - dest.p2.y = dest.p1.y + oheight; - } - } - if(constraints.has_constraints()) { - if(constraints.hit.bottom) { - dest.move(constraints.ground_movement); - } - if(constraints.hit.top || constraints.hit.bottom) { - constraints.hit.left = false; - constraints.hit.right = false; - moving_object->collision_solid(constraints.hit); - } - } - - constraints = Constraints(); - for(int i = 0; i < 2; ++i) { - collision_static(&constraints, movement, dest, *moving_object); - if(!constraints.has_constraints()) - break; - - // apply calculated vertical constraints - if(constraints.right < INFINITY) { - float width = constraints.right - constraints.left; - if(width + SHIFT_DELTA < owidth) { - printf("Object %p crushed horizontally... L:%f R:%f\n", moving_object, - constraints.left, constraints.right); - CollisionHit h; - h.left = true; - h.right = true; - h.crush = true; - moving_object->collision_solid(h); - } else { - dest.p2.x = constraints.right - DELTA; - dest.p1.x = dest.p2.x - owidth; - } - } else if(constraints.left > -INFINITY) { - dest.p1.x = constraints.left + DELTA; - dest.p2.x = dest.p1.x + owidth; - } - } - - if(constraints.has_constraints()) { - if( constraints.hit.left || constraints.hit.right - || constraints.hit.top || constraints.hit.bottom - || constraints.hit.crush ) - moving_object->collision_solid(constraints.hit); - //else printf("Wayne?\n"); - } - - // an extra pass to make sure we're not crushed horizontally - constraints = Constraints(); - collision_static(&constraints, movement, dest, *moving_object); - if(constraints.bottom < INFINITY) { - float height = constraints.bottom - constraints.top; - if(height + SHIFT_DELTA < oheight) { - printf("Object %p crushed vertically...\n", moving_object); - CollisionHit h; - h.top = true; - h.bottom = true; - h.crush = true; - moving_object->collision_solid(h); - } - } + collision_static_constrains(*moving_object); } + // part2: COLGROUP_MOVING vs tile attributes for(MovingObjects::iterator i = moving_objects.begin(); i != moving_objects.end(); ++i) { diff --git a/src/sector.hpp b/src/sector.hpp index 0ed2f4c17..cced76952 100644 --- a/src/sector.hpp +++ b/src/sector.hpp @@ -181,6 +181,8 @@ private: */ void collision_static(collision::Constraints* constraints, const Vector& movement, const Rect& dest, GameObject& object); + + void collision_static_constrains(MovingObject& object); GameObject* parse_object(const std::string& name, const lisp::Lisp& lisp);