Fake solid for trampoline.
authorWolfgang Becker <uafr@gmx.de>
Sat, 15 Jul 2006 23:01:06 +0000 (23:01 +0000)
committerWolfgang Becker <uafr@gmx.de>
Sat, 15 Jul 2006 23:01:06 +0000 (23:01 +0000)
SVN-Revision: 4025

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

index c49f1c0..84ae104 100644 (file)
@@ -53,7 +53,6 @@
     (trampoline
       (x 320)
       (y 1056)
-      (portable #f)
     )
     (trampoline
       (x 288)
index 039add7..85dca25 100644 (file)
@@ -973,7 +973,7 @@ Player::collision(GameObject& other, const CollisionHit& hit)
     return CONTINUE;
   }
 
-  return FORCE_MOVE;
+  return CONTINUE;
 }
 
 void
index 496e5ab..7df1e31 100644 (file)
 
 /* 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<Player*> (&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<MovingObject*> (&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 
index f488ace..247a3de 100644 (file)
@@ -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) {
index 0ed2f4c..cced769 100644 (file)
@@ -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);