Skip to content

Add new expressions #2558

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Apr 25, 2021
28 changes: 26 additions & 2 deletions Core/GDCore/Extensions/Builtin/BaseObjectExtension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -998,17 +998,41 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsBaseObjectExtension(
_("Angle between two objects"),
_("Compute the angle between two objects. If you need the "
"angle to an arbitrary position, use AngleToPosition."),
_("Position"),
_("Angle"),
"res/actions/position.png")
.AddParameter("object", _("Object"))
.AddParameter("objectPtr", _("Object"));

obj.AddExpression("XFromAngleAndDistance",
_("X position from angle and distance"),
_("Compute the X position when given an angle and distance "
"relative to the starting object. This is also known as "
"getting the cartesian coordinates of a 2D vector, using "
"its polar coordinates."),
_("Position"),
"res/actions/position.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Distance"));

obj.AddExpression("YFromAngleAndDistance",
_("Y position from angle and distance"),
_("Compute the Y position when given an angle and distance "
"relative to the starting object. This is also known as "
"getting the cartesian coordinates of a 2D vector, using "
"its polar coordinates."),
_("Position"),
"res/actions/position.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Distance"));

obj.AddExpression("AngleToPosition",
_("Angle between an object and a position"),
_("Compute the angle between the object center and a "
"\"target\" position. If you need the angle between two "
"objects, use AngleToObject."),
_("Position"),
_("Angle"),
"res/actions/position.png")
.AddParameter("object", _("Object"))
.AddParameter("expression", _("Target X position"))
Expand Down
24 changes: 24 additions & 0 deletions Core/GDCore/Extensions/Builtin/MathematicalToolsExtension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,30 @@ BuiltinExtensionsImplementer::ImplementsMathematicalToolsExtension(
.AddParameter("expression", _("b (in a+(b-a)*x)"))
.AddParameter("expression", _("x (in a+(b-a)*x)"));

extension
.AddExpression("XFromAngleAndDistance",
_("X position from angle and distance"),
_("Compute the X position when given an angle and distance "
"relative to the origin (0;0). This is also known as "
"getting the cartesian coordinates of a 2D vector, using "
"its polar coordinates."),
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Distance"));

extension
.AddExpression("YFromAngleAndDistance",
_("Y position from angle and distance"),
_("Compute the Y position when given an angle and distance "
"relative to the origin (0;0). This is also known as "
"getting the cartesian coordinates of a 2D vector, using "
"its polar coordinates."),
_("Mathematical tools"),
"res/mathfunction.png")
.AddParameter("expression", _("Angle, in degrees"))
.AddParameter("expression", _("Distance"));

#endif
}

Expand Down
2 changes: 2 additions & 0 deletions GDJS/GDJS/Extensions/Builtin/BaseObjectExtension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,8 @@ BaseObjectExtension::BaseObjectExtension() {
"getTimerElapsedTimeInSeconds");
objectStrExpressions["ObjectName"].SetFunctionName("getName");
objectStrExpressions["Layer"].SetFunctionName("getLayer");
objectExpressions["XFromAngleAndDistance"].SetFunctionName("getXFromAngleAndDistance");
objectExpressions["YFromAngleAndDistance"].SetFunctionName("getYFromAngleAndDistance");

GetAllActions()["Create"].SetFunctionName(
"gdjs.evtTools.object.createObjectOnScene");
Expand Down
2 changes: 2 additions & 0 deletions GDJS/GDJS/Extensions/Builtin/MathematicalToolsExtension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ MathematicalToolsExtension::MathematicalToolsExtension() {
GetAllExpressions()["round"].SetFunctionName("Math.round");
GetAllExpressions()["trunc"].SetFunctionName("gdjs.evtTools.common.trunc");
GetAllExpressions()["lerp"].SetFunctionName("gdjs.evtTools.common.lerp");
GetAllExpressions()["XFromAngleAndDistance"].SetFunctionName("gdjs.evtTools.common.getXFromAngleAndDistance");
GetAllExpressions()["YFromAngleAndDistance"].SetFunctionName("gdjs.evtTools.common.getYFromAngleAndDistance");

StripUnimplementedInstructionsAndExpressions();
}
Expand Down
26 changes: 26 additions & 0 deletions GDJS/Runtime/events-tools/commontools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,32 @@ namespace gdjs {
export const trunc = function (x: float): number {
return x | 0;
};

/**
* Compute the X position when given an angle and distance relative to the origin (0;0).
* This is also known as getting the cartesian coordinates of a 2D vector, using its polar coordinates.
* @param angle The angle, in degrees.
* @param distance The distance from the object, in pixels.
*/
export const getXFromAngleAndDistance = function (
angle: float,
distance: float
): number {
return distance * Math.cos(gdjs.toRad(angle));
};

/**
* Compute the Y position when given an angle and distance relative to the origin (0;0).
* This is also known as getting the cartesian coordinates of a 2D vector, using its polar coordinates.
* @param angle The angle, in degrees.
* @param distance The distance from the object, in pixels.
*/
export const getYFromAngleAndDistance = function (
angle: float,
distance: float
): number {
return distance * Math.sin(gdjs.toRad(angle));
};
}
}
}
60 changes: 44 additions & 16 deletions GDJS/Runtime/runtimeobject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -395,12 +395,12 @@ namespace gdjs {
scene: gdjs.RuntimeScene
): void {
this.rotateTowardAngle(
(Math.atan2(
y - (this.getDrawableY() + this.getCenterY()),
x - (this.getDrawableX() + this.getCenterX())
) *
180) /
Math.PI,
gdjs.toDegrees(
Math.atan2(
y - (this.getDrawableY() + this.getCenterY()),
x - (this.getDrawableX() + this.getCenterX())
)
),
speed,
scene
);
Expand Down Expand Up @@ -848,7 +848,7 @@ namespace gdjs {
* @param multiplier Set the force multiplier
*/
addPolarForce(angle: float, len: float, multiplier: integer): void {
const angleInRadians = (angle / 180) * 3.14159;
const angleInRadians = gdjs.toRad(angle);

//TODO: Benchmark with Math.PI
const forceX = Math.cos(angleInRadians) * len;
Expand All @@ -869,12 +869,12 @@ namespace gdjs {
len: float,
multiplier: integer
): void {
const angle = Math.atan2(
const angleInRadians = Math.atan2(
y - (this.getDrawableY() + this.getCenterY()),
x - (this.getDrawableX() + this.getCenterX())
);
const forceX = Math.cos(angle) * len;
const forceY = Math.sin(angle) * len;
const forceX = Math.cos(angleInRadians) * len;
const forceY = Math.sin(angleInRadians) * len;
this._forces.push(this._getRecycledForce(forceX, forceY, multiplier));
}

Expand Down Expand Up @@ -1043,7 +1043,7 @@ namespace gdjs {
this.hitBoxes[0].vertices[3][0] = 0 - centerX;
this.hitBoxes[0].vertices[3][1] = height - centerY;
}
this.hitBoxes[0].rotate((this.getAngle() / 180) * Math.PI);
this.hitBoxes[0].rotate(gdjs.toRad(this.getAngle()));
this.hitBoxes[0].move(
this.getDrawableX() + centerX,
this.getDrawableY() + centerY
Expand Down Expand Up @@ -1494,7 +1494,35 @@ namespace gdjs {
this.getDrawableY() +
this.getCenterY() -
(otherObject.getDrawableY() + otherObject.getCenterY());
return (Math.atan2(-y, -x) * 180) / Math.PI;
return gdjs.toDegrees(Math.atan2(-y, -x));
}

/**
* Compute the X position when given an angle and distance relative to the starting object.
* This is also known as getting the cartesian coordinates of a 2D vector, using its polar coordinates.
* @param angle The angle, in degrees.
* @param distance The distance from the object, in pixels
*/
getXFromAngleAndDistance(angle: float, distance: float): float {
return (
this.getDrawableX() +
this.getCenterX() +
distance * Math.cos(gdjs.toRad(angle))
);
}

/**
* Compute the Y position when given an angle and distance relative to the starting object.
* This is also known as getting the cartesian coordinates of a 2D vector, using its polar coordinates.
* @param angle The angle, in degrees.
* @param distance The distance from the object, in pixels
*/
getYFromAngleAndDistance(angle: float, distance: float): float {
return (
this.getDrawableY() +
this.getCenterY() +
distance * Math.sin(gdjs.toRad(angle))
);
}

/**
Expand All @@ -1505,7 +1533,7 @@ namespace gdjs {
getAngleToPosition(targetX: float, targetY: float): float {
const x = this.getDrawableX() + this.getCenterX() - targetX;
const y = this.getDrawableY() + this.getCenterY() - targetY;
return (Math.atan2(-y, -x) * 180) / Math.PI;
return gdjs.toDegrees(Math.atan2(-y, -x));
}

/**
Expand All @@ -1523,19 +1551,19 @@ namespace gdjs {
distance: float,
angleInDegrees: float
): void {
const angle = (angleInDegrees / 180) * 3.14159;
const angleInRadians = gdjs.toRad(angleInDegrees);

// Offset the position by the center, as PutAround* methods should position the center
// of the object (just like GetSqDistanceTo, RaycastTest uses center too).
this.setX(
x +
Math.cos(angle) * distance +
Math.cos(angleInRadians) * distance +
this.getX() -
(this.getDrawableX() + this.getCenterX())
);
this.setY(
y +
Math.sin(angle) * distance +
Math.sin(angleInRadians) * distance +
this.getY() -
(this.getDrawableY() + this.getCenterY())
);
Expand Down