phaser4-rex-plugins
Version:
662 lines (543 loc) • 21.4 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.rexanchorplugin = factory());
})(this, (function () { 'use strict';
var EventEmitterMethods = {
setEventEmitter(eventEmitter, EventEmitterClass) {
if (EventEmitterClass === undefined) {
EventEmitterClass = Phaser.Events.EventEmitter; // Use built-in EventEmitter class by default
}
this._privateEE = (eventEmitter === true) || (eventEmitter === undefined);
this._eventEmitter = (this._privateEE) ? (new EventEmitterClass()) : eventEmitter;
return this;
},
destroyEventEmitter() {
if (this._eventEmitter && this._privateEE) {
this._eventEmitter.shutdown();
}
return this;
},
getEventEmitter() {
return this._eventEmitter;
},
on() {
if (this._eventEmitter) {
this._eventEmitter.on.apply(this._eventEmitter, arguments);
}
return this;
},
once() {
if (this._eventEmitter) {
this._eventEmitter.once.apply(this._eventEmitter, arguments);
}
return this;
},
off() {
if (this._eventEmitter) {
this._eventEmitter.off.apply(this._eventEmitter, arguments);
}
return this;
},
emit(event) {
if (this._eventEmitter && event) {
this._eventEmitter.emit.apply(this._eventEmitter, arguments);
}
return this;
},
addListener() {
if (this._eventEmitter) {
this._eventEmitter.addListener.apply(this._eventEmitter, arguments);
}
return this;
},
removeListener() {
if (this._eventEmitter) {
this._eventEmitter.removeListener.apply(this._eventEmitter, arguments);
}
return this;
},
removeAllListeners() {
if (this._eventEmitter) {
this._eventEmitter.removeAllListeners.apply(this._eventEmitter, arguments);
}
return this;
},
listenerCount() {
if (this._eventEmitter) {
return this._eventEmitter.listenerCount.apply(this._eventEmitter, arguments);
}
return 0;
},
listeners() {
if (this._eventEmitter) {
return this._eventEmitter.listeners.apply(this._eventEmitter, arguments);
}
return [];
},
eventNames() {
if (this._eventEmitter) {
return this._eventEmitter.eventNames.apply(this._eventEmitter, arguments);
}
return [];
},
};
const SceneClass = Phaser.Scene;
var IsSceneObject = function (object) {
return (object instanceof SceneClass);
};
var GetSceneObject = function (object) {
if ((object == null) || (typeof (object) !== 'object')) {
return null;
} else if (IsSceneObject(object)) { // object = scene
return object;
} else if (object.scene && IsSceneObject(object.scene)) { // object = game object
return object.scene;
} else if (object.parent && object.parent.scene && IsSceneObject(object.parent.scene)) { // parent = bob object
return object.parent.scene;
} else {
return null;
}
};
const GameClass = Phaser.Game;
var IsGame = function (object) {
return (object instanceof GameClass);
};
var GetGame = function (object) {
if ((object == null) || (typeof (object) !== 'object')) {
return null;
} else if (IsGame(object)) {
return object;
} else if (IsGame(object.game)) {
return object.game;
} else if (IsSceneObject(object)) { // object = scene object
return object.sys.game;
} else if (IsSceneObject(object.scene)) { // object = game object
return object.scene.sys.game;
}
};
const GetValue$1 = Phaser.Utils.Objects.GetValue;
class ComponentBase {
constructor(parent, config) {
this.setParent(parent); // gameObject, scene, or game
this.isShutdown = false;
// Event emitter, default is private event emitter
this.setEventEmitter(GetValue$1(config, 'eventEmitter', true));
// Register callback of parent destroy event, also see `shutdown` method
if (this.parent) {
if (this.parent === this.scene) { // parent is a scene
this.scene.sys.events.once('shutdown', this.onEnvDestroy, this);
} else if (this.parent === this.game) { // parent is game
this.game.events.once('shutdown', this.onEnvDestroy, this);
} else if (this.parent.once) { // parent is game object or something else
this.parent.once('destroy', this.onParentDestroy, this);
}
// bob object does not have event emitter
}
}
shutdown(fromScene) {
// Already shutdown
if (this.isShutdown) {
return;
}
// parent might not be shutdown yet
if (this.parent) {
if (this.parent === this.scene) { // parent is a scene
this.scene.sys.events.off('shutdown', this.onEnvDestroy, this);
} else if (this.parent === this.game) { // parent is game
this.game.events.off('shutdown', this.onEnvDestroy, this);
} else if (this.parent.once) { // parent is game object or something else
this.parent.off('destroy', this.onParentDestroy, this);
}
// bob object does not have event emitter
}
this.destroyEventEmitter();
this.parent = undefined;
this.scene = undefined;
this.game = undefined;
this.isShutdown = true;
}
destroy(fromScene) {
this.shutdown(fromScene);
}
onEnvDestroy() {
this.destroy(true);
}
onParentDestroy(parent, fromScene) {
this.destroy(fromScene);
}
setParent(parent) {
this.parent = parent; // gameObject, scene, or game
this.scene = GetSceneObject(parent);
this.game = GetGame(parent);
return this;
}
}
Object.assign(
ComponentBase.prototype,
EventEmitterMethods
);
const CameraClass = Phaser.Cameras.Scene2D.BaseCamera;
var IsCameraObject = function (object) {
return (object instanceof CameraClass);
};
const Rectangle = Phaser.Geom.Rectangle;
var GetViewport = function (scene, camera, out) {
if (!IsCameraObject(camera)) {
out = camera;
camera = undefined;
}
if (out === undefined) {
out = new Rectangle();
} else if (out === true) {
out = globRect;
}
if (camera) {
return scene.scale.getViewPort(camera, out);
} else {
return scene.scale.getViewPort(out);
}
};
var globRect = new Rectangle();
var HasResizeMethod = function (gameObject) {
// 1st pass : Has `resize` method?
if (gameObject.resize) {
return true;
}
// 2nd pass : Has `setSize` method?
// Does not have `setSize` method
if (!gameObject.setSize) {
return false;
}
// Has `setSize` method but only for internal usage.
for (var i = 0, cnt = ExcludeClassList$1.length; i < cnt; i++) {
var excludeClass = ExcludeClassList$1[i];
if (excludeClass && gameObject instanceof excludeClass) {
return false;
}
}
return true;
};
var ExcludeClassList$1 = [
Phaser.GameObjects.Image,
Phaser.GameObjects.Sprite,
Phaser.GameObjects.Mesh,
Phaser.GameObjects.Shader,
Phaser.GameObjects.Video
];
var CanSetDisplaySize = function (gameObject) {
if (gameObject.displayWidth === undefined) {
return false;
}
for (var i = 0, cnt = ExcludeClassList.length; i < cnt; i++) {
var excludeClass = ExcludeClassList[i];
if (excludeClass && gameObject instanceof excludeClass) {
return false;
}
}
return true;
};
var ExcludeClassList = [
Phaser.GameObjects.BitmapText,
];
var ResizeGameObject = function (gameObject, newDisplayWidth, newDisplayHeight) {
// Set display size
if (!gameObject || ((newDisplayWidth === undefined) && (newDisplayHeight === undefined))) {
return;
}
if (HasResizeMethod(gameObject)) { // Has `resize`, or `setSize` method
var newWidth, newHeight;
if (newDisplayWidth === undefined) {
newWidth = gameObject.width;
} else {
newWidth = newDisplayWidth / gameObject.scaleX;
}
if (newDisplayHeight === undefined) {
newHeight = gameObject.height;
} else {
newHeight = newDisplayHeight / gameObject.scaleY;
}
if (gameObject.resize) {
gameObject.resize(newWidth, newHeight);
} else {
gameObject.setSize(newWidth, newHeight);
}
} else {
var canSetDisplaySize = CanSetDisplaySize(gameObject);
if (newDisplayWidth !== undefined) {
if (canSetDisplaySize) {
gameObject.displayWidth = newDisplayWidth;
} else {
gameObject.scaleX = newDisplayWidth / gameObject.width;
}
}
if (newDisplayHeight !== undefined) {
if (canSetDisplaySize) {
gameObject.displayHeight = newDisplayHeight;
} else {
gameObject.scaleY = newDisplayHeight / gameObject.height;
}
}
}
};
var DefaultResizeCallback = function (width, height, gameObject, anchor) {
ResizeGameObject(gameObject, width, height);
};
const GetValue = Phaser.Utils.Objects.GetValue;
class Anchor extends ComponentBase {
constructor(gameObject, config) {
super(gameObject, { eventEmitter: false });
// No event emitter
// this.parent = gameObject;
this.viewport = undefined;
this.resetFromJSON(config);
}
shutdown(fromScene) {
// Already shutdown
if (this.isShutdown) {
return;
}
this.autoAnchor(false);
this.viewport = undefined;
this.onUpdateViewportCallback = undefined;
this.onUpdateViewportCallbackScope = undefined;
this.onResizeCallback = undefined;
this.onResizeCallbackScope = undefined;
super.shutdown(fromScene);
}
resetFromJSON(o) {
if (o === undefined) {
o = {};
}
var gameObject = this.parent;
// Position
var alignX, configX;
if (o.x !== undefined) {
alignX = null;
configX = o.x;
} else if (o.left !== undefined) {
alignX = 0;
configX = o.left;
} else if (o.right !== undefined) {
alignX = 1;
configX = o.right;
} else if (o.centerX !== undefined) {
alignX = 0.5;
configX = o.centerX;
}
var alignY, configY;
if (o.y !== undefined) {
alignY = null;
configY = o.y;
} else if (o.top !== undefined) {
alignY = 0;
configY = o.top;
} else if (o.bottom !== undefined) {
alignY = 1;
configY = o.bottom;
} else if (o.centerY !== undefined) {
alignY = 0.5;
configY = o.centerY;
}
var percentageX, offsetX;
if (configX !== undefined) {
configX = configX.replace('left', '0%').replace('right', '100%').replace('center', '50%').split('%');
percentageX = parseFloat(configX[0]) / 100;
offsetX = (configX[1] === '') ? 0 : parseFloat(configX[1]);
}
var percentageY, offsetY;
if (configY !== undefined) {
configY = configY.replace('top', '0%').replace('bottom', '100%').replace('center', '50%').split('%');
percentageY = parseFloat(configY[0]) / 100;
offsetY = (configY[1] === '') ? 0 : parseFloat(configY[1]);
}
// Size
var configWidth = o.width;
var percentageWidth, paddingWidth;
if (configWidth !== undefined) {
configWidth = configWidth.split('%');
percentageWidth = parseFloat(configWidth[0]) / 100;
paddingWidth = (configWidth[1] === '') ? 0 : parseFloat(configWidth[1]);
}
var configHeight = o.height;
var percentageHeight, paddingHeight;
if (configHeight !== undefined) {
configHeight = configHeight.split('%');
percentageHeight = parseFloat(configHeight[0]) / 100;
paddingHeight = (configHeight[1] === '') ? 0 : parseFloat(configHeight[1]);
}
var aspectRatio = o.aspectRatio;
if (aspectRatio === true) {
aspectRatio = gameObject.displayWidth / gameObject.displayHeight;
}
// Position
this.setAlign(alignX, alignY);
this.setPercentage(percentageX, percentageY);
this.setOffset(offsetX, offsetY);
// Size
this.setSizePercentage(percentageWidth, percentageHeight);
this.setSizePadding(paddingWidth, paddingHeight);
this.setAspectRatio(aspectRatio);
var onResizeCallback = GetValue(o, 'onResizeCallback', DefaultResizeCallback);
var onResizeCallbackScope = GetValue(o, 'onResizeCallbackScope');
this.setResizeCallback(onResizeCallback, onResizeCallbackScope);
var onUpdateViewportCallback = GetValue(o, 'onUpdateViewportCallback');
var onUpdateViewportCallbackScope = GetValue(o, 'onUpdateViewportCallbackScope');
this.setUpdateViewportCallback(onUpdateViewportCallback, onUpdateViewportCallbackScope);
this.autoAnchor(o.enable);
return this;
}
autoAnchor(enable) {
if (enable === undefined) {
enable = true;
}
enable = !!enable;
if (this.autoAnchorEnable === enable) {
return this;
}
if (enable) {
this.scene.sys.scale.on('resize', this.anchor, this);
this.anchor();
} else {
this.scene.sys.scale.off('resize', this.anchor, this);
}
this.autoAnchorEnable = enable;
return this;
}
// Position
setAlign(x, y) {
this.alignX = x;
this.alignY = y;
return this;
}
setPercentage(x, y) {
this.percentageX = x;
this.percentageY = y;
return this;
}
setOffset(x, y) {
this.offsetX = x;
this.offsetY = y;
return this;
}
// Size
setSizePercentage(width, height) {
this.percentageWidth = width;
this.percentageHeight = height;
return this;
}
setSizePadding(width, height) {
this.paddingWidth = width;
this.paddingHeight = height;
return this;
}
setAspectRatio(aspectRatio) {
this.aspectRatio = aspectRatio;
return this;
}
setResizeCallback(callback, scope) {
this.onResizeCallback = callback;
this.onResizeCallbackScope = scope;
return this;
}
setUpdateViewportCallback(callback, scope) {
this.onUpdateViewportCallback = callback;
this.onUpdateViewportCallbackScope = scope;
return this;
}
anchor() {
this.updateViewport();
this.updateSize();
this.updatePosition();
return this;
}
updateSize() {
var callback = this.onResizeCallback,
scope = this.onResizeCallbackScope;
var newWidth = this.anchorWidth,
newHeight = this.anchorHeight;
if (((newWidth === undefined) && (newHeight === undefined)) || !callback) {
return;
}
var gameObject = this.parent;
if (newWidth === undefined) {
if (this.aspectRatio && newHeight) {
newWidth = this.aspectRatio * newHeight;
} else {
newWidth = gameObject.width;
}
}
if (newHeight === undefined) {
if (this.aspectRatio && newWidth) {
newHeight = newWidth / this.aspectRatio;
} else {
newHeight = gameObject.height;
}
}
if (scope) {
callback.call(scope, newWidth, newHeight, gameObject, this);
} else {
callback(newWidth, newHeight, gameObject, this);
}
}
updatePosition() {
var gameObject = this.parent;
if (this.alignX === null) {
gameObject.x = this.anchorX;
} else if (this.alignX !== undefined) {
gameObject.x = this.anchorX + (gameObject.displayWidth * (gameObject.originX - this.alignX));
}
if (this.alignY === null) {
gameObject.y = this.anchorY;
} else if (this.alignY !== undefined) {
gameObject.y = this.anchorY + (gameObject.displayHeight * (gameObject.originY - this.alignY));
}
return this;
}
get anchorX() {
return this.viewport.x + (this.viewport.width * this.percentageX) + this.offsetX;
}
get anchorY() {
return this.viewport.y + (this.viewport.height * this.percentageY) + this.offsetY;
}
get anchorWidth() {
if (this.percentageWidth === undefined) {
return undefined;
}
return (this.viewport.width * this.percentageWidth) + this.paddingWidth;
}
get anchorHeight() {
if (this.percentageHeight === undefined) {
return undefined;
}
return (this.viewport.height * this.percentageHeight) + this.paddingHeight;
}
updateViewport() {
var camera = this.parent.scene.cameras.main;
this.viewport = GetViewport(this.scene, camera, this.viewport);
var viewport = this.viewport;
var callback = this.onUpdateViewportCallback,
scope = this.onUpdateViewportCallbackScope;
if (callback) {
if (scope) {
callback.call(scope, viewport, this.parent, this);
} else {
callback(viewport, this.parent, this);
}
}
}
}
class AnchorPlugin extends Phaser.Plugins.BasePlugin {
constructor(pluginManager) {
super(pluginManager);
}
start() {
var eventEmitter = this.game.events;
eventEmitter.on('destroy', this.destroy, this);
}
add(gameObject, config) {
return new Anchor(gameObject, config);
}
}
return AnchorPlugin;
}));