/* 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)
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
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);
}
}
}
}
}
+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()
{
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) {
|| !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) {