diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c64d1c257..fffe50fcb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ### Changed - Core: full ES6 refactoring of `me.device`, and API clean-up (@see https://github.com/melonjs/melonJS/wiki/Upgrade-Guide#120x-to-130x-stable) - Loader: `onload` and `onerror` callbacks are now optionals when directly loading assets (easier with base64 encoded assets) +- Game: refactoring of`game` into an Instantiable `Application` object, with `game` now being the default instance of it (#1091) ### Fixed - Loader: fix loading/preloading of base64 audio assets, and base64 encoded FontFace diff --git a/src/application/application.js b/src/application/application.js new file mode 100644 index 0000000000..3f04bf8afd --- /dev/null +++ b/src/application/application.js @@ -0,0 +1,228 @@ +import { renderer } from "./../video/video.js"; +import * as event from "./../system/event.js"; +import timer from "./../system/timer.js"; +import state from "./../state/state.js"; +import World from "./../physics/world.js"; + +/** + * @classdesc + * An Application represents a single melonJS game. + * An Application is responsible for updating (each frame) all the related object status and draw them. + * @see game + */ +class Application { + constructor() { + /** + * a reference to the current active stage "default" camera + * @public + * @type {Camera2d} + */ + this.viewport = null; + + /** + * a reference to the game world,
+ * a world is a virtual environment containing all the game objects + * @public + * @type {World} + */ + this.world = null; + + /** + * when true, all objects will be added under the root world container.
+ * When false, a `me.Container` object will be created for each corresponding groups + * @public + * @type {boolean} + * @default true + */ + this.mergeGroup = true; + + /** + * Specify the property to be used when sorting renderables. + * Accepted values : "x", "y", "z" + * @public + * @type {string} + * @default "z" + */ + this.sortOn = "z"; + + /** + * Last time the game update loop was executed.
+ * Use this value to implement frame prediction in drawing events, + * for creating smooth motion while running game update logic at + * a lower fps. + * @public + * @type {DOMHighResTimeStamp} + * @name lastUpdate + * @memberof Application + */ + this.lastUpdate = 0; + + // to know when we have to refresh the display + this.isDirty = true; + + // always refresh the display when updatesPerSecond are lower than fps + this.isAlwaysDirty = false; + + // frame counter for frameSkipping + // reset the frame counter + this.frameCounter = 0; + this.frameRate = 1; + + // time accumulation for multiple update calls + this.accumulator = 0.0; + this.accumulatorMax = 0.0; + this.accumulatorUpdateDelta = 0; + + // min update step size + this.stepSize = 1000 / 60; + this.updateDelta = 0; + this.lastUpdateStart = null; + this.updateAverageDelta = 0; + } + + /** + * init the game instance (create a physic world, update starting time, etc..) + */ + init() { + this.world = new World(); + this.lastUpdate = globalThis.performance.now(); + event.emit(event.GAME_INIT, this); + } + + /** + * reset the game Object manager + * destroy all current objects + */ + reset() { + // point to the current active stage "default" camera + var current = state.current(); + if (typeof current !== "undefined") { + this.viewport = current.cameras.get("default"); + } + + // publish reset notification + event.emit(event.GAME_RESET); + + // Refresh internal variables for framerate limiting + this.updateFrameRate(); + } + + /** + * Fired when a level is fully loaded and all renderable instantiated.
+ * Additionnaly the level id will also be passed to the called function. + * @example + * // call myFunction () everytime a level is loaded + * me.game.onLevelLoaded = this.myFunction.bind(this); + */ + onLevelLoaded() {}; + + /** + * Update the renderer framerate using the system config variables. + * @see timer.maxfps + * @see World.fps + */ + updateFrameRate() { + // reset the frame counter + this.frameCounter = 0; + this.frameRate = ~~(0.5 + 60 / timer.maxfps); + + // set step size based on the updatesPerSecond + this.stepSize = (1000 / this.world.fps); + this.accumulator = 0.0; + this.accumulatorMax = this.stepSize * 10; + + // display should always re-draw when update speed doesn't match fps + // this means the user intends to write position prediction drawing logic + this.isAlwaysDirty = (timer.maxfps > this.world.fps); + } + + /** + * Returns the parent container of the specified Child in the game world + * @param {Renderable} child + * @returns {Container} + */ + getParentContainer(child) { + return child.ancestor; + } + + /** + * force the redraw (not update) of all objects + */ + repaint() { + this.isDirty = true; + } + + /** + * update all objects related to this game active scene/stage + * @param {number} time current timestamp as provided by the RAF callback + * @param {Stage} stage the current stage + */ + update(time, stage) { + // handle frame skipping if required + if ((++this.frameCounter % this.frameRate) === 0) { + // reset the frame counter + this.frameCounter = 0; + + // publish notification + event.emit(event.GAME_BEFORE_UPDATE, time); + + this.accumulator += timer.getDelta(); + this.accumulator = Math.min(this.accumulator, this.accumulatorMax); + + this.updateDelta = (timer.interpolation) ? timer.getDelta() : this.stepSize; + this.accumulatorUpdateDelta = (timer.interpolation) ? this.updateDelta : Math.max(this.updateDelta, this.updateAverageDelta); + + while (this.accumulator >= this.accumulatorUpdateDelta || timer.interpolation) { + this.lastUpdateStart = globalThis.performance.now(); + + // game update event + if (state.isPaused() !== true) { + event.emit(event.GAME_UPDATE, time); + } + + // update all objects (and pass the elapsed time since last frame) + this.isDirty = stage.update(this.updateDelta) || this.isDirty; + + this.lastUpdate = globalThis.performance.now(); + this.updateAverageDelta = this.lastUpdate - this.lastUpdateStart; + + this.accumulator -= this.accumulatorUpdateDelta; + if (timer.interpolation) { + this.accumulator = 0; + break; + } + } + + // publish notification + event.emit(event.GAME_AFTER_UPDATE, this.lastUpdate); + } + } + + /** + * draw the active scene/stage associated to this game + * @param {Stage} stage the current stage + */ + draw(stage) { + if (renderer.isContextValid === true && (this.isDirty || this.isAlwaysDirty)) { + // publish notification + event.emit(event.GAME_BEFORE_DRAW, globalThis.performance.now()); + + // prepare renderer to draw a new frame + renderer.clear(); + + // render the stage + stage.draw(renderer); + + // set back to flag + this.isDirty = false; + + // flush/render our frame + renderer.flush(); + + // publish notification + event.emit(event.GAME_AFTER_DRAW, globalThis.performance.now()); + } + } +} + +export default Application; diff --git a/src/camera/camera2d.js b/src/camera/camera2d.js index 828a292db7..babcefa1d7 100644 --- a/src/camera/camera2d.js +++ b/src/camera/camera2d.js @@ -10,7 +10,7 @@ import * as event from "./../system/event.js"; import pool from "./../system/pooling.js"; import Renderable from "./../renderable/renderable.js"; import {clamp, toBeCloseTo} from "./../math/math.js"; -import { world } from "./../game.js"; +import game from "./../game.js"; // some ref shortcut @@ -615,7 +615,7 @@ class Camera2d extends Renderable { localToWorld(x, y, v) { // TODO memoization for one set of coords (multitouch) v = v || pool.pull("Vector2d"); - v.set(x, y).add(this.pos).sub(world.pos); + v.set(x, y).add(this.pos).sub(game.world.pos); if (!this.currentTransform.isIdentity()) { this.invCurrentTransform.apply(v); } @@ -639,7 +639,7 @@ class Camera2d extends Renderable { if (!this.currentTransform.isIdentity()) { this.currentTransform.apply(v); } - return v.sub(this.pos).add(world.pos); + return v.sub(this.pos).add(game.world.pos); } /** @@ -706,7 +706,7 @@ class Camera2d extends Renderable { this.preDraw(renderer); - container.preDraw(renderer); + container.preDraw(renderer, this); // draw all objects, // specifying the viewport as the rectangle area to redraw @@ -715,7 +715,7 @@ class Camera2d extends Renderable { // draw the viewport/camera effects this.drawFX(renderer); - container.postDraw(renderer); + container.postDraw(renderer, this); this.postDraw(renderer); diff --git a/src/game.js b/src/game.js index a966ff888b..0895314929 100644 --- a/src/game.js +++ b/src/game.js @@ -1,243 +1,20 @@ -import { renderer } from "./video/video.js"; import * as event from "./system/event.js"; -import timer from "./system/timer.js"; -import state from "./state/state.js"; -import World from "./physics/world.js"; +import Application from "./application/application.js"; /** - * game represents your current game, it contains all the objects, - * tilemap layers, current viewport, collision map, etc...
- * game is also responsible for updating (each frame) the object status and draw them. + * game is a default instance of a melonJS Application and represents your current game, + * it contains all the objects, tilemap layers, current viewport, collision map, etc...
* @namespace game + * @see Application */ -// to know when we have to refresh the display -var isDirty = true; - -// always refresh the display when updatesPerSecond are lower than fps -var isAlwaysDirty = false; - -// frame counter for frameSkipping -// reset the frame counter -var frameCounter = 0; -var frameRate = 1; - -// time accumulation for multiple update calls -var accumulator = 0.0; -var accumulatorMax = 0.0; -var accumulatorUpdateDelta = 0; - -// min update step size -var stepSize = 1000 / 60; -var updateDelta = 0; -var lastUpdateStart = null; -var updateAverageDelta = 0; - +// create a default melonJS application instance +let game = new Application(); // initialize the game manager on system boot event.on(event.BOOT, () => { - // the root object of our world is an entity container - world = new World(); - // publish init notification - event.emit(event.GAME_INIT); + // initialize the default game instance + game.init(); }); - -/** - * a reference to the current active stage "default" camera - * @public - * @type {Camera2d} - * @name viewport - * @memberof game - */ -export let viewport; - -/** - * a reference to the game world,
- * a world is a virtual environment containing all the game objects - * @public - * @type {World} - * @name world - * @memberof game - */ -export let world; - -/** - * when true, all objects will be added under the root world container.
- * When false, a `me.Container` object will be created for each corresponding groups - * @public - * @type {boolean} - * @default true - * @name mergeGroup - * @memberof game - */ -export let mergeGroup = true; - -/** - * Specify the property to be used when sorting entities. - * Accepted values : "x", "y", "z" - * @public - * @type {string} - * @default "z" - * @name sortOn - * @memberof game - */ -export let sortOn = "z"; - -/** - * Last time the game update loop was executed.
- * Use this value to implement frame prediction in drawing events, - * for creating smooth motion while running game update logic at - * a lower fps. - * @public - * @type {DOMHighResTimeStamp} - * @name lastUpdate - * @memberof game - */ -export let lastUpdate = globalThis.performance.now(); - -/** - * Fired when a level is fully loaded and all entities instantiated.
- * Additionnaly the level id will also be passed to the called function. - * @function game.onLevelLoaded - * @example - * // call myFunction () everytime a level is loaded - * me.game.onLevelLoaded = this.myFunction.bind(this); - */ -export function onLevelLoaded() {}; - -/** - * reset the game Object manager
- * destroy all current objects - * @function game.reset - */ -export function reset () { - // point to the current active stage "default" camera - var current = state.current(); - if (typeof current !== "undefined") { - viewport = current.cameras.get("default"); - } - - // publish reset notification - event.emit(event.GAME_RESET); - - // Refresh internal variables for framerate limiting - updateFrameRate(); -} - -/** - * Update the renderer framerate using the system config variables. - * @function game.updateFrameRate - * @see timer.maxfps - * @see World.fps - */ -export function updateFrameRate() { - // reset the frame counter - frameCounter = 0; - frameRate = ~~(0.5 + 60 / timer.maxfps); - - // set step size based on the updatesPerSecond - stepSize = (1000 / world.fps); - accumulator = 0.0; - accumulatorMax = stepSize * 10; - - // display should always re-draw when update speed doesn't match fps - // this means the user intends to write position prediction drawing logic - isAlwaysDirty = (timer.maxfps > world.fps); -}; - -/** - * Returns the parent container of the specified Child in the game world - * @function game.getParentContainer - * @param {Renderable} child - * @returns {Container} - */ -export function getParentContainer(child) { - return child.ancestor; -}; - -/** - * force the redraw (not update) of all objects - * @function game.repaint - */ -export function repaint() { - isDirty = true; -}; - - -/** - * update all objects of the game manager - * @ignore - * @function game.update - * @param {number} time current timestamp as provided by the RAF callback - * @param {Stage} stage the current stage - */ -export function update(time, stage) { - // handle frame skipping if required - if ((++frameCounter % frameRate) === 0) { - // reset the frame counter - frameCounter = 0; - - // publish notification - event.emit(event.GAME_BEFORE_UPDATE, time); - - accumulator += timer.getDelta(); - accumulator = Math.min(accumulator, accumulatorMax); - - updateDelta = (timer.interpolation) ? timer.getDelta() : stepSize; - accumulatorUpdateDelta = (timer.interpolation) ? updateDelta : Math.max(updateDelta, updateAverageDelta); - - while (accumulator >= accumulatorUpdateDelta || timer.interpolation) { - lastUpdateStart = globalThis.performance.now(); - - // game update event - if (state.isPaused() !== true) { - event.emit(event.GAME_UPDATE, time); - } - - // update all objects (and pass the elapsed time since last frame) - isDirty = stage.update(updateDelta) || isDirty; - - lastUpdate = globalThis.performance.now(); - updateAverageDelta = lastUpdate - lastUpdateStart; - - accumulator -= accumulatorUpdateDelta; - if (timer.interpolation) { - accumulator = 0; - break; - } - } - - // publish notification - event.emit(event.GAME_AFTER_UPDATE, lastUpdate); - } -}; - -/** - * draw the current scene/stage - * @function game.draw - * @ignore - * @param {Stage} stage the current stage - */ -export function draw(stage) { - - if (renderer.isContextValid === true && (isDirty || isAlwaysDirty)) { - // publish notification - event.emit(event.GAME_BEFORE_DRAW, globalThis.performance.now()); - - // prepare renderer to draw a new frame - renderer.clear(); - - // render the stage - stage.draw(renderer); - - // set back to flag - isDirty = false; - - // flush/render our frame - renderer.flush(); - - // publish notification - event.emit(event.GAME_AFTER_DRAW, globalThis.performance.now()); - } -}; +export default game; diff --git a/src/index.js b/src/index.js index 97f2415570..3b151674e7 100644 --- a/src/index.js +++ b/src/index.js @@ -6,7 +6,7 @@ import * as audio from "./audio/audio.js"; import collision from "./physics/collision.js"; import * as event from "./system/event.js"; import * as device from "./system/device.js"; -import * as game from "./game.js"; +import game from "./game.js"; import loader from "./loader/loader.js"; import * as Math from "./math/math.js"; import utils from "./utils/utils.js"; diff --git a/src/input/pointer.js b/src/input/pointer.js index 6ed0b42f84..ab074ddad8 100644 --- a/src/input/pointer.js +++ b/src/input/pointer.js @@ -1,6 +1,6 @@ import Vector2d from "./../math/vector2.js"; import Bounds from "./../physics/bounds.js"; -import { viewport } from "./../game.js"; +import game from "./../game.js"; import { globalToLocal } from "./input.js"; import { locked } from "./pointerevent.js"; @@ -360,8 +360,8 @@ class Pointer extends Bounds { this.type = event.type; // get the current screen to game world offset - if (typeof viewport !== "undefined") { - viewport.localToWorld(this.gameScreenX, this.gameScreenY, tmpVec); + if (typeof game.viewport !== "undefined") { + game.viewport.localToWorld(this.gameScreenX, this.gameScreenY, tmpVec); } /* Initialize the two coordinate space properties. */ diff --git a/src/input/pointerevent.js b/src/input/pointerevent.js index 2f46ef0d84..dfab4ff463 100644 --- a/src/input/pointerevent.js +++ b/src/input/pointerevent.js @@ -10,7 +10,7 @@ import * as device from "./../system/device.js"; import Pointer from "./pointer.js"; import Rect from "./../geometries/rectangle.js"; import Container from "./../renderable/container.js"; -import { world, viewport } from "./../game.js"; +import game from "./../game.js"; /** * A pool of `Pointer` objects to cache pointer/touch event coordinates. @@ -287,10 +287,10 @@ function dispatchEvent(normalizedEvents) { } // fetch valid candiates from the game world container - var candidates = world.broadphase.retrieve(currentPointer, Container.prototype._sortReverseZ); + var candidates = game.world.broadphase.retrieve(currentPointer, Container.prototype._sortReverseZ); // add the main game viewport to the list of candidates - candidates = candidates.concat([ viewport ]); + candidates = candidates.concat([ game.viewport ]); for (var c = candidates.length, candidate; c--, (candidate = candidates[c]);) { if (eventHandlers.has(candidate) && (candidate.isKinematic !== true)) { diff --git a/src/level/level.js b/src/level/level.js index 4e2aa993b7..8f0a71be20 100644 --- a/src/level/level.js +++ b/src/level/level.js @@ -2,7 +2,7 @@ import utils from "./../utils/utils.js"; import * as event from "./../system/event.js"; import state from "./../state/state.js"; import loader from "./../loader/loader.js"; -import * as game from "./../game.js"; +import game from "./../game.js"; import TMXTileMap from "./tiled/TMXTileMap.js"; @@ -125,7 +125,7 @@ var level = { * @param {string} levelId level id * @param {object} [options] additional optional parameters * @param {Container} [options.container=game.world] container in which to load the specified level - * @param {Function} [options.onLoaded=ame.onLevelLoaded] callback for when the level is fully loaded + * @param {Function} [options.onLoaded=game.onLevelLoaded] callback for when the level is fully loaded * @param {boolean} [options.flatten=game.mergeGroup] if true, flatten all objects into the given container * @param {boolean} [options.setViewportBounds=true] if true, set the viewport bounds to the map size * @returns {boolean} true if the level was successfully loaded diff --git a/src/level/tiled/TMXLayer.js b/src/level/tiled/TMXLayer.js index aeef8efb97..cf20d6bba1 100644 --- a/src/level/tiled/TMXLayer.js +++ b/src/level/tiled/TMXLayer.js @@ -4,7 +4,7 @@ import * as TMXUtils from "./TMXUtils.js"; import Tile from "./TMXTile.js"; import Renderable from "./../../renderable/renderable.js"; import CanvasRenderer from "./../../video/canvas/canvas_renderer"; -import { world } from "./../../game.js"; +import game from "./../../game.js"; /** * Create required arrays for the given layer object @@ -173,7 +173,7 @@ class TMXLayer extends Renderable { // check for the correct rendering method if (typeof (this.preRender) === "undefined") { - this.preRender = world.preRender; + this.preRender = game.world.preRender; } // set a renderer diff --git a/src/level/tiled/TMXTileMap.js b/src/level/tiled/TMXTileMap.js index f63b4423c8..cf5f55b9d7 100644 --- a/src/level/tiled/TMXTileMap.js +++ b/src/level/tiled/TMXTileMap.js @@ -1,6 +1,6 @@ import pool from "./../../system/pooling.js"; import * as event from "./../../system/event.js"; -import { viewport } from "./../../game.js"; +import game from "./../../game.js"; import collision from "./../../physics/collision.js"; import Body from "./../../physics/body.js"; import TMXOrthogonalRenderer from "./renderer/TMXOrthogonalRenderer.js"; @@ -396,7 +396,7 @@ class TMXTileMap { */ function _setBounds(width, height) { // adjust the viewport bounds if level is smaller - viewport.setBounds( + game.viewport.setBounds( 0, 0, Math.max(levelBounds.width, width), Math.max(levelBounds.height, height) @@ -413,7 +413,7 @@ class TMXTileMap { if (setViewportBounds === true) { event.off(event.VIEWPORT_ONRESIZE, _setBounds); // force viewport bounds update - _setBounds(viewport.width, viewport.height); + _setBounds(game.viewport.width, game.viewport.height); // Replace the resize handler event.on(event.VIEWPORT_ONRESIZE, _setBounds, this); } diff --git a/src/loader/loadingscreen.js b/src/loader/loadingscreen.js index 5d8d50afaa..a9cee0ad78 100644 --- a/src/loader/loadingscreen.js +++ b/src/loader/loadingscreen.js @@ -1,4 +1,4 @@ -import { world, viewport } from "./../game.js"; +import game from "./../game.js"; import { renderer } from "./../video/video.js"; import * as event from "./../system/event.js"; import Sprite from "./../renderable/sprite.js"; @@ -41,7 +41,7 @@ class ProgressBar extends Renderable { * draw function * @ignore */ - draw (renderer) { + draw(renderer, viewport) { // draw the progress bar renderer.setColor("black"); renderer.fillRect(this.pos.x, viewport.centerY, renderer.getWidth(), this.barHeight / 2); @@ -75,10 +75,10 @@ class DefaultLoadingScreen extends Stage { var barHeight = 8; // set a background color - world.backgroundColor.parseCSS("#202020"); + game.world.backgroundColor.parseCSS("#202020"); // progress bar - world.addChild(new ProgressBar( + game.world.addChild(new ProgressBar( 0, renderer.getHeight() / 2, renderer.getWidth(), @@ -89,7 +89,7 @@ class DefaultLoadingScreen extends Stage { loader.load({name: "melonjs_logo", type: "image", src: logo_url}); // melonJS logo - world.addChild(new Sprite( + game.world.addChild(new Sprite( renderer.getWidth() / 2, renderer.getHeight() / 2, { image : "melonjs_logo", diff --git a/src/physics/body.js b/src/physics/body.js index 5af99a6533..5515965bf2 100644 --- a/src/physics/body.js +++ b/src/physics/body.js @@ -7,7 +7,7 @@ import collision from "./collision.js"; import * as arrayUtil from "./../utils/array.js"; import timer from "./../system/timer.js"; import { clamp } from "./../math/math.js"; -import { world } from "./../game.js"; +import game from "./../game.js"; /** @@ -464,7 +464,7 @@ class Body { } // cancel the falling an jumping flags if necessary - var dir = Math.sign(world.gravity.y * this.gravityScale) || 1; + var dir = Math.sign(game.world.gravity.y * this.gravityScale) || 1; this.falling = overlap.y >= dir; this.jumping = overlap.y <= -dir; } @@ -601,7 +601,7 @@ class Body { // apply gravity to the current velocity if (!this.ignoreGravity) { - var worldGravity = world.gravity; + var worldGravity = game.world.gravity; // apply gravity if defined this.vel.x += worldGravity.x * this.gravityScale * deltaTime; diff --git a/src/physics/detector.js b/src/physics/detector.js index d4ebc4db4e..56c9033e17 100644 --- a/src/physics/detector.js +++ b/src/physics/detector.js @@ -1,7 +1,7 @@ import * as SAT from "./sat.js"; import ResponseObject from "./response.js"; import Vector2d from "./../math/vector2.js"; -import { world } from "./../game.js"; +import game from "./../game.js"; // a dummy object when using Line for raycasting let dummyObj = { @@ -50,7 +50,7 @@ function shouldCollide(a, b) { export function collisionCheck(objA, response = globalResponse) { var collisionCounter = 0; // retreive a list of potential colliding objects from the game world - var candidates = world.broadphase.retrieve(objA); + var candidates = game.world.broadphase.retrieve(objA); for (var i = candidates.length, objB; i--, (objB = candidates[i]);) { @@ -139,7 +139,7 @@ export function rayCast(line, result = []) { var collisionCounter = 0; // retrieve a list of potential colliding objects from the game world - var candidates = world.broadphase.retrieve(line); + var candidates = game.world.broadphase.retrieve(line); for (var i = candidates.length, objB; i--, (objB = candidates[i]);) { diff --git a/src/physics/quadtree.js b/src/physics/quadtree.js index 9b35e0fa8d..c84ef3773c 100644 --- a/src/physics/quadtree.js +++ b/src/physics/quadtree.js @@ -1,7 +1,7 @@ import Vector2d from "./../math/vector2.js"; import Container from "./../renderable/container.js"; import * as arrayUtil from "./../utils/array.js"; -import { viewport } from "./../game.js"; +import game from "./../game.js"; /* * A QuadTree implementation in JavaScript, a 2d spatial subdivision algorithm. @@ -125,7 +125,7 @@ class QuadTree { // use game world coordinates for floating items if (item.isFloating === true) { - pos = viewport.localToWorld(bounds.left, bounds.top, QT_VECTOR); + pos = game.viewport.localToWorld(bounds.left, bounds.top, QT_VECTOR); } else { pos = QT_VECTOR.set(item.left, item.top); } diff --git a/src/renderable/container.js b/src/renderable/container.js index 906888e0da..a0fb91246e 100644 --- a/src/renderable/container.js +++ b/src/renderable/container.js @@ -1,5 +1,5 @@ import utils from "./../utils/utils.js"; -import * as game from "./../game.js"; +import game from "./../game.js"; import * as event from "./../system/event.js"; import pool from "./../system/pooling.js"; import state from "./../state/state.js"; diff --git a/src/renderable/imagelayer.js b/src/renderable/imagelayer.js index d7997e9ffa..0d4ad9de94 100644 --- a/src/renderable/imagelayer.js +++ b/src/renderable/imagelayer.js @@ -1,7 +1,7 @@ import { renderer } from "./../video/video.js"; import * as event from "./../system/event.js"; import pool from "./../system/pooling.js"; -import { viewport } from "./../game.js"; +import game from "./../game.js"; import Sprite from "./sprite.js"; import * as stringUtil from "./../utils/string.js"; @@ -134,7 +134,7 @@ class ImageLayer extends Sprite { this.repeatY = true; break; } - this.resize(viewport.width, viewport.height); + this.resize(game.viewport.width, game.viewport.height); this.createPattern(); } @@ -146,13 +146,13 @@ class ImageLayer extends Sprite { event.on(event.VIEWPORT_ONRESIZE, this.resize, this); // force a first refresh when the level is loaded event.once(event.LEVEL_LOADED, () => { - this.updateLayer(viewport.pos); + this.updateLayer(game.viewport.pos); }); // in case the level is not added to the root container, // the onActivateEvent call happens after the LEVEL_LOADED event // so we need to force a first update if (this.ancestor.root !== true) { - this.updateLayer(viewport.pos); + this.updateLayer(game.viewport.pos); } } @@ -193,8 +193,8 @@ class ImageLayer extends Sprite { var width = this.width, height = this.height, - bw = viewport.bounds.width, - bh = viewport.bounds.height, + bw = game.viewport.bounds.width, + bh = game.viewport.bounds.height, ax = this.anchorPoint.x, ay = this.anchorPoint.y, @@ -204,8 +204,8 @@ class ImageLayer extends Sprite { * See https://github.com/melonjs/melonJS/issues/741#issuecomment-138431532 * for a thorough description of how this works. */ - x = ax * (rx - 1) * (bw - viewport.width) + this.offset.x - rx * vpos.x, - y = ay * (ry - 1) * (bh - viewport.height) + this.offset.y - ry * vpos.y; + x = ax * (rx - 1) * (bw - game.viewport.width) + this.offset.x - rx * vpos.x, + y = ay * (ry - 1) * (bh - game.viewport.height) + this.offset.y - ry * vpos.y; // Repeat horizontally; start drawing from left boundary diff --git a/src/renderable/trigger.js b/src/renderable/trigger.js index 0e807c199a..92a0b6610d 100644 --- a/src/renderable/trigger.js +++ b/src/renderable/trigger.js @@ -2,7 +2,7 @@ import Renderable from "./renderable.js"; import collision from "./../physics/collision.js"; import Body from "./../physics/body.js"; import level from "./../level/level.js"; -import { world, viewport } from "./../game.js"; +import game from "./../game.js"; import pool from "./../system/pooling.js"; /** @@ -89,7 +89,7 @@ class Trigger extends Renderable { getTriggerSettings() { // Lookup for the container instance if (typeof(this.triggerSettings.container) === "string") { - this.triggerSettings.container = world.getChildByName(this.triggerSettings.container)[0]; + this.triggerSettings.container = game.world.getChildByName(this.triggerSettings.container)[0]; } return this.triggerSettings; } @@ -99,7 +99,7 @@ class Trigger extends Renderable { */ onFadeComplete() { level.load(this.gotolevel, this.getTriggerSettings()); - viewport.fadeOut(this.fade, this.duration); + game.viewport.fadeOut(this.fade, this.duration); } /** @@ -118,7 +118,7 @@ class Trigger extends Renderable { if (this.fade && this.duration) { if (!this.fading) { this.fading = true; - viewport.fadeIn(this.fade, this.duration, + game.viewport.fadeIn(this.fade, this.duration, this.onFadeComplete.bind(this)); } } else { diff --git a/src/state/stage.js b/src/state/stage.js index 70d4094786..37816f5924 100644 --- a/src/state/stage.js +++ b/src/state/stage.js @@ -1,5 +1,5 @@ import { renderer } from "./../video/video.js"; -import * as game from "./../game.js"; +import game from "./../game.js"; import Camera2d from "./../camera/camera2d.js"; import Color from "./../math/color.js"; diff --git a/src/state/state.js b/src/state/state.js index 2a40378b37..c58fe5fbdf 100644 --- a/src/state/state.js +++ b/src/state/state.js @@ -1,7 +1,7 @@ import { pauseTrack, resumeTrack } from "./../audio/audio.js"; import * as fctUtil from "./../utils/function.js"; import * as event from "./../system/event.js"; -import * as game from "./../game.js"; +import game from "./../game.js"; import * as device from "./../system/device.js"; import Stage from "./../state/stage.js"; import DefaultLoadingScreen from "./../loader/loadingscreen.js"; diff --git a/src/tweens/tween.js b/src/tweens/tween.js index b2bb36742f..b8e4001b55 100644 --- a/src/tweens/tween.js +++ b/src/tweens/tween.js @@ -1,6 +1,6 @@ import timer from "./../system/timer.js"; import * as event from "./../system/event.js"; -import { world, lastUpdate } from "./../game.js"; +import game from "./../game.js"; import { Easing } from "./easing.js"; import { Interpolation } from "./interpolation.js"; @@ -72,7 +72,7 @@ class Tween { this._onUpdateCallback = null; this._onCompleteCallback = null; // tweens are synchronized with the game update loop - this._tweenTimeTracker = lastUpdate; + this._tweenTimeTracker = game.lastUpdate; // reset flags to default value this.isPersistent = false; @@ -170,7 +170,7 @@ class Tween { this._onStartCallbackFired = false; // add the tween to the object pool on start - world.addChild(this); + game.world.addChild(this); this._startTime = time + this._delayTime; @@ -212,7 +212,7 @@ class Tween { */ stop() { // remove the tween from the world container - world.removeChildNow(this); + game.world.removeChildNow(this); return this; } @@ -349,7 +349,7 @@ class Tween { // the original Tween implementation expect // a timestamp and not a time delta - this._tweenTimeTracker = (lastUpdate > this._tweenTimeTracker) ? lastUpdate : this._tweenTimeTracker + dt; + this._tweenTimeTracker = (game.lastUpdate > this._tweenTimeTracker) ? game.lastUpdate : this._tweenTimeTracker + dt; var time = this._tweenTimeTracker; var property; @@ -442,7 +442,7 @@ class Tween { } else { // remove the tween from the world container - world.removeChildNow(this); + game.world.removeChildNow(this); if ( this._onCompleteCallback !== null ) { diff --git a/src/video/video.js b/src/video/video.js index 13fe01c52b..0e42c69ca6 100644 --- a/src/video/video.js +++ b/src/video/video.js @@ -3,7 +3,7 @@ import WebGLRenderer from "./webgl/webgl_renderer.js"; import CanvasRenderer from "./canvas/canvas_renderer.js"; import utils from "./../utils/utils.js"; import * as event from "./../system/event.js"; -import { repaint } from "./../game.js"; +import game from "./../game.js"; import * as device from "./../system/device.js"; import { initialized, version } from "./../index.js"; @@ -454,5 +454,5 @@ export function scale(x, y) { renderer.setBlendMode(settings.blendMode, context); // force repaint - repaint(); + game.repaint(); };