diff --git a/GDJS/GDJS/Events/CodeGeneration/ObjectCodeGenerator.cpp b/GDJS/GDJS/Events/CodeGeneration/ObjectCodeGenerator.cpp index 109c78fc7199..1a195775a98e 100644 --- a/GDJS/GDJS/Events/CodeGeneration/ObjectCodeGenerator.cpp +++ b/GDJS/GDJS/Events/CodeGeneration/ObjectCodeGenerator.cpp @@ -79,7 +79,7 @@ gd::String ObjectCodeGenerator::GenerateRuntimeObjectCompleteCode( *eventsFunction, methodCodeNamespace, methodFullyQualifiedName, - "that._onceTriggers", + "runtimeScene.getOnceTriggers()", functionName == doStepPreEventsFunctionName ? GenerateDoStepPreEventsPreludeCode(eventsBasedObject) : "", @@ -208,7 +208,6 @@ CODE_NAMESPACE.RUNTIME_OBJECT_CLASSNAME = class RUNTIME_OBJECT_CLASSNAME extends super(parentInstanceContainer, objectData, instanceData); this._parentInstanceContainer = parentInstanceContainer; - this._onceTriggers = new gdjs.OnceTriggers(); this._objectData = {}; INITIALIZE_PROPERTIES_CODE INITIALIZE_ANIMATABLE_CODE @@ -360,7 +359,7 @@ CODE_NAMESPACE.RUNTIME_OBJECT_CLASSNAME.prototype.doStepPreEvents = function() { gd::String ObjectCodeGenerator::GenerateDoStepPreEventsPreludeCode( const gd::EventsBasedObject& eventsBasedObject) { gd::String doStepPreEventsPreludeCode; - doStepPreEventsPreludeCode += "this._onceTriggers.startNewFrame();"; + doStepPreEventsPreludeCode += "this._instanceContainer.getOnceTriggers().startNewFrame();"; if (eventsBasedObject.IsAnimatable()) { doStepPreEventsPreludeCode += "\nthis._animator.step(this.getElapsedTime() / 1000);"; diff --git a/GDJS/Runtime/CustomRuntimeObjectInstanceContainer.ts b/GDJS/Runtime/CustomRuntimeObjectInstanceContainer.ts index 5860ce866d51..94baa56ef765 100644 --- a/GDJS/Runtime/CustomRuntimeObjectInstanceContainer.ts +++ b/GDJS/Runtime/CustomRuntimeObjectInstanceContainer.ts @@ -394,11 +394,19 @@ namespace gdjs { } getViewportOriginX(): float { - return this._customObject.getUnscaledCenterX(); + // We don't use `getUnscaledCenterX` because of custom center. + return ( + this._customObject.getInnerAreaMinX() + + this._customObject.getInnerAreaMaxX() + ) / 2; } getViewportOriginY(): float { - return this._customObject.getUnscaledCenterY(); + // We don't use `getUnscaledCenterY` because of custom center. + return ( + this._customObject.getInnerAreaMinY() + + this._customObject.getInnerAreaMaxY() + ) / 2; } onChildrenLocationChanged(): void { diff --git a/GDJS/Runtime/RuntimeCustomObjectLayer.ts b/GDJS/Runtime/RuntimeCustomObjectLayer.ts index 0f2e3374f99a..02442911f28e 100644 --- a/GDJS/Runtime/RuntimeCustomObjectLayer.ts +++ b/GDJS/Runtime/RuntimeCustomObjectLayer.ts @@ -10,6 +10,9 @@ namespace gdjs { * @category Core Engine > Layers */ export class RuntimeCustomObjectLayer extends gdjs.RuntimeLayer { + private _cameraDeltaX: float = 0; + private _cameraDeltaY: float = 0; + /** * @param layerData The data used to initialize the layer * @param instanceContainer The container in which the layer is used @@ -22,6 +25,7 @@ namespace gdjs { // Let the renderer do its final set up: this._renderer.onCreated(); + this._renderer.updatePosition(); } override onGameResolutionResized( @@ -30,23 +34,29 @@ namespace gdjs { ): void {} override getCameraX(cameraId?: integer): float { - return 0; + return this._cameraDeltaX + this._runtimeScene.getViewportOriginX(); } override getCameraY(cameraId?: integer): float { - return 0; + return this._cameraDeltaY + this._runtimeScene.getViewportOriginY(); } - override setCameraX(x: float, cameraId?: integer): void {} + override setCameraX(x: float, cameraId?: integer): void { + this._cameraDeltaX = x - this._runtimeScene.getViewportOriginX(); + this._renderer.updatePosition(); + } - override setCameraY(y: float, cameraId?: integer): void {} + override setCameraY(y: float, cameraId?: integer): void { + this._cameraDeltaY = y - this._runtimeScene.getViewportOriginY(); + this._renderer.updatePosition(); + } override getCameraWidth(cameraId?: integer): float { - return 0; + return this.getWidth(); } override getCameraHeight(cameraId?: integer): float { - return 0; + return this.getHeight(); } override setCameraZoom(newZoom: float, cameraId?: integer): void {} @@ -121,9 +131,15 @@ namespace gdjs { cameraId: integer, result: FloatPoint ): FloatPoint { + // The result parameter used to be optional. + let position = result || [0, 0]; + + x += this._cameraDeltaX; + y += this._cameraDeltaY; + // TODO EBO use an AffineTransformation to avoid chained calls. // The result parameter used to be optional. - return this._runtimeScene.convertCoords(x, y, result || [0, 0]); + return this._runtimeScene.convertCoords(x, y, position); } override convertInverseCoords( @@ -132,9 +148,16 @@ namespace gdjs { cameraId: integer, result: FloatPoint ): FloatPoint { + // The result parameter used to be optional. + let position = result || [0, 0]; + // TODO EBO use an AffineTransformation to avoid chained calls. // The result parameter used to be optional. - return this._runtimeScene.convertInverseCoords(x, y, result || [0, 0]); + this._runtimeScene.convertInverseCoords(x, y, position); + position[0] -= this._cameraDeltaX; + position[1] -= this._cameraDeltaY; + + return position; } override applyLayerInverseTransformation( @@ -143,8 +166,8 @@ namespace gdjs { cameraId: integer, result: FloatPoint ): FloatPoint { - result[0] = x; - result[1] = y; + result[0] = x - this._cameraDeltaX; + result[1] = y - this._cameraDeltaY; return result; } @@ -154,8 +177,8 @@ namespace gdjs { cameraId: integer, result: FloatPoint ): FloatPoint { - result[0] = x; - result[1] = y; + result[0] = x + this._cameraDeltaX; + result[1] = y + this._cameraDeltaY; return result; } } diff --git a/GDJS/Runtime/RuntimeInstanceContainer.ts b/GDJS/Runtime/RuntimeInstanceContainer.ts index 5a70e9cd2bcf..88fec20e0f29 100644 --- a/GDJS/Runtime/RuntimeInstanceContainer.ts +++ b/GDJS/Runtime/RuntimeInstanceContainer.ts @@ -56,6 +56,8 @@ namespace gdjs { _debugDrawShowPointsNames: boolean = false; _debugDrawShowCustomPoints: boolean = false; + _onceTriggers: OnceTriggers; + /** * @param runtimeGame The game associated to this scene. */ @@ -71,6 +73,7 @@ namespace gdjs { // Register an UnknownRuntimeObject to use when the object doesn't exist. this.registerObject(unknownObjectData); } + this._onceTriggers = new gdjs.OnceTriggers(); } /** @@ -842,6 +845,13 @@ namespace gdjs { } } + /** + * Get the structure containing the triggers for "Trigger once" conditions. + */ + getOnceTriggers() { + return this._onceTriggers; + } + /** * Clear any data structures to make sure memory is freed as soon as * possible. @@ -859,6 +869,8 @@ namespace gdjs { this._instancesRemoved = []; this._layersCameraCoordinates = {}; this._initialBehaviorSharedData = new Hashtable(); + // @ts-ignore We are deleting the object + this._onceTriggers = null; } } } diff --git a/GDJS/Runtime/runtimescene.ts b/GDJS/Runtime/runtimescene.ts index a4e6a63aa011..acf90459a3e2 100644 --- a/GDJS/Runtime/runtimescene.ts +++ b/GDJS/Runtime/runtimescene.ts @@ -45,7 +45,6 @@ namespace gdjs { /** Should the canvas be cleared before this scene rendering. */ _clearCanvas: boolean = true; - _onceTriggers: OnceTriggers; _profiler: gdjs.Profiler | null = null; // Set to `new gdjs.Profiler()` to have profiling done on the scene. @@ -74,7 +73,6 @@ namespace gdjs { gdjs.VariablesContainer >(); this._timeManager = new gdjs.TimeManager(); - this._onceTriggers = new gdjs.OnceTriggers(); this._requestedChange = SceneChangeRequest.CONTINUE; this._cachedGameResolutionWidth = runtimeGame ? runtimeGame.getGameResolutionWidth() @@ -345,8 +343,6 @@ namespace gdjs { this._eventsFunction = null; this._lastId = 0; this.networkId = null; - // @ts-ignore We are deleting the object - this._onceTriggers = null; } /** @@ -819,13 +815,6 @@ namespace gdjs { } } - /** - * Get the structure containing the triggers for "Trigger once" conditions. - */ - getOnceTriggers() { - return this._onceTriggers; - } - /** * Check if the scene was just resumed. * This is true during the first frame after the scene has been unpaused. diff --git a/GDJS/tests/tests-utils/MockedCustomObject.js b/GDJS/tests/tests-utils/MockedCustomObject.js index 2b37f50a585e..9e62d7899a7b 100644 --- a/GDJS/tests/tests-utils/MockedCustomObject.js +++ b/GDJS/tests/tests-utils/MockedCustomObject.js @@ -8,7 +8,6 @@ gdjs.evtsExt__MyExtension__MyCustomObject.MyCustomObject = class MyCustomObject super(parentInstanceContainer, objectData); this._parentInstanceContainer = parentInstanceContainer; - this._onceTriggers = new gdjs.OnceTriggers(); this._objectData = {}; this._objectData.MyProperty = objectData.content.MyProperty !== undefined ? objectData.content.MyProperty : Number("123") || 0;