Skip to content

Commit

Permalink
[#1091] further code revamping/reshuffling to enable instantiable gam…
Browse files Browse the repository at this point in the history
…e Application
  • Loading branch information
obiot committed Dec 13, 2022
1 parent 5edbadc commit 196eda3
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 184 deletions.
33 changes: 20 additions & 13 deletions src/application/application.js
Expand Up @@ -12,25 +12,29 @@ import World from "./../physics/world.js";
*/
export default class Application {
constructor() {

/**
* the parent HTML element holding the main canvas of this application
* @type {HTMLElement}
*/
this.parentElement = undefined;

/**
* a reference to the current active stage "default" camera
* @public
* the active stage "default" camera
* @type {Camera2d}
*/
this.viewport = undefined;

/**
* a reference to the game world, <br>
* a world is a virtual environment containing all the game objects
* @public
* @type {World}
*/
this.world = undefined;

/**
* when true, all objects will be added under the root world container.<br>
* When false, a `me.Container` object will be created for each corresponding groups
* @public
* @type {boolean}
* @default true
*/
Expand All @@ -39,7 +43,6 @@ import World from "./../physics/world.js";
/**
* Specify the property to be used when sorting renderables.
* Accepted values : "x", "y", "z"
* @public
* @type {string}
* @default "z"
*/
Expand All @@ -50,13 +53,17 @@ import World from "./../physics/world.js";
* 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;

/**
* true when this app instance has been initialized
* @type {boolean}
* @default false
*/
this.isInitialized = false;

// to know when we have to refresh the display
this.isDirty = true;

Expand Down Expand Up @@ -89,6 +96,7 @@ import World from "./../physics/world.js";
// set the reference to this application instance
this.world.app = this;
this.lastUpdate = globalThis.performance.now();
this.isInitialized = true;
event.emit(event.GAME_INIT, this);
}

Expand Down Expand Up @@ -140,12 +148,11 @@ import World from "./../physics/world.js";
}

/**
* Returns the parent container of the specified Child in the game world
* @param {Renderable} child
* @returns {Container}
* Returns the parent HTML Element holding the main canvas of this application
* @returns {HTMLElement}
*/
getParentContainer(child) {
return child.ancestor;
getParentElement() {
return this.parentElement;
}

/**
Expand Down
8 changes: 4 additions & 4 deletions src/input/pointerevent.js
@@ -1,6 +1,6 @@
import {preventDefault} from "./input.js";
import {getBindingKey, triggerKeyEvent} from "./keyboard.js";
import { renderer, scaleRatio, getParent } from "./../video/video.js";
import { renderer } from "./../video/video.js";
import { throttle } from "./../utils/function.js";
import { remove } from "./../utils/array.js";
import * as event from "./../system/event.js";
Expand Down Expand Up @@ -195,7 +195,7 @@ function enablePointerEvent() {
if (device.hasPointerLockSupport) {
document.addEventListener("pointerlockchange", () => {
// change the locked status accordingly
locked = document.pointerLockElement === getParent();
locked = document.pointerLockElement === game.getParentElement();
// emit the corresponding internal event
event.emit(event.POINTERLOCKCHANGE, locked);
}, true);
Expand Down Expand Up @@ -560,7 +560,7 @@ export function globalToLocal(x, y, v) {
var pixelRatio = globalThis.devicePixelRatio || 1;
x -= rect.left + (globalThis.pageXOffset || 0);
y -= rect.top + (globalThis.pageYOffset || 0);
var scale = scaleRatio;
var scale = renderer.scaleRatio;
if (scale.x !== 1.0 || scale.y !== 1.0) {
x /= scale.x;
y /= scale.y;
Expand Down Expand Up @@ -786,7 +786,7 @@ export function releaseAllPointerEvents(region) {
*/
export function requestPointerLock() {
if (device.hasPointerLockSupport) {
var element = getParent();
var element = game.getParentElement();
element.requestPointerLock();
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion src/system/device.js
Expand Up @@ -473,7 +473,7 @@ export function isFullscreen() {
* @function requestFullscreen
* @memberof device
* @public
* @param {object} [element=default canvas object] - the element to be set in full-screen mode.
* @param {Element} [element] - the element to be set in full-screen mode.
* @example
* // add a keyboard shortcut to toggle Fullscreen mode on/off
* me.input.bindKey(me.input.KEY.F, "toggleFullscreen");
Expand Down
27 changes: 20 additions & 7 deletions src/video/renderer.js
@@ -1,8 +1,8 @@
import Color from "./../math/color.js";
import Matrix3d from "./../math/matrix3.js";
import { createCanvas, renderer } from "./video.js";
import { createCanvas } from "./video.js";
import * as event from "./../system/event.js";
import * as device from "./../system/device.js";
import { platform } from "../system/device.js";
import { setPrefixed } from "./../utils/agent.js";
import Rect from "./../geometries/rectangle.js";
import RoundRect from "./../geometries/roundrect.js";
Expand All @@ -11,6 +11,7 @@ import Polygon from "./../geometries/poly.js";
import Line from "./../geometries/line.js";
import Bounds from "./../physics/bounds.js";
import Path2D from "./../geometries/path2d.js";
import Vector2d from "../math/vector2.js";
import Point from "../geometries/point.js";

/**
Expand Down Expand Up @@ -41,6 +42,20 @@ import Point from "../geometries/point.js";
*/
this.settings = options;

/**
* the requested video size ratio
* @public
* @type {Number}
*/
this.designRatio = this.settings.width / this.settings.height;

/**
* the scaling ratio to be applied to the main canvas
* @type {Vector2d}
* @default <1,1>
*/
this.scaleRatio = new Vector2d(this.settings.scale, this.settings.scale);

/**
* true if the current rendering context is valid
* @default true
Expand Down Expand Up @@ -70,7 +85,7 @@ import Point from "../geometries/point.js";
this.currentBlendMode = "none";

// create the main screen canvas
if (device.platform.ejecta === true) {
if (platform.ejecta === true) {
// a main canvas is already automatically created by Ejecta
this.canvas = document.getElementById("canvas");
} else if (typeof globalThis.canvas !== "undefined") {
Expand All @@ -94,9 +109,9 @@ import Point from "../geometries/point.js";
// default uvOffset
this.uvOffset = 0;

// reset the instantiated renderer on game reset
// reset the renderer on game reset
event.on(event.GAME_RESET, () => {
renderer.reset();
this.reset();
});
}

Expand Down Expand Up @@ -323,8 +338,6 @@ import Point from "../geometries/point.js";

/**
* fill the given shape
* @name fill
* @memberof Renderer
* @param {Rect|RoundRect|Polygon|Line|Ellipse} shape - a shape object to fill
*/
fill(shape) {
Expand Down
107 changes: 107 additions & 0 deletions src/video/utils/resize.js
@@ -0,0 +1,107 @@
import * as device from "./../../system/device.js";
import game from "./../../game.js";

/**
* scale the "displayed" canvas by the given scalar.
* this will modify the size of canvas element directly.
* Only use this if you are not using the automatic scaling feature.
* @param {number} x - x scaling multiplier
* @param {number} y - y scaling multiplier
*/
function scale(renderer, x, y) {
var canvas = renderer.getCanvas();
var context = renderer.getContext();
var settings = renderer.settings;
var pixelRatio = device.devicePixelRatio;

var w = settings.zoomX = canvas.width * x * pixelRatio;
var h = settings.zoomY = canvas.height * y * pixelRatio;

// update the global scale variable
renderer.scaleRatio.set(x * pixelRatio, y * pixelRatio);

// adjust CSS style based on device pixel ratio
canvas.style.width = (w / pixelRatio) + "px";
canvas.style.height = (h / pixelRatio) + "px";

// if anti-alias and blend mode were resetted (e.g. Canvas mode)
renderer.setAntiAlias(context, settings.antiAlias);
renderer.setBlendMode(settings.blendMode, context);

// force repaint
game.repaint();
}

/**
* callback for window resize event
*/
export function onresize(renderer) {
var settings = renderer.settings;
var scaleX = 1, scaleY = 1;

if (settings.autoScale) {

// set max the canvas max size if CSS values are defined
var canvasMaxWidth = Infinity;
var canvasMaxHeight = Infinity;

if (globalThis.getComputedStyle) {
var style = globalThis.getComputedStyle(renderer.getCanvas(), null);
canvasMaxWidth = parseInt(style.maxWidth, 10) || Infinity;
canvasMaxHeight = parseInt(style.maxHeight, 10) || Infinity;
}

// get the maximum canvas size within the parent div containing the canvas container
var nodeBounds = device.getParentBounds(game.getParentElement());

var _max_width = Math.min(canvasMaxWidth, nodeBounds.width);
var _max_height = Math.min(canvasMaxHeight, nodeBounds.height);

// calculate final canvas width & height
var screenRatio = _max_width / _max_height;

if ((settings.scaleMethod === "fill-min" && screenRatio > renderer.designRatio) ||
(settings.scaleMethod === "fill-max" && screenRatio < renderer.designRatio) ||
(settings.scaleMethod === "flex-width")
) {
// resize the display canvas to fill the parent container
var sWidth = Math.min(canvasMaxWidth, settings.height * screenRatio);
scaleX = scaleY = _max_width / sWidth;
renderer.resize(Math.floor(sWidth), settings.height);
}
else if ((settings.scaleMethod === "fill-min" && screenRatio < renderer.designRatio) ||
(settings.scaleMethod === "fill-max" && screenRatio > renderer.designRatio) ||
(settings.scaleMethod === "flex-height")
) {
// resize the display canvas to fill the parent container
var sHeight = Math.min(canvasMaxHeight, settings.width * (_max_height / _max_width));
scaleX = scaleY = _max_height / sHeight;
renderer.resize(settings.width, Math.floor(sHeight));
}
else if (settings.scaleMethod === "flex") {
// resize the display canvas to fill the parent container
renderer.resize(Math.floor(_max_width), Math.floor(_max_height));
}
else if (settings.scaleMethod === "stretch") {
// scale the display canvas to fit with the parent container
scaleX = _max_width / settings.width;
scaleY = _max_height / settings.height;
}
else {
// scale the display canvas to fit the parent container
// make sure we maintain the original aspect ratio
if (screenRatio < renderer.designRatio) {
scaleX = scaleY = _max_width / settings.width;
}
else {
scaleX = scaleY = _max_height / settings.height;
}
}

// adjust scaling ratio based on the new scaling ratio
scale(renderer, scaleX, scaleY);
} else {
// adjust scaling ratio based on the given settings
scale(renderer, settings.scale, settings.scale);
}
}

0 comments on commit 196eda3

Please sign in to comment.