mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Compare commits
4 Commits
shape-pain
...
fix-platfo
Author | SHA1 | Date | |
---|---|---|---|
![]() |
911443ebd7 | ||
![]() |
5faf9bd63c | ||
![]() |
bb23e05edc | ||
![]() |
b45c448cdb |
@@ -648,6 +648,19 @@ void DeclarePlatformBehaviorExtension(gd::PlatformExtension& extension) {
|
|||||||
.UseStandardOperatorParameters("number")
|
.UseStandardOperatorParameters("number")
|
||||||
.MarkAsAdvanced();
|
.MarkAsAdvanced();
|
||||||
|
|
||||||
|
aut.AddScopedAction("FollowCurrentPlatform",
|
||||||
|
_("Follow the floor"),
|
||||||
|
_("Move the object to follow the platform it's currently"
|
||||||
|
"on if any. This action allows to avoid the 1-frame "
|
||||||
|
"delay induced by the automatic following."),
|
||||||
|
_("Move _PARAM0_ to follow the floor"),
|
||||||
|
_(""),
|
||||||
|
"CppPlatform/Extensions/platformerobjecticon.png",
|
||||||
|
"CppPlatform/Extensions/platformerobjecticon.png")
|
||||||
|
.AddParameter("object", _("Object"))
|
||||||
|
.AddParameter("behavior", _("Behavior"), "PlatformerObjectBehavior")
|
||||||
|
.MarkAsAdvanced();
|
||||||
|
|
||||||
aut.AddCondition("CurrentSpeed",
|
aut.AddCondition("CurrentSpeed",
|
||||||
_("Current horizontal speed"),
|
_("Current horizontal speed"),
|
||||||
_("Compare the current horizontal speed of the object "
|
_("Compare the current horizontal speed of the object "
|
||||||
|
@@ -131,10 +131,14 @@ class PlatformBehaviorJsExtension : public gd::PlatformExtension {
|
|||||||
"getCurrentJumpSpeed");
|
"getCurrentJumpSpeed");
|
||||||
autExpressions["CurrentJumpSpeed"].SetFunctionName("getCurrentJumpSpeed");
|
autExpressions["CurrentJumpSpeed"].SetFunctionName("getCurrentJumpSpeed");
|
||||||
autActions["PlatformBehavior::SetCanJump"].SetFunctionName("setCanJump");
|
autActions["PlatformBehavior::SetCanJump"].SetFunctionName("setCanJump");
|
||||||
autActions["PlatformBehavior::PlatformerObjectBehavior::SetCanNotAirJump"].SetFunctionName("setCanNotAirJump");
|
autActions["PlatformBehavior::PlatformerObjectBehavior::SetCanNotAirJump"]
|
||||||
autActions["PlatformBehavior::PlatformerObjectBehavior::AbortJump"].SetFunctionName("abortJump");
|
.SetFunctionName("setCanNotAirJump");
|
||||||
autConditions["PlatformBehavior::CanJump"].SetFunctionName(
|
autActions["PlatformBehavior::PlatformerObjectBehavior::AbortJump"]
|
||||||
"canJump");
|
.SetFunctionName("abortJump");
|
||||||
|
autActions
|
||||||
|
["PlatformBehavior::PlatformerObjectBehavior::FollowCurrentPlatform"]
|
||||||
|
.SetFunctionName("followCurrentPlatformIfAny");
|
||||||
|
autConditions["PlatformBehavior::CanJump"].SetFunctionName("canJump");
|
||||||
autActions["PlatformBehavior::SimulateLeftKey"].SetFunctionName(
|
autActions["PlatformBehavior::SimulateLeftKey"].SetFunctionName(
|
||||||
"simulateLeftKey");
|
"simulateLeftKey");
|
||||||
autActions["PlatformBehavior::SimulateRightKey"].SetFunctionName(
|
autActions["PlatformBehavior::SimulateRightKey"].SetFunctionName(
|
||||||
|
@@ -1592,6 +1592,17 @@ namespace gdjs {
|
|||||||
this._currentFallSpeed !== 0
|
this._currentFallSpeed !== 0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
followCurrentPlatformIfAny(): boolean {
|
||||||
|
let hasMoved = false;
|
||||||
|
if (this.isOnFloor()) {
|
||||||
|
const timeDelta = this.owner.getElapsedTime() / 1000;
|
||||||
|
const hasMovedX = this._onFloor.followCurrentPlatformOnX(timeDelta);
|
||||||
|
const hasMovedY = this._onFloor.followCurrentPlatformOnY(timeDelta);
|
||||||
|
hasMoved = hasMovedX || hasMovedY;
|
||||||
|
}
|
||||||
|
return hasMoved;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1666,6 +1677,11 @@ namespace gdjs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
beforeUpdatingObstacles(timeDelta: float) {
|
beforeUpdatingObstacles(timeDelta: float) {
|
||||||
|
this.followCurrentPlatformOnY(timeDelta);
|
||||||
|
}
|
||||||
|
|
||||||
|
followCurrentPlatformOnY(timeDelta: float): boolean {
|
||||||
|
let hasMoved = false;
|
||||||
const object = this._behavior.owner;
|
const object = this._behavior.owner;
|
||||||
//Stick the object to the floor if its height has changed.
|
//Stick the object to the floor if its height has changed.
|
||||||
if (this._oldHeight !== object.getHeight()) {
|
if (this._oldHeight !== object.getHeight()) {
|
||||||
@@ -1674,6 +1690,7 @@ namespace gdjs {
|
|||||||
object.getHeight() +
|
object.getHeight() +
|
||||||
(object.getY() - object.getDrawableY())
|
(object.getY() - object.getDrawableY())
|
||||||
);
|
);
|
||||||
|
hasMoved = true;
|
||||||
}
|
}
|
||||||
// Directly follow the floor movement on the Y axis by moving the character.
|
// Directly follow the floor movement on the Y axis by moving the character.
|
||||||
// For the X axis, we follow the floor movement using `_requestedDeltaX`
|
// For the X axis, we follow the floor movement using `_requestedDeltaX`
|
||||||
@@ -1694,14 +1711,18 @@ namespace gdjs {
|
|||||||
// and the platform can go out of the spatial search rectangle
|
// and the platform can go out of the spatial search rectangle
|
||||||
// even though they are next to each other, which means
|
// even though they are next to each other, which means
|
||||||
// that the character will fall.
|
// that the character will fall.
|
||||||
const deltaY = this._floorPlatform!.owner.getY() - this._floorLastY;
|
const floorY = this._floorPlatform!.owner.getY();
|
||||||
|
const deltaY = floorY - this._floorLastY;
|
||||||
if (
|
if (
|
||||||
deltaY !== 0 &&
|
deltaY !== 0 &&
|
||||||
Math.abs(deltaY) <=
|
Math.abs(deltaY) <=
|
||||||
Math.abs(this._behavior._maxFallingSpeed * timeDelta)
|
Math.abs(this._behavior._maxFallingSpeed * timeDelta)
|
||||||
) {
|
) {
|
||||||
object.setY(object.getY() + deltaY);
|
object.setY(object.getY() + deltaY);
|
||||||
|
this._floorLastY = floorY;
|
||||||
|
hasMoved = true;
|
||||||
}
|
}
|
||||||
|
return hasMoved;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkTransitionBeforeX() {
|
checkTransitionBeforeX() {
|
||||||
@@ -1739,11 +1760,29 @@ namespace gdjs {
|
|||||||
beforeMovingX() {
|
beforeMovingX() {
|
||||||
const behavior = this._behavior;
|
const behavior = this._behavior;
|
||||||
// Shift the object according to the floor movement.
|
// Shift the object according to the floor movement.
|
||||||
behavior._requestedDeltaX +=
|
const floorX = this._floorPlatform!.owner.getX();
|
||||||
this._floorPlatform!.owner.getX() - this._floorLastX;
|
const deltaX = floorX - this._floorLastX;
|
||||||
|
behavior._requestedDeltaX += deltaX;
|
||||||
|
this._floorLastX = floorX;
|
||||||
// See `beforeUpdatingObstacles` for the logic for the Y axis.
|
// See `beforeUpdatingObstacles` for the logic for the Y axis.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
followCurrentPlatformOnX(timeDelta: float): boolean {
|
||||||
|
let hasMoved = false;
|
||||||
|
const object = this._behavior.owner;
|
||||||
|
|
||||||
|
// Shift the object according to the floor movement.
|
||||||
|
const floorX = this._floorPlatform!.owner.getX();
|
||||||
|
const deltaX = floorX - this._floorLastX;
|
||||||
|
if (deltaX !== 0) {
|
||||||
|
console.log(deltaX);
|
||||||
|
object.setX(object.getX() + deltaX);
|
||||||
|
this._floorLastX = floorX;
|
||||||
|
hasMoved = true;
|
||||||
|
}
|
||||||
|
return hasMoved;
|
||||||
|
}
|
||||||
|
|
||||||
checkTransitionBeforeY(timeDelta: float) {
|
checkTransitionBeforeY(timeDelta: float) {
|
||||||
const behavior = this._behavior;
|
const behavior = this._behavior;
|
||||||
// Go on a ladder
|
// Go on a ladder
|
||||||
|
@@ -694,7 +694,7 @@ describe('gdjs.PlatformerObjectRuntimeBehavior', function () {
|
|||||||
expect(object.getBehavior('auto1').isFalling()).to.be(false);
|
expect(object.getBehavior('auto1').isFalling()).to.be(false);
|
||||||
expect(object.getBehavior('auto1').isOnFloor()).to.be(true);
|
expect(object.getBehavior('auto1').isOnFloor()).to.be(true);
|
||||||
expect(object.getY()).to.be.within(140.6297999, 140.6298001);
|
expect(object.getY()).to.be.within(140.6297999, 140.6298001);
|
||||||
// TODO Remove the 1-frame delay
|
// The floor following has a 1-frame delay.
|
||||||
expect(object.getX()).to.be(5);
|
expect(object.getX()).to.be(5);
|
||||||
runtimeScene.renderAndStep(1000 / 60);
|
runtimeScene.renderAndStep(1000 / 60);
|
||||||
expect(object.getX()).to.be(6);
|
expect(object.getX()).to.be(6);
|
||||||
|
@@ -68,7 +68,7 @@ describe('gdjs.PlatformerObjectRuntimeBehavior', function () {
|
|||||||
runtimeScene.renderAndStepWithEventsFunction(1000 / 60, () => {
|
runtimeScene.renderAndStepWithEventsFunction(1000 / 60, () => {
|
||||||
platform.setX(platform.getX() + 0.12);
|
platform.setX(platform.getX() + 0.12);
|
||||||
});
|
});
|
||||||
// TODO Remove the 1-frame delay
|
// The floor following has a 1-frame delay.
|
||||||
expect(object.getX()).to.be(0.24);
|
expect(object.getX()).to.be(0.24);
|
||||||
runtimeScene.renderAndStep(1000 / 60);
|
runtimeScene.renderAndStep(1000 / 60);
|
||||||
expect(object.getX()).to.be(0.36);
|
expect(object.getX()).to.be(0.36);
|
||||||
@@ -258,13 +258,13 @@ describe('gdjs.PlatformerObjectRuntimeBehavior', function () {
|
|||||||
// The object follow the platform
|
// The object follow the platform
|
||||||
// The rounding error is probably due to a separate call.
|
// The rounding error is probably due to a separate call.
|
||||||
// TODO Try to make it exact or find why
|
// TODO Try to make it exact or find why
|
||||||
// TODO Remove the 1-frame delay
|
// The floor following has a 1-frame delay.
|
||||||
expect(object.getY()).to.be.within(
|
expect(object.getY()).to.be.within(
|
||||||
previousPlatformY - object.getHeight() - epsilon,
|
previousPlatformY - object.getHeight() - epsilon,
|
||||||
previousPlatformY - object.getHeight() + epsilon
|
previousPlatformY - object.getHeight() + epsilon
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// TODO Remove the 1-frame delay
|
// The floor following has a 1-frame delay.
|
||||||
expect(object.getX()).to.be(0 + 4 * deltaX);
|
expect(object.getX()).to.be(0 + 4 * deltaX);
|
||||||
runtimeScene.renderAndStep(1000 / 60);
|
runtimeScene.renderAndStep(1000 / 60);
|
||||||
expect(object.getX()).to.be(0 + 5 * deltaX);
|
expect(object.getX()).to.be(0 + 5 * deltaX);
|
||||||
@@ -400,13 +400,13 @@ describe('gdjs.PlatformerObjectRuntimeBehavior', function () {
|
|||||||
expect(object.getBehavior('auto1').isFalling()).to.be(false);
|
expect(object.getBehavior('auto1').isFalling()).to.be(false);
|
||||||
expect(object.getBehavior('auto1').isMoving()).to.be(false);
|
expect(object.getBehavior('auto1').isMoving()).to.be(false);
|
||||||
// The object must not be inside the platform or it gets stuck
|
// The object must not be inside the platform or it gets stuck
|
||||||
// TODO Remove the 1-frame delay
|
// The floor following has a 1-frame delay.
|
||||||
expect(object.getY()).to.be.within(
|
expect(object.getY()).to.be.within(
|
||||||
previousPlatformY - object.getHeight() - epsilon,
|
previousPlatformY - object.getHeight() - epsilon,
|
||||||
previousPlatformY - object.getHeight() + epsilon
|
previousPlatformY - object.getHeight() + epsilon
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// TODO Remove the 1-frame delay
|
// The floor following has a 1-frame delay.
|
||||||
expect(object.getX()).to.be(0 + 4 * deltaX);
|
expect(object.getX()).to.be(0 + 4 * deltaX);
|
||||||
runtimeScene.renderAndStep(1000 / 60);
|
runtimeScene.renderAndStep(1000 / 60);
|
||||||
expect(object.getX()).to.be(0 + 5 * deltaX);
|
expect(object.getX()).to.be(0 + 5 * deltaX);
|
||||||
|
Reference in New Issue
Block a user