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

941 lines
27 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);
});
it("can get default values for tweens that don't exist", () => {
expect(behavior.exists('MyTween')).to.be(false);
expect(behavior.getValue('MyTween')).to.be(0);
expect(behavior.getProgress('MyTween')).to.be(0);
expect(behavior.isPlaying('MyTween')).to.be(false);
expect(behavior.hasFinished('MyTween')).to.be(false);
});
it('can play a tween till the end', () => {
object.setPosition(200, 300);
behavior.addObjectPositionXTween2('MyTween', 600, 'linear', 0.25, false);
// Tween actions don't change the value directly.
expect(object.getX()).to.be(200);
expect(behavior.getValue('MyTween')).to.be(200);
expect(behavior.getProgress('MyTween')).to.be(0);
let oldX;
let oldValue;
let oldProgress;
for (let i = 0; i < 10; i++) {
oldX = object.getX();
oldValue = behavior.getValue('MyTween');
oldProgress = behavior.getProgress('MyTween');
runtimeScene.renderAndStep(1000 / 60);
expect(behavior.isPlaying('MyTween')).to.be(true);
expect(behavior.hasFinished('MyTween')).to.be(false);
expect(object.getX()).to.be.above(oldX);
expect(behavior.getValue('MyTween')).to.be.above(oldValue);
expect(behavior.getProgress('MyTween')).to.be.above(oldProgress);
}
// The tween reaches the end
runtimeScene.renderAndStep(1000 / 60);
expect(behavior.isPlaying('MyTween')).to.be(false);
expect(behavior.hasFinished('MyTween')).to.be(true);
expect(object.getX()).to.be(600);
expect(behavior.getValue('MyTween')).to.be(600);
expect(behavior.getProgress('MyTween')).to.be(1);
expect(runtimeScene.getInstancesCountOnScene('Object')).to.be(1);
// The value is not changed after the tween is finished
runtimeScene.renderAndStep(1000 / 60);
expect(behavior.isPlaying('MyTween')).to.be(false);
expect(behavior.hasFinished('MyTween')).to.be(true);
expect(object.getX()).to.be(600);
expect(behavior.getValue('MyTween')).to.be(600);
expect(behavior.getProgress('MyTween')).to.be(1);
// The value is not set to the targeted value over and over
// after the tween is finished.
object.setX(123);
runtimeScene.renderAndStep(1000 / 60);
expect(object.getX()).to.be(123);
});
it('can remove the object at the end', () => {
object.setPosition(200, 300);
behavior.addObjectPositionXTween2('MyTween', 600, 'linear', 0.25, true);
for (let i = 0; i < 9; i++) {
runtimeScene.renderAndStep(1000 / 60);
}
// The tween is near the end.
runtimeScene.renderAndStep(1000 / 60);
expect(behavior.isPlaying('MyTween')).to.be(true);
expect(behavior.hasFinished('MyTween')).to.be(false);
expect(object.getX()).to.be(600);
expect(runtimeScene.getInstancesCountOnScene('Object')).to.be(1);
runtimeScene.renderAndStep(1000 / 60);
expect(runtimeScene.getInstancesCountOnScene('Object')).to.be(0);
});
it('can pause and resume a tween', () => {
object.setPosition(200, 300);
behavior.addObjectPositionXTween2('MyTween', 600, 'linear', 0.25, false);
// The tween starts
for (let i = 0; i < 5; i++) {
runtimeScene.renderAndStep(1000 / 60);
expect(behavior.isPlaying('MyTween')).to.be(true);
expect(behavior.hasFinished('MyTween')).to.be(false);
}
expect(object.getX()).to.be(400);
// Pause the tween
behavior.pauseTween('MyTween');
expect(object.getX()).to.be(400);
for (let i = 0; i < 5; i++) {
runtimeScene.renderAndStep(1000 / 60);
expect(behavior.isPlaying('MyTween')).to.be(false);
expect(behavior.hasFinished('MyTween')).to.be(false);
expect(object.getX()).to.be(400);
}
// The value is not overridden during the pause.
object.setX(123);
runtimeScene.renderAndStep(1000 / 60);
expect(object.getX()).to.be(123);
// Resume the tween
behavior.resumeTween('MyTween');
// Tween actions don't change the value directly.
expect(object.getX()).to.be(123);
expect(behavior.isPlaying('MyTween')).to.be(true);
expect(behavior.hasFinished('MyTween')).to.be(false);
runtimeScene.renderAndStep(1000 / 60);
expect(object.getX()).to.be(440);
});
it('can stop and restart a tween', () => {
object.setPosition(200, 300);
// Start the tween
behavior.addObjectPositionXTween2('MyTween', 600, 'linear', 0.25, false);
for (let i = 0; i < 5; i++) {
runtimeScene.renderAndStep(1000 / 60);
expect(behavior.isPlaying('MyTween')).to.be(true);
expect(behavior.hasFinished('MyTween')).to.be(false);
}
expect(object.getX()).to.be(400);
// Stop the tween
behavior.stopTween('MyTween', false);
expect(object.getX()).to.be(400);
for (let i = 0; i < 5; i++) {
runtimeScene.renderAndStep(1000 / 60);
expect(behavior.isPlaying('MyTween')).to.be(false);
expect(behavior.hasFinished('MyTween')).to.be(true);
expect(object.getX()).to.be(400);
}
// The value is not overridden by a stopped tween.
object.setX(123);
runtimeScene.renderAndStep(1000 / 60);
expect(object.getX()).to.be(123);
// A stopped tween can't be resumed.
behavior.resumeTween('MyTween');
expect(behavior.isPlaying('MyTween')).to.be(false);
expect(behavior.hasFinished('MyTween')).to.be(true);
expect(object.getX()).to.be(123);
runtimeScene.renderAndStep(1000 / 60);
expect(object.getX()).to.be(123);
expect(behavior.isPlaying('MyTween')).to.be(false);
expect(behavior.hasFinished('MyTween')).to.be(true);
// Restart the tween
behavior.addObjectPositionXTween2('MyTween', 623, 'linear', 0.25, false);
for (let i = 0; i < 5; i++) {
runtimeScene.renderAndStep(1000 / 60);
expect(behavior.isPlaying('MyTween')).to.be(true);
expect(behavior.hasFinished('MyTween')).to.be(false);
}
expect(object.getX()).to.be(373);
});
it('can remove and recreate a tween', () => {
object.setPosition(200, 300);
// Start the tween
expect(behavior.exists('MyTween')).to.be(false);
behavior.addObjectPositionXTween2('MyTween', 600, 'linear', 0.25, false);
expect(behavior.exists('MyTween')).to.be(true);
for (let i = 0; i < 5; i++) {
runtimeScene.renderAndStep(1000 / 60);
expect(behavior.isPlaying('MyTween')).to.be(true);
expect(behavior.hasFinished('MyTween')).to.be(false);
}
expect(object.getX()).to.be(400);
// Remove the tween
expect(behavior.exists('MyTween')).to.be(true);
behavior.removeTween('MyTween');
expect(behavior.exists('MyTween')).to.be(false);
expect(object.getX()).to.be(400);
for (let i = 0; i < 5; i++) {
runtimeScene.renderAndStep(1000 / 60);
expect(behavior.isPlaying('MyTween')).to.be(false);
expect(behavior.hasFinished('MyTween')).to.be(false);
expect(object.getX()).to.be(400);
}
// The value is not overridden after the tween has been removed.
object.setX(123);
runtimeScene.renderAndStep(1000 / 60);
expect(object.getX()).to.be(123);
// A removed tween can't be resumed.
behavior.resumeTween('MyTween');
expect(behavior.isPlaying('MyTween')).to.be(false);
expect(behavior.hasFinished('MyTween')).to.be(false);
expect(object.getX()).to.be(123);
runtimeScene.renderAndStep(1000 / 60);
expect(object.getX()).to.be(123);
expect(behavior.isPlaying('MyTween')).to.be(false);
expect(behavior.hasFinished('MyTween')).to.be(false);
// Recreate the tween
expect(behavior.exists('MyTween')).to.be(false);
behavior.addObjectPositionXTween2('MyTween', 623, 'linear', 0.25, false);
expect(behavior.exists('MyTween')).to.be(true);
for (let i = 0; i < 5; i++) {
runtimeScene.renderAndStep(1000 / 60);
expect(behavior.isPlaying('MyTween')).to.be(true);
expect(behavior.hasFinished('MyTween')).to.be(false);
}
expect(object.getX()).to.be(373);
expect(behavior.exists('MyTween')).to.be(true);
});
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.addVariableTween3('MyTween', variable, 600, 'linear', 0.25, false);
checkProgress(6, () => variable.getAsNumber());
expect(variable.getAsNumber()).to.be(440);
});
it('can tween an object value', () => {
behavior.addValueTween('MyTween', 200, 600, 'linear', 0.25, false, false);
checkProgress(6, () => behavior.getValue('MyTween'));
expect(behavior.getValue('MyTween')).to.be(440);
});
it('can tween the position on X axis', () => {
object.setX(200);
behavior.addObjectPositionXTween2('MyTween', 600, 'linear', 0.25, false);
checkProgress(6, () => object.getX());
expect(object.getX()).to.be(440);
});
it('can tween the position on Y axis', () => {
object.setY(200);
behavior.addObjectPositionYTween2('MyTween', 600, 'linear', 0.25, false);
checkProgress(6, () => object.getY());
expect(object.getY()).to.be(440);
});
it('can tween the position on Z axis', () => {
cube.setZ(200);
cubeBehavior.addObjectPositionZTween2(
null,
'MyTween',
600,
'linear',
0.25,
false
);
checkProgress(6, () => cube.getZ());
expect(cube.getZ()).to.be(440);
});
it('can tween the angle', () => {
object.setAngle(200);
behavior.addObjectAngleTween2('MyTween', 600, 'linear', 0.25, false);
checkProgress(6, () => object.getAngle());
expect(object.getAngle()).to.be(440);
});
it('can tween the rotation X', () => {
cube.setRotationX(200);
cubeBehavior.addObjectRotationXTween(
null,
'MyTween',
600,
'linear',
0.25,
false
);
checkProgress(6, () => cube.getRotationX());
expect(cube.getRotationX()).to.be(440);
});
it('can tween the rotation Y', () => {
cube.setRotationY(200);
cubeBehavior.addObjectRotationYTween(
null,
'MyTween',
600,
'linear',
0.25,
false
);
checkProgress(6, () => cube.getRotationY());
expect(cube.getRotationY()).to.be(440);
});
it('can tween the width', () => {
object.setWidth(200);
behavior.addObjectWidthTween2('MyTween', 600, 'linear', 0.25, false);
checkProgress(6, () => object.getWidth());
expect(object.getWidth()).to.be(440);
});
it('can tween the height', () => {
object.setHeight(200);
behavior.addObjectHeightTween2('MyTween', 600, 'linear', 0.25, false);
checkProgress(6, () => object.getHeight());
expect(object.getHeight()).to.be(440);
});
it('can tween the depth', () => {
cube.setDepth(200);
cubeBehavior.addObjectDepthTween2(
null,
'MyTween',
600,
'linear',
0.25,
false
);
checkProgress(6, () => cube.getDepth());
expect(cube.getDepth()).to.be(440);
});
it('can tween a number effect property', () => {
sprite.addEffect({
effectType: 'Outline',
name: 'MyEffect',
doubleParameters: { padding: 0, thickness: 200 },
stringParameters: { color: '16;32;64' },
booleanParameters: {},
});
spriteBehavior.addNumberEffectPropertyTween(
null,
'MyTween',
600,
'MyEffect',
'thickness',
'linear',
0.25,
false
);
checkProgress(6, () =>
sprite.getRendererEffects()['MyEffect'].getDoubleParameter('thickness')
);
expect(
sprite.getRendererEffects()['MyEffect'].getDoubleParameter('thickness')
).to.be(440);
});
it('can tween a color effect property', () => {
sprite.addEffect({
effectType: 'Outline',
name: 'MyEffect',
doubleParameters: { padding: 0, thickness: 200 },
stringParameters: { color: '16;32;64' },
booleanParameters: {},
});
spriteBehavior.addColorEffectPropertyTween(
null,
'MyTween',
'255;192;128',
'MyEffect',
'color',
'linear',
0.25,
false
);
checkProgress(6, () =>
sprite.getRendererEffects()['MyEffect'].getColorParameter('color')
);
expect(
sprite.getRendererEffects()['MyEffect'].getColorParameter('color')
).to.be(gdjs.rgbOrHexStringToNumber('76;235;27'));
});
it('can tween the opacity', () => {
sprite.setOpacity(128);
spriteBehavior.addObjectOpacityTween2(
'MyTween',
255,
'linear',
0.25,
false
);
checkProgress(6, () => sprite.getOpacity());
expect(sprite.getOpacity()).to.be(204.2);
});
it('can tween the color', () => {
sprite.setColor('16;32;64');
spriteBehavior.addObjectColorTween2(
'MyTween',
'255;192;128',
'linear',
0.25,
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.addObjectColorHSLTween2(
'MyTween',
180,
true,
25,
50,
'linear',
0.25,
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.addObjectScaleXTween2(
'MyTween',
600,
'linear',
0.25,
false,
false
);
checkProgress(6, () => sprite.getScaleX());
// The interpolation is exponential.
expect(sprite.getScaleX()).to.be(386.6364089863524);
expect(sprite.getX()).to.be(100);
expect(sprite.getY()).to.be(400);
});
it('can tween the scale on X axis to 0', () => {
sprite.setPosition(100, 400);
sprite.setScaleX(1);
spriteBehavior.addObjectScaleTween3(
'MyTween',
0,
'linear',
0.25,
false,
false
);
// The interpolation is exponential.
// It would need an infinite speed to go away from 0.
// This is why the scale is set to 0 directly.
for (let i = 0; i < 11; i++) {
runtimeScene.renderAndStep(1000 / 60);
expect(sprite.getScaleX()).to.be(0);
}
expect(spriteBehavior.hasFinished('MyTween')).to.be(true);
expect(sprite.getX()).to.be(100);
expect(sprite.getY()).to.be(400);
});
it('can tween the scale on X axis from 0', () => {
sprite.setPosition(100, 400);
sprite.setScaleX(0);
spriteBehavior.addObjectScaleTween3(
'MyTween',
1,
'linear',
0.25,
false,
false
);
// The interpolation is exponential.
// It would need an infinite speed to go away from 0.
// This is why the scale is set to 1 directly at the end.
for (let i = 0; i < 11; i++) {
expect(sprite.getScale()).to.be(0);
runtimeScene.renderAndStep(1000 / 60);
}
expect(spriteBehavior.hasFinished('MyTween')).to.be(true);
expect(sprite.getScaleX()).to.be(1);
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.addObjectScaleXTween2(
'MyTween',
600,
'linear',
0.25,
false,
true
);
checkProgress(6, () => sprite.getScaleX());
// The interpolation is exponential.
expect(sprite.getScaleX()).to.be(386.6364089863524);
expect(sprite.getX()).to.be(-5872.3650875632775);
expect(sprite.getY()).to.be(400);
});
it('can tween the scale on Y axis', () => {
sprite.setPosition(100, 400);
sprite.setScaleY(200);
spriteBehavior.addObjectScaleYTween2(
'MyTween',
600,
'linear',
0.25,
false,
false
);
checkProgress(6, () => sprite.getScaleY());
// The interpolation is exponential.
expect(sprite.getScaleY()).to.be(386.6364089863524);
expect(sprite.getX()).to.be(100);
expect(sprite.getY()).to.be(400);
});
it('can tween the scale on Y axis to 0', () => {
sprite.setPosition(100, 400);
sprite.setScaleY(1);
spriteBehavior.addObjectScaleTween3(
'MyTween',
0,
'linear',
0.25,
false,
false
);
// The interpolation is exponential.
// It would need an infinite speed to go away from 0.
// This is why the scale is set to 0 directly.
for (let i = 0; i < 11; i++) {
runtimeScene.renderAndStep(1000 / 60);
expect(sprite.getScaleY()).to.be(0);
}
expect(spriteBehavior.hasFinished('MyTween')).to.be(true);
expect(sprite.getX()).to.be(100);
expect(sprite.getY()).to.be(400);
});
it('can tween the scale on Y axis from 0', () => {
sprite.setPosition(100, 400);
sprite.setScaleY(0);
spriteBehavior.addObjectScaleTween3(
'MyTween',
1,
'linear',
0.25,
false,
false
);
// The interpolation is exponential.
// It would need an infinite speed to go away from 0.
// This is why the scale is set to 1 directly at the end.
for (let i = 0; i < 11; i++) {
expect(sprite.getScale()).to.be(0);
runtimeScene.renderAndStep(1000 / 60);
}
expect(spriteBehavior.hasFinished('MyTween')).to.be(true);
expect(sprite.getScaleY()).to.be(1);
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.addObjectScaleYTween2(
'MyTween',
600,
'linear',
0.25,
false,
true
);
checkProgress(6, () => sprite.getScaleY());
// The interpolation is exponential.
expect(sprite.getScaleY()).to.be(386.6364089863524);
expect(sprite.getX()).to.be(100);
expect(sprite.getY()).to.be(-5572.3650875632775);
});
it('can tween the font size', () => {
textObject.setCharacterSize(200);
textObjectBehavior.addTextObjectCharacterSizeTween2(
'MyTween',
600,
'linear',
0.25,
false
);
checkProgress(6, () => textObject.getCharacterSize());
// The interpolation is exponential.
expect(textObject.getCharacterSize()).to.be(386.6364089863524);
});
it('can tween the position', () => {
object.setPosition(200, 300);
behavior.addObjectPositionTween2(
'MyTween',
600,
900,
'linear',
0.25,
false
);
checkProgress(6, [() => object.getX(), () => object.getY()]);
expect(object.getX()).to.be(440);
expect(object.getY()).to.be(660);
});
it('can tween the scale', () => {
sprite.setPosition(100, 400);
sprite.setScale(200);
spriteBehavior.addObjectScaleTween3(
'MyTween',
600,
'linear',
0.25,
false,
false
);
checkProgress(6, () => sprite.getScale());
// The interpolation is exponential.
expect(sprite.getScale()).to.be(386.6364089863524);
expect(sprite.getX()).to.be(100);
expect(sprite.getY()).to.be(400);
});
it('can tween the scale to 0', () => {
sprite.setPosition(100, 400);
sprite.setScale(1);
spriteBehavior.addObjectScaleTween3(
'MyTween',
0,
'linear',
0.25,
false,
false
);
// The interpolation is exponential.
// It would need an infinite speed to go away from 0.
// This is why the scale is set to 0 directly.
for (let i = 0; i < 11; i++) {
runtimeScene.renderAndStep(1000 / 60);
expect(sprite.getScale()).to.be(0);
}
expect(spriteBehavior.hasFinished('MyTween')).to.be(true);
expect(sprite.getX()).to.be(100);
expect(sprite.getY()).to.be(400);
});
it('can tween the scale from 0', () => {
sprite.setPosition(100, 400);
sprite.setScale(0);
spriteBehavior.addObjectScaleTween3(
'MyTween',
1,
'linear',
0.25,
false,
false
);
// The interpolation is exponential.
// It would need an infinite speed to go away from 0.
// This is why the scale is set to 1 directly at the end.
for (let i = 0; i < 11; i++) {
expect(sprite.getScale()).to.be(0);
runtimeScene.renderAndStep(1000 / 60);
}
expect(spriteBehavior.hasFinished('MyTween')).to.be(true);
expect(sprite.getScale()).to.be(1);
expect(sprite.getX()).to.be(100);
expect(sprite.getY()).to.be(400);
});
it('can tween the scales from center', () => {
sprite.setPosition(100, 400);
sprite.setScale(200);
spriteBehavior.addObjectScaleTween3(
'MyTween',
600,
'linear',
0.25,
false,
true
);
checkProgress(6, () => sprite.getScale());
// The interpolation is exponential.
expect(sprite.getScale()).to.be(386.6364089863524);
expect(sprite.getX()).to.be(-5872.3650875632775);
expect(sprite.getY()).to.be(-5572.3650875632775);
});
it('can tween the scale of a cube', () => {
cube.setPosition(100, 400);
cube.setZ(800);
cube.setScale(200);
cubeBehavior.addObjectScaleTween3(
'MyTween',
600,
'linear',
0.25,
false,
false
);
checkProgress(6, () => cube.getScale());
// The interpolation is exponential.
expect(cube.getScale()).to.be(386.6364089863524);
expect(cube.getX()).to.be(100);
expect(cube.getY()).to.be(400);
expect(cube.getZ()).to.be(800);
});
it('can tween the scales of a cube from center', () => {
cube.setPosition(100, 400);
cube.setZ(800);
cube.setScale(200);
cubeBehavior.addObjectScaleTween3(
'MyTween',
600,
'linear',
0.25,
false,
true
);
checkProgress(6, () => cube.getScale());
// The interpolation is exponential.
expect(cube.getScale()).to.be(386.6364089863524);
expect(cube.getX()).to.be(-5872.3650875632775);
expect(cube.getY()).to.be(-5572.3650875632775);
expect(cube.getZ()).to.be(-5172.3650875632775);
});
});