Add animation time control for sprites and 3D models (#5777)

This commit is contained in:
D8H
2023-10-17 10:02:49 +02:00
committed by GitHub
parent 787274f7fa
commit 95a9e37aba
56 changed files with 17143 additions and 26 deletions
@@ -23,6 +23,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAnimatableExtension(
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects");
extension.AddInstructionOrExpressionGroupMetadata(_("Animatable capability"))
.SetIcon("res/actions/animation24.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Animations and images"))
.SetIcon("res/actions/animation24.png");
@@ -53,6 +55,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAnimatableExtension(
"number", gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Animation index")))
.MarkAsSimple();
aut.GetAllExpressions()["Index"].SetGroup("");
aut.AddExpressionAndConditionAndAction(
"string",
@@ -69,6 +72,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAnimatableExtension(
"objectAnimationName", gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Animation name")))
.MarkAsSimple();
aut.GetAllStrExpressions()["Name"].SetGroup("");
aut.AddScopedAction("PauseAnimation",
_("Pause the animation"),
@@ -107,6 +111,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAnimatableExtension(
"number", gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Speed scale")))
.MarkAsSimple();
aut.GetAllExpressions()["SpeedScale"].SetGroup("");
aut.AddScopedCondition("IsAnimationPaused",
_("Animation paused"),
@@ -130,6 +135,31 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsAnimatableExtension(
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
.MarkAsSimple();
aut.AddExpressionAndConditionAndAction(
"number",
"ElapsedTime",
_("Animation elapsed time"),
_("the elapsed time from the beginning of the animation (in seconds)"),
_("the animation elapsed time"),
_("Animations and images"),
"res/actions/animation24.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior")
.UseStandardParameters(
"number", gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Elapsed time (in seconds)")))
.MarkAsAdvanced();
aut.GetAllExpressions()["ElapsedTime"].SetGroup("");
aut.AddExpression(
"Duration",
_("Animation duration"),
_("Return the current animation duration (in seconds)."),
_("Animations and images"),
"res/actions/animation24.png")
.AddParameter("object", _("Object"))
.AddParameter("behavior", _("Behavior"), "AnimatableBehavior");
}
} // namespace gd
@@ -23,6 +23,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsOpacityExtension(
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects");
extension.AddInstructionOrExpressionGroupMetadata(_("Opacity capability"))
.SetIcon("res/actions/opacity24.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Visibility"))
.SetIcon("res/actions/opacity24.png");
@@ -54,6 +56,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsOpacityExtension(
_("Opacity (0-255)")))
.SetFunctionName("setOpacity")
.SetGetter("getOpacity");
aut.GetAllExpressions()["Value"].SetGroup("");
}
} // namespace gd
@@ -23,6 +23,8 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsScalableExtension(
"Florian Rival",
"Open source (MIT License)")
.SetExtensionHelpPath("/objects");
extension.AddInstructionOrExpressionGroupMetadata(_("Scalable capability"))
.SetIcon("res/actions/scale24_black.png");
extension.AddInstructionOrExpressionGroupMetadata(_("Size"))
.SetIcon("res/actions/scale24_black.png");
@@ -53,6 +55,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsScalableExtension(
gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Scale (1 by default)")))
.MarkAsAdvanced();
aut.GetAllExpressions()["Value"].SetGroup("");
aut.AddExpressionAndConditionAndAction(
"number",
@@ -69,6 +72,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsScalableExtension(
gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Scale (1 by default)")))
.MarkAsAdvanced();
aut.GetAllExpressions()["X"].SetGroup("");
aut.AddExpressionAndConditionAndAction(
"number",
@@ -85,6 +89,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsScalableExtension(
gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Scale (1 by default)")))
.MarkAsAdvanced();
aut.GetAllExpressions()["Y"].SetGroup("");
}
} // namespace gd
@@ -52,6 +52,7 @@ void GD_CORE_API BuiltinExtensionsImplementer::ImplementsTextContainerExtension(
"string", gd::ParameterOptions::MakeNewOptions().SetDescription(
_("Text")))
.MarkAsSimple();
aut.GetAllStrExpressions()["Value"].SetGroup("");
}
} // namespace gd
+19 -2
View File
@@ -221,6 +221,9 @@ namespace gdjs {
const animation = this._animations[animationIndex];
this._currentAnimationIndex = animationIndex;
this._renderer.playAnimation(animation.source, animation.loop);
if (this._animationPaused) {
this._renderer.pauseAnimation();
}
}
}
@@ -272,12 +275,12 @@ namespace gdjs {
pauseAnimation() {
this._animationPaused = true;
return this._renderer.pauseAnimation();
this._renderer.pauseAnimation();
}
resumeAnimation() {
this._animationPaused = false;
return this._renderer.resumeAnimation();
this._renderer.resumeAnimation();
}
getAnimationSpeedScale() {
@@ -288,6 +291,20 @@ namespace gdjs {
this._animationSpeedScale = ratio;
}
getAnimationElapsedTime(): float {
return this._renderer.getAnimationElapsedTime();
}
setAnimationElapsedTime(time: float): void {
this._renderer.setAnimationElapsedTime(time);
}
getAnimationDuration(): float {
return this._renderer.getAnimationDuration(
this._animations[this._currentAnimationIndex].source
);
}
getCenterX(): float {
const centerPoint = this._renderer.getCenterPoint();
return this.getWidth() * centerPoint[0];
@@ -348,6 +348,24 @@ namespace gdjs {
// Make sure the first frame is displayed.
this._animationMixer.update(0);
}
getAnimationElapsedTime(): float {
return this._action ? this._action.time : 0;
}
setAnimationElapsedTime(time: float): void {
if (this._action) {
this._action.time = time;
}
}
getAnimationDuration(animationName: string): float {
const clip = THREE.AnimationClip.findByName(
this._originalModel.animations,
animationName
);
return clip ? clip.duration : 0;
}
}
export const Model3DRuntimeObjectRenderer = Model3DRuntimeObject3DRenderer;
@@ -67,6 +67,20 @@ AnimatableExtension::AnimatableExtension() {
conditions["AnimatableCapability::AnimatableBehavior::HasAnimationEnded"]
.SetFunctionName("hasAnimationEnded")
.SetIncludeFile("object-capabilities/AnimatableBehavior.js");
actions["AnimatableCapability::AnimatableBehavior::SetElapsedTime"]
.SetFunctionName("setAnimationElapsedTime")
.SetGetter("getAnimationElapsedTime")
.SetIncludeFile("object-capabilities/AnimatableBehavior.js");
conditions["AnimatableCapability::AnimatableBehavior::ElapsedTime"]
.SetFunctionName("getAnimationElapsedTime")
.SetIncludeFile("object-capabilities/AnimatableBehavior.js");
expressions["ElapsedTime"]
.SetFunctionName("getAnimationElapsedTime")
.SetIncludeFile("object-capabilities/AnimatableBehavior.js");
expressions["Duration"]
.SetFunctionName("getAnimationDuration")
.SetIncludeFile("object-capabilities/AnimatableBehavior.js");
}
} // namespace gdjs
@@ -49,6 +49,22 @@ namespace gdjs {
getAnimationSpeedScale(): float;
setAnimationSpeedScale(ratio: float): void;
/**
* @return The elapsed time from the start of the animation in seconds.
*/
getAnimationElapsedTime(): float;
/**
* Set the elapsed time from the start of the animation in seconds.
* @param time The time in seconds
*/
setAnimationElapsedTime(time: float): void;
/**
* @return The duration of the current animation in seconds.
*/
getAnimationDuration(): float;
}
/**
@@ -128,6 +144,18 @@ namespace gdjs {
setAnimationSpeedScale(ratio: float): void {
this.object.setAnimationSpeedScale(ratio);
}
getAnimationElapsedTime(): float {
return this.object.getAnimationElapsedTime();
}
setAnimationElapsedTime(time: float): void {
this.object.setAnimationElapsedTime(time);
}
getAnimationDuration(): float {
return this.object.getAnimationDuration();
}
}
gdjs.registerBehavior(
+45 -24
View File
@@ -475,40 +475,29 @@ namespace gdjs {
const direction = this._animations[this._currentAnimation].directions[
this._currentDirection
];
const oldFrame = this._currentFrame;
const animationDuration =
direction.frames.length * direction.timeBetweenFrames;
const animationDuration = this.getAnimationDuration();
if (
!this._animationPaused &&
(direction.loop || this._animationElapsedTime !== animationDuration) &&
direction.timeBetweenFrames
) {
const elapsedTime = this.getElapsedTime() / 1000;
this._animationElapsedTime += elapsedTime * this._animationSpeedScale;
if (direction.loop) {
this._animationElapsedTime = gdjs.evtTools.common.mod(
this._animationElapsedTime,
direction.frames.length * direction.timeBetweenFrames
);
} else {
this._animationElapsedTime = gdjs.evtTools.common.clamp(
this._animationElapsedTime,
0,
animationDuration
);
}
this._currentFrame = Math.min(
Math.floor(this._animationElapsedTime / direction.timeBetweenFrames),
direction.frames.length - 1
const animationElapsedTime =
this._animationElapsedTime +
(this.getElapsedTime() / 1000) * this._animationSpeedScale;
this.setAnimationElapsedTime(
direction.loop
? gdjs.evtTools.common.mod(animationElapsedTime, animationDuration)
: gdjs.evtTools.common.clamp(
animationElapsedTime,
0,
animationDuration
)
);
}
if (oldFrame !== this._currentFrame || this._animationFrameDirty) {
if (this._animationFrameDirty) {
this._updateAnimationFrame();
}
if (oldFrame !== this._currentFrame) {
this.invalidateHitboxes();
}
this._renderer.ensureUpToDate();
}
@@ -755,6 +744,38 @@ namespace gdjs {
return this._currentFrame;
}
getAnimationElapsedTime(): float {
return this._animationElapsedTime;
}
setAnimationElapsedTime(time: float): void {
const direction = this._animations[this._currentAnimation].directions[
this._currentDirection
];
this._animationElapsedTime = gdjs.evtTools.common.clamp(
time,
0,
this.getAnimationDuration()
);
const oldFrame = this._currentFrame;
this._currentFrame = Math.min(
Math.floor(this._animationElapsedTime / direction.timeBetweenFrames),
direction.frames.length - 1
);
if (oldFrame !== this._currentFrame) {
this._updateAnimationFrame();
this.invalidateHitboxes();
}
}
getAnimationDuration(): number {
const direction = this._animations[this._currentAnimation].directions[
this._currentDirection
];
return direction.frames.length * direction.timeBetweenFrames;
}
getAnimationFrameCount(): number {
if (this._currentAnimation >= this._animations.length) {
return 0;
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

File diff suppressed because it is too large Load Diff