Fix jumping again disallowed when a platformer object is falling, even if jumping was allowed again at the beginning of the jump (#3495)

This commit is contained in:
D8H
2022-01-23 13:29:17 +01:00
committed by GitHub
parent 342a690fa6
commit 6da11cf0ed
2 changed files with 64 additions and 4 deletions

View File

@@ -453,8 +453,9 @@ namespace gdjs {
_setFalling() {
this._state.leave();
const from = this._state;
this._state = this._falling;
this._falling.enter();
this._falling.enter(from);
}
_setOnFloor(collidingPlatform: PlatformRuntimeBehavior) {
@@ -1797,8 +1798,17 @@ namespace gdjs {
this._behavior = behavior;
}
enter() {
this._behavior._canJump = false;
enter(from: State) {
// Only forbid jumping when starting to fall from a platform,
// not when falling during a jump. This is because the Jumping
// state has already set `_canJump` to false and we don't want to reset
// it again because it could have been set back to `true` to allow
// for an "air jump".
// Transition from Falling to Falling state should not happen,
// but don't change anything if this ever happen.
if (from !== this._behavior._jumping && from !== this) {
this._behavior._canJump = false;
}
}
leave() {}

View File

@@ -727,7 +727,7 @@ describe('gdjs.PlatformerObjectRuntimeBehavior', function () {
expect(object.getBehavior('auto1').isFallingWithoutJumping()).to.be(true);
});
it('can be allowed to jump in mid air', function () {
it('can be allowed to jump in mid air after falling from a platform', function () {
// Ensure the object falls on the platform
for (let i = 0; i < 10; ++i) {
runtimeScene.renderAndStep(1000 / 60);
@@ -774,6 +774,56 @@ describe('gdjs.PlatformerObjectRuntimeBehavior', function () {
expect(object.getBehavior('auto1').isFallingWithoutJumping()).to.be(true);
});
it('can still be allowed to jump in mid air after its jump speed reached 0', function () {
// Ensure the object falls on the platform
for (let i = 0; i < 10; ++i) {
runtimeScene.renderAndStep(1000 / 60);
}
// Check the object is on the platform
expect(object.getY()).to.be(-30); // -30 = -10 (platform y) + -20 (object height)
expect(object.getBehavior('auto1').isFalling()).to.be(false);
expect(object.getBehavior('auto1').isFallingWithoutJumping()).to.be(
false
);
expect(object.getBehavior('auto1').isMoving()).to.be(false);
// Jump
object.getBehavior('auto1').simulateJumpKey();
runtimeScene.renderAndStep(1000 / 60);
expect(object.getBehavior('auto1').isJumping()).to.be(true);
expect(object.getBehavior('auto1').isFalling()).to.be(false);
expect(object.getBehavior('auto1').isFallingWithoutJumping()).to.be(
false
);
expect(object.getBehavior('auto1').canJump()).to.be(false);
// Allow to jump again
object.getBehavior('auto1').setCanJump();
// Is jumping
for (let i = 0; i < 40; ++i) {
object.getBehavior('auto1').simulateLeftKey();
runtimeScene.renderAndStep(1000 / 60);
// Can still jump...
expect(object.getBehavior('auto1').canJump()).to.be(true);
}
// ...even when after the jump ended.
expect(object.getBehavior('auto1').isFallingWithoutJumping()).to.be(true);
expect(object.getBehavior('auto1').isFalling()).to.be(true);
expect(object.getBehavior('auto1').isJumping()).to.be(false);
// Jump again
object.getBehavior('auto1').simulateJumpKey();
runtimeScene.renderAndStep(1000 / 60);
expect(object.getBehavior('auto1').isJumping()).to.be(true);
expect(object.getBehavior('auto1').isFalling()).to.be(false);
expect(object.getBehavior('auto1').isFallingWithoutJumping()).to.be(
false
);
expect(object.getBehavior('auto1').canJump()).to.be(false);
});
it('can allow coyote time', function () {
// Ensure the object falls on the platform
for (let i = 0; i < 10; ++i) {