Files
GDevelop/Extensions/TweenBehavior/tests/LegacyTweenBehavior.spec.js
Florian Rival 5eeb505807 Fix tests
Don't show in changelog
2025-08-08 11:36:33 +02:00

538 lines
14 KiB
JavaScript

// @ts-check
describe('gdjs.TweenRuntimeBehavior', () => {
const behaviorName = 'Tween';
const createScene = (timeDelta = 1000 / 60) => {
const runtimeGame = gdjs.getPixiRuntimeGame();
const runtimeScene = new gdjs.TestRuntimeScene(runtimeGame);
runtimeScene._timeManager.getElapsedTime = () => {
return timeDelta;
};
return runtimeScene;
};
/**
* @param {gdjs.RuntimeScene} runtimeScene
* @returns {gdjs.TestRuntimeObject}
*/
const addObject = (runtimeScene) => {
const object = new gdjs.TestRuntimeObject(runtimeScene, {
name: 'Object',
type: '',
effects: [],
variables: [],
behaviors: [
{
type: 'Tween::TweenBehavior',
name: behaviorName,
},
],
});
runtimeScene.addObject(object);
return object;
};
/**
* @param {gdjs.RuntimeScene} runtimeScene
*/
const addSprite = (runtimeScene) => {
const object = new gdjs.SpriteRuntimeObject(runtimeScene, {
name: 'Sprite',
type: 'Sprite',
effects: [],
variables: [],
behaviors: [
{
type: 'Tween::TweenBehavior',
name: behaviorName,
},
],
animations: [
{
name: 'animation',
directions: [
{
sprites: [
{
originPoint: { name: 'Center', x: 0, y: 0 },
centerPoint: {
name: 'Origin',
automatic: false,
x: 32,
y: 32,
},
points: [
{ name: 'Center', x: 0, y: 0 },
{ name: 'Origin', x: 32, y: 32 },
],
hasCustomCollisionMask: false,
customCollisionMask: [],
image: '',
},
],
timeBetweenFrames: 0,
looping: false,
},
],
useMultipleDirections: false,
},
],
updateIfNotVisible: true,
});
object.getWidth = () => 64;
object.getHeight = () => 64;
runtimeScene.addObject(object);
return object;
};
/**
* @param {gdjs.RuntimeScene} runtimeScene
*/
const addCube = (runtimeScene) => {
const object = new gdjs.Cube3DRuntimeObject(runtimeScene, {
name: 'Cube',
type: 'Scene3D::Cube3DObject',
effects: [],
variables: [],
behaviors: [
{
type: 'Tween::TweenBehavior',
name: behaviorName,
},
],
// @ts-ignore
content: {
width: 64,
height: 64,
depth: 64,
},
});
runtimeScene.addObject(object);
return object;
};
/**
* @param {gdjs.RuntimeScene} runtimeScene
*/
const addTextObject = (runtimeScene) => {
const object = new gdjs.TextRuntimeObject(runtimeScene, {
name: 'Text',
type: 'TextObject::Text',
effects: [],
variables: [],
behaviors: [
{
type: 'Tween::TweenBehavior',
name: behaviorName,
},
],
content: {
characterSize: 20,
font: '',
bold: false,
italic: false,
underlined: false,
color: '0;0;0',
text: '',
textAlignment: 'left',
verticalTextAlignment: 'top',
isOutlineEnabled: false,
outlineThickness: 2,
outlineColor: '255;255;255',
isShadowEnabled: false,
shadowColor: '0;0;0',
shadowOpacity: 128,
shadowDistance: 4,
shadowAngle: 90,
shadowBlurRadius: 2,
lineHeight: 0,
},
});
runtimeScene.addObject(object);
return object;
};
/** @type {gdjs.RuntimeScene} */
let runtimeScene;
/** @type {gdjs.RuntimeObject} */
let object;
/** @type {gdjs.SpriteRuntimeObject} */
let sprite;
/** @type {gdjs.Cube3DRuntimeObject} */
let cube;
/** @type {gdjs.TextRuntimeObject} */
let textObject;
/** @type {gdjs.TweenRuntimeBehavior} */
let behavior;
/** @type {gdjs.TweenRuntimeBehavior} */
let spriteBehavior;
/** @type {gdjs.TweenRuntimeBehavior} */
let cubeBehavior;
/** @type {gdjs.TweenRuntimeBehavior} */
let textObjectBehavior;
beforeEach(() => {
runtimeScene = createScene();
runtimeScene.getLayer('').setTimeScale(1.5);
object = addObject(runtimeScene);
sprite = addSprite(runtimeScene);
cube = addCube(runtimeScene);
textObject = addTextObject(runtimeScene);
//@ts-ignore
behavior = object.getBehavior(behaviorName);
//@ts-ignore
spriteBehavior = sprite.getBehavior(behaviorName);
//@ts-ignore
cubeBehavior = cube.getBehavior(behaviorName);
//@ts-ignore
textObjectBehavior = textObject.getBehavior(behaviorName);
});
const checkProgress = (steps, getValueFunctions) => {
if (!Array.isArray(getValueFunctions)) {
getValueFunctions = [getValueFunctions];
}
for (let i = 0; i < steps; i++) {
const oldValues = getValueFunctions.map((getValue) => getValue());
runtimeScene.renderAndStep(1000 / 60);
for (let index = 0; index < oldValues.length; index++) {
expect(getValueFunctions[index]()).not.to.be(oldValues[index]);
}
}
};
it('can tween an object variable', () => {
const variable = object.getVariables().get('MyVariable');
variable.setNumber(200);
behavior.addVariableTween2(
'MyTween',
variable,
600,
'linear',
250 / 1.5,
false
);
checkProgress(6, () => variable.getAsNumber());
expect(variable.getAsNumber()).to.be(440);
});
it('can tween an object variable (older action)', () => {
const variable = object.getVariables().get('MyVariable');
variable.setNumber(200);
behavior.addVariableTween(
'MyTween',
variable,
200,
600,
'linear',
250 / 1.5,
false
);
checkProgress(6, () => variable.getAsNumber());
expect(variable.getAsNumber()).to.be(440);
});
it('can tween the position on X axis', () => {
object.setX(200);
behavior.addObjectPositionXTween(
'MyTween',
600,
'linear',
250 / 1.5,
false
);
checkProgress(6, () => object.getX());
expect(object.getX()).to.be(440);
});
it('can tween the position on Y axis', () => {
object.setY(200);
behavior.addObjectPositionYTween(
'MyTween',
600,
'linear',
250 / 1.5,
false
);
checkProgress(6, () => object.getY());
expect(object.getY()).to.be(440);
});
it('can tween the position on Z axis', () => {
cube.setZ(200);
cubeBehavior.addObjectPositionZTween(
'MyTween',
600,
'linear',
250 / 1.5,
false
);
checkProgress(6, () => cube.getZ());
expect(cube.getZ()).to.be(440);
});
it('can tween the angle', () => {
object.setAngle(200);
behavior.addObjectAngleTween('MyTween', 600, 'linear', 250 / 1.5, false);
checkProgress(6, () => object.getAngle());
expect(object.getAngle()).to.be(440);
});
it('can tween the width', () => {
object.setWidth(200);
behavior.addObjectWidthTween('MyTween', 600, 'linear', 250 / 1.5, false);
checkProgress(6, () => object.getWidth());
expect(object.getWidth()).to.be(440);
});
it('can tween the height', () => {
object.setHeight(200);
behavior.addObjectHeightTween('MyTween', 600, 'linear', 250 / 1.5, false);
checkProgress(6, () => object.getHeight());
expect(object.getHeight()).to.be(440);
});
it('can tween the depth', () => {
cube.setDepth(200);
cubeBehavior.addObjectDepthTween(
'MyTween',
600,
'linear',
250 / 1.5,
false
);
checkProgress(6, () => cube.getDepth());
expect(cube.getDepth()).to.be(440);
});
it('can tween the opacity', () => {
sprite.setOpacity(128);
spriteBehavior.addObjectOpacityTween(
'MyTween',
255,
'linear',
250 / 1.5,
false
);
checkProgress(6, () => sprite.getOpacity());
expect(sprite.getOpacity()).to.be(204.2);
});
it('can tween the color', () => {
sprite.setColor('16;32;64');
spriteBehavior.addObjectColorTween(
'MyTween',
'255;192;128',
'linear',
250 / 1.5,
false,
true
);
checkProgress(6, () => sprite.getColor());
// Colors are rounded by the tween.
expect(sprite.getColor()).to.be('76;235;27');
});
it('can tween the color to HSL', () => {
sprite.setColor('16;32;64');
spriteBehavior.addObjectColorHSLTween(
'MyTween',
180,
true,
25,
50,
'linear',
250 / 1.5,
false
);
checkProgress(6, () => sprite.getColor());
// Colors are rounded by the tween.
expect(sprite.getColor()).to.be('57;110;129');
});
it('can tween the scale on X axis', () => {
sprite.setPosition(100, 400);
sprite.setScaleX(200);
spriteBehavior.addObjectScaleXTween(
'MyTween',
600,
'linear',
250 / 1.5,
false,
false
);
checkProgress(6, () => sprite.getScaleX());
// The interpolation was not exponential.
expect(sprite.getScaleX()).to.be(440);
expect(sprite.getX()).to.be(100);
expect(sprite.getY()).to.be(400);
});
it('can tween the scale on X axis from center', () => {
sprite.setPosition(100, 400);
sprite.setScaleX(200);
spriteBehavior.addObjectScaleXTween(
'MyTween',
600,
'linear',
250 / 1.5,
false,
true
);
checkProgress(6, () => sprite.getScaleX());
// The interpolation was not exponential.
expect(sprite.getScaleX()).to.be(440);
expect(sprite.getX()).to.be(-7580);
expect(sprite.getY()).to.be(400);
});
it('can tween the scale on Y axis', () => {
sprite.setPosition(100, 400);
sprite.setScaleY(200);
spriteBehavior.addObjectScaleYTween(
'MyTween',
600,
'linear',
250 / 1.5,
false,
false
);
checkProgress(6, () => sprite.getScaleY());
// The interpolation was not exponential.
expect(sprite.getScaleY()).to.be(440);
expect(sprite.getX()).to.be(100);
expect(sprite.getY()).to.be(400);
});
it('can tween the scale on Y axis from center', () => {
sprite.setPosition(100, 400);
sprite.setScaleY(200);
spriteBehavior.addObjectScaleYTween(
'MyTween',
600,
'linear',
250 / 1.5,
false,
true
);
checkProgress(6, () => sprite.getScaleY());
// The interpolation was not exponential.
expect(sprite.getScaleY()).to.be(440);
expect(sprite.getX()).to.be(100);
expect(sprite.getY()).to.be(-7280);
});
it('can tween the font size', () => {
textObject.setCharacterSize(200);
textObjectBehavior.addTextObjectCharacterSizeTween(
'MyTween',
600,
'linear',
250 / 1.5,
false
);
checkProgress(6, () => textObject.getCharacterSize());
// The interpolation was not exponential.
expect(textObject.getCharacterSize()).to.be(440);
});
it('can tween the position', () => {
object.setPosition(200, 300);
behavior.addObjectPositionTween(
'MyTween',
600,
900,
'linear',
250 / 1.5,
false
);
checkProgress(6, [() => object.getX(), () => object.getY()]);
expect(object.getX()).to.be(440);
expect(object.getY()).to.be(660);
});
it('can tween the scales', () => {
sprite.setPosition(100, 400);
sprite.setScaleX(200);
sprite.setScaleY(300);
spriteBehavior.addObjectScaleTween(
'MyTween',
600,
900,
'linear',
250 / 1.5,
false,
false
);
checkProgress(6, [() => sprite.getScaleX(), () => sprite.getScaleY()]);
// The interpolation was not exponential.
expect(sprite.getScaleX()).to.be(440);
expect(sprite.getScaleY()).to.be(660);
expect(sprite.getX()).to.be(100);
expect(sprite.getY()).to.be(400);
});
it('can tween the scales from center', () => {
sprite.setPosition(100, 400);
sprite.setScaleX(200);
sprite.setScaleY(300);
spriteBehavior.addObjectScaleTween(
'MyTween',
600,
900,
'linear',
250 / 1.5,
false,
true
);
checkProgress(6, [() => sprite.getScaleX(), () => sprite.getScaleY()]);
// The interpolation was not exponential.
expect(sprite.getScaleX()).to.be(440);
expect(sprite.getScaleY()).to.be(660);
expect(sprite.getX()).to.be(-7580);
expect(sprite.getY()).to.be(-11120);
});
it('can tween the scales in seconds', () => {
sprite.setPosition(100, 400);
sprite.setScaleX(200);
sprite.setScaleY(300);
spriteBehavior.addObjectScaleTween2(
'MyTween',
600,
900,
'linear',
0.25,
false,
false
);
checkProgress(6, [() => sprite.getScaleX(), () => sprite.getScaleY()]);
// The interpolation is exponential.
expect(sprite.getScaleX()).to.be(386.6364089863524);
expect(sprite.getScaleY()).to.be(579.9546134795287);
expect(sprite.getX()).to.be(100);
expect(sprite.getY()).to.be(400);
});
it('can tween the scales from center in seconds', () => {
sprite.setPosition(100, 400);
sprite.setScaleX(200);
sprite.setScaleY(300);
spriteBehavior.addObjectScaleTween2(
'MyTween',
600,
900,
'linear',
0.25,
false,
true
);
checkProgress(6, [() => sprite.getScaleX(), () => sprite.getScaleY()]);
// The interpolation is exponential.
expect(sprite.getScaleX()).to.be(386.6364089863524);
expect(sprite.getScaleY()).to.be(579.9546134795287);
expect(sprite.getX()).to.be(-5872.3650875632775);
expect(sprite.getY()).to.be(-8558.547631344918);
});
});