I see that you copied your Collision Top side of Platform_01 to the collision event with lift, as that bug you mentioned doesn't happen if there's only a PhysicalResponse call in the collision event. The problem is caused by the if condition:
- Code: Select all
if (Player_base.yvelocity > 0) // <-- this!
{
// here's the rest of the code
}
The whole collision event is executed only if the player's yvelocity is greater than 0, i.e. when the player is falling. So, the event will only work if the lift you are riding is going downwards. When the lift starts going upwards, the collision event is executed for 1 last time, and InTheAir gets set to 0, as does the player's yvelocity. Now, the collision event is not executed anymore, because the player's yvelocity is less than or equal to 0, i.e. not greater than 0. And the reason the player remains stuck in the air until he's not colliding with the lift anymore is the way CollisionFree works.
What CollisionFree does is to check whether the actor would have a collision with any actor if it was moved to the given coordinates. In the Draw Actor script of the player there's this:
- Code: Select all
if (CollisionFree("Player_base",x,y+1) == 1)
{
InTheAir = 1;
}
The code checks if the player would be free of collisions if it was moved 1 pixel down. And when the player gets stuck in the air and is still in contact with the lift CollisionFree will return 0, telling that the player would not be free from collisions even if it was moved 1 pixel down. This goes on until the lift has moved up so that it's only colliding with the player by its lowest line of pixels. That's when CollisionFree returns 1, because now moving the player 1 pixel downwards results in him not colliding with any actors. And it is only then when the variable InTheAir finally gets set back to 1 and the player starts falling again.
The simplest fix is to just remove the condition. But doing so still leaves another problem. When the lift is going downwards, the player constantly changes between falling and not falling and it makes his lift ride look jumpy. And beside the visual annoyance, there's a much more severe problem - the player can only jump when he's not falling. And when he's constantly changing between falling and standing it's out of pure luck if the player manages to jump.
So here's a suggestion for fixing both problems.
If both, the lift and the player are moving downwards set the player's yvelocity equal to that of the lift after processing the PhysicalResponse. That way the both of them will move at the same speed and the player will remain standing and able to jump.
- Code: Select all
double TempXvelocity = Player_base.xvelocity;
double TempXcoordinates = Player_base.x;
if (collide.yvelocity > 0 && Player_base.yvelocity > 0)
{
PhysicalResponse(MOVE_EVENT_ACTOR_ONLY, USE_CALCULATED_MASS, 1.000000, 1.000000, 0.000000, 0.000000);
Player_base.yvelocity = collide.yvelocity;
}
else
{
PhysicalResponse(MOVE_EVENT_ACTOR_ONLY, USE_CALCULATED_MASS, 1.000000, 1.000000, 0.000000, 0.000000);
}
Player_base.x = TempXcoordinates;
Player_base.xvelocity = TempXvelocity;
InTheAir = 0;
There's still a single moment where the player is unable to jump, though. That's at the moment when the lift changes direction from going upwards to going downwards. The player's collision with the lift stops for a few frames and the CollisionFree goes on to set the InTheAir variable to 1, thus disabling jumping. It's a small window, but still can cause problems for players.
For fixing that problem one way to go is by using a different variable for determining whether the player is allowed to jump or not. That variable could be named CanJump, for example. Then you'd just set the variable to 1 in any Collision Top side of Platform / Lift events, and adjust the jumping code to check for CanJump == 1 as well as setting it to 0 after jumping. Then the last addition would be to add code like this to the player's Draw Actor script inside the CollisionFree check:
- Code: Select all
if (Player_base.yvelocity > 7)
{
CanJump = 0;
}
This would make the player unable to jump when falling, but only a little after he's started falling. By adjusting the value in the condition it is possible to eliminate the window of no-jumping when the lift changes direction. But this method also makes players able to jump a little after they've already walked off a platform. Some games do this intentionally. For example the original Crash Bandicoot games gave the player a little extra time for jumping even if they were not standing on the ground anymore. But this can be a difficult thing to balance, because if it's too noticeable, it just feels like the game is broken. So, I'm not sure if this is the best way to go for fixing the little no-jump window, but I can't come up with anything else right now.
The way to test for the no-jump window is to set the game's fps limit to 10, for example, and then wait for the moment where the player loses contact to the lift upon the lift changing direction, and then trying to jump just before the player lands on the lift again. It really is a small window, and not very likely to happen often when playing the game normally at normal fps. But it can happen, and it would not be a very nice way to possibly lose a life. Other possible solutions may involve partially redesigning the collisions and gravity of the game. It's up to you to decide what to do. I can also try to take a look at some of my older games to see if they have this problem or if I've managed to circumvent it.
I hope this Wall of Text™ was helpful in some way.