diff --git a/GDJS/Runtime/spriteruntimeobject.ts b/GDJS/Runtime/spriteruntimeobject.ts index 696c7c84c318..c61569e1eb56 100644 --- a/GDJS/Runtime/spriteruntimeobject.ts +++ b/GDJS/Runtime/spriteruntimeobject.ts @@ -603,7 +603,7 @@ namespace gdjs { return ( this.x + (-animationFrame.origin.x - - this._renderer.getUnscaledWidth() + + this.getCurrentFrameWidth() + 2 * animationFrame.center.x) * absScaleX ); @@ -626,7 +626,7 @@ namespace gdjs { return ( this.y + (-animationFrame.origin.y - - this._renderer.getUnscaledHeight() + + this.getCurrentFrameHeight() + 2 * animationFrame.center.y) * absScaleY ); @@ -639,17 +639,13 @@ namespace gdjs { */ getCenterX(): float { const animationFrame = this._animator.getCurrentFrame(); - const centerX = animationFrame - ? animationFrame.center.x - : this._renderer.getUnscaledWidth() / 2; + const frameWidth = this.getCurrentFrameWidth(); + const centerX = animationFrame ? animationFrame.center.x : frameWidth / 2; if (!this._flippedX) { //Just need to multiply by the scale as it is the center. return centerX * Math.abs(this._scaleX * this._preScale); } else { - return ( - (this._renderer.getUnscaledWidth() - centerX) * - Math.abs(this._scaleX * this._preScale) - ); + return (frameWidth - centerX) * Math.abs(this._scaleX * this._preScale); } } @@ -659,16 +655,16 @@ namespace gdjs { */ getCenterY(): float { const animationFrame = this._animator.getCurrentFrame(); + const frameHeight = this.getCurrentFrameHeight(); const centerY = animationFrame ? animationFrame.center.y - : this._renderer.getUnscaledHeight() / 2; + : frameHeight / 2; if (!this._flippedY) { //Just need to multiply by the scale as it is the center. return centerY * Math.abs(this._scaleY * this._preScale); } else { return ( - (this._renderer.getUnscaledHeight() - centerY) * - Math.abs(this._scaleY * this._preScale) + (frameHeight - centerY) * Math.abs(this._scaleY * this._preScale) ); } } @@ -833,19 +829,16 @@ namespace gdjs { if (this._animationFrameDirty) { this._updateAnimationFrame(); } - const unscaledWidth = this._renderer.getUnscaledWidth(); - if (unscaledWidth !== 0) { - this.setScaleX(newWidth / (unscaledWidth * this._preScale)); + const originalHeight = this.getOriginalHeight(); + if (originalHeight !== 0) { + this.setScaleX(newWidth / originalHeight); } } setHeight(newHeight: float): void { - if (this._animationFrameDirty) { - this._updateAnimationFrame(); - } - const unscaledHeight = this._renderer.getUnscaledHeight(); - if (unscaledHeight !== 0) { - this.setScaleY(newHeight / (unscaledHeight * this._preScale)); + const originalWidth = this.getOriginalWidth(); + if (originalWidth !== 0) { + this.setScaleY(newHeight / originalWidth); } } @@ -855,11 +848,25 @@ namespace gdjs { } override getOriginalWidth(): float { - return this._renderer.getUnscaledWidth() * this._preScale; + return this.getCurrentFrameWidth() * this._preScale; } override getOriginalHeight(): float { - return this._renderer.getUnscaledHeight() * this._preScale; + return this.getCurrentFrameHeight() * this._preScale; + } + + private getCurrentFrameWidth(): float { + if (this._animationFrameDirty) { + this._updateAnimationFrame(); + } + return this._renderer.getUnscaledWidth(); + } + + private getCurrentFrameHeight(): float { + if (this._animationFrameDirty) { + this._updateAnimationFrame(); + } + return this._renderer.getUnscaledHeight(); } /** diff --git a/GDJS/tests/tests-utils/assets/128x128.jpg b/GDJS/tests/tests-utils/assets/128x128.jpg new file mode 100644 index 000000000000..09a85021a04b Binary files /dev/null and b/GDJS/tests/tests-utils/assets/128x128.jpg differ diff --git a/GDJS/tests/tests-utils/init.pixiruntimegamewithassets.js b/GDJS/tests/tests-utils/init.pixiruntimegamewithassets.js index dfbb797731ac..de9c1552c663 100644 --- a/GDJS/tests/tests-utils/init.pixiruntimegamewithassets.js +++ b/GDJS/tests/tests-utils/init.pixiruntimegamewithassets.js @@ -102,9 +102,19 @@ gdjs.getPixiRuntimeGameWithAssets = () => { file: 'base/GDJS/tests/tests-utils/assets/64x64.jpg', userAdded: true, }, + { + kind: 'image', + name: 'base/tests-utils/assets/128x128.jpg', + metadata: '', + file: 'base/GDJS/tests/tests-utils/assets/128x128.jpg', + userAdded: true, + }, ], }, - usedResources: [{ name: 'base/tests-utils/assets/64x64.jpg' }], + usedResources: [ + { name: 'base/tests-utils/assets/64x64.jpg' }, + { name: 'base/tests-utils/assets/128x128.jpg' }, + ], // Used in CustomRuntimeObjects.js eventsFunctionsExtensions: [ { diff --git a/GDJS/tests/tests/spriteruntimeobject.pixiruntimegamewithassets.js b/GDJS/tests/tests/spriteruntimeobject.pixiruntimegamewithassets.js index c438d1ad6843..3ab4f2d54feb 100644 --- a/GDJS/tests/tests/spriteruntimeobject.pixiruntimegamewithassets.js +++ b/GDJS/tests/tests/spriteruntimeobject.pixiruntimegamewithassets.js @@ -88,6 +88,80 @@ describe('gdjs.SpriteRuntimeObject (using a PixiJS RuntimeGame with assets)', fu expect(object.getHeight()).to.be(64); }); + it('returns correct dimensions immediately after changing animation', async () => { + const runtimeGame = await gdjs.getPixiRuntimeGameWithAssets(); + const runtimeScene = new gdjs.RuntimeScene(runtimeGame); + + const object = new gdjs.SpriteRuntimeObject(runtimeScene, { + name: 'obj1', + type: 'Sprite', + updateIfNotVisible: false, + variables: [], + behaviors: [], + effects: [], + animations: [ + { + name: 'smallAnimation', + useMultipleDirections: false, + directions: [ + { + looping: false, + timeBetweenFrames: 1, + sprites: [ + { + hasCustomCollisionMask: false, + image: 'base/tests-utils/assets/64x64.jpg', + points: [], + originPoint: { name: 'Origin', x: 11, y: 12 }, + centerPoint: { automatic: true, name: 'Center', x: 0, y: 0 }, + customCollisionMask: [], + }, + ], + }, + ], + }, + { + name: 'largeAnimation', + useMultipleDirections: false, + directions: [ + { + looping: false, + timeBetweenFrames: 1, + sprites: [ + { + hasCustomCollisionMask: false, + image: 'base/tests-utils/assets/128x128.jpg', + points: [], + originPoint: { name: 'Origin', x: 13, y: 14 }, + centerPoint: { automatic: true, name: 'Center', x: 0, y: 0 }, + customCollisionMask: [], + }, + ], + }, + ], + }, + ], + }); + + // Get initial dimensions and frame related properties. + expect(object.getOriginalWidth()).to.be(64); + expect(object.getOriginalHeight()).to.be(64); + expect(object.getCenterX()).to.be(32); + expect(object.getCenterY()).to.be(32); + expect(object.getDrawableX()).to.be(-11); + expect(object.getDrawableY()).to.be(-12); + + // Change animation without rendering - dimensions and any other frame related properties should update immediately. + object.setAnimation(1); + + expect(object.getOriginalWidth()).to.be(128); + expect(object.getOriginalHeight()).to.be(128); + expect(object.getCenterX()).to.be(64); + expect(object.getCenterY()).to.be(64); + expect(object.getDrawableX()).to.be(-13); + expect(object.getDrawableY()).to.be(-14); + }); + it('returns the object drawable X/Y', async () => { const runtimeGame = await gdjs.getPixiRuntimeGameWithAssets(); const runtimeScene = new gdjs.RuntimeScene(runtimeGame);