silver-fang-mini-game/node_modules/.vite/deps/phaser.js
2024-10-27 19:54:14 +02:00

138737 lines
6.3 MiB

var __getOwnPropNames = Object.getOwnPropertyNames;
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
// node_modules/phaser/dist/phaser.js
var require_phaser = __commonJS({
"node_modules/phaser/dist/phaser.js"(exports, module) {
(function webpackUniversalModuleDefinition(root, factory) {
if (typeof exports === "object" && typeof module === "object")
module.exports = factory();
else if (typeof define === "function" && define.amd)
define("Phaser", [], factory);
else if (typeof exports === "object")
exports["Phaser"] = factory();
else
root["Phaser"] = factory();
})(exports, () => {
return (
/******/
(() => {
var __webpack_modules__ = {
/***/
50792: (
/***/
(module2) => {
"use strict";
var has = Object.prototype.hasOwnProperty, prefix = "~";
function Events() {
}
if (Object.create) {
Events.prototype = /* @__PURE__ */ Object.create(null);
if (!new Events().__proto__) prefix = false;
}
function EE(fn, context, once) {
this.fn = fn;
this.context = context;
this.once = once || false;
}
function addListener(emitter, event, fn, context, once) {
if (typeof fn !== "function") {
throw new TypeError("The listener must be a function");
}
var listener = new EE(fn, context || emitter, once), evt = prefix ? prefix + event : event;
if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
else emitter._events[evt] = [emitter._events[evt], listener];
return emitter;
}
function clearEvent(emitter, evt) {
if (--emitter._eventsCount === 0) emitter._events = new Events();
else delete emitter._events[evt];
}
function EventEmitter() {
this._events = new Events();
this._eventsCount = 0;
}
EventEmitter.prototype.eventNames = function eventNames() {
var names = [], events, name;
if (this._eventsCount === 0) return names;
for (name in events = this._events) {
if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
}
if (Object.getOwnPropertySymbols) {
return names.concat(Object.getOwnPropertySymbols(events));
}
return names;
};
EventEmitter.prototype.listeners = function listeners(event) {
var evt = prefix ? prefix + event : event, handlers = this._events[evt];
if (!handlers) return [];
if (handlers.fn) return [handlers.fn];
for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
ee[i] = handlers[i].fn;
}
return ee;
};
EventEmitter.prototype.listenerCount = function listenerCount(event) {
var evt = prefix ? prefix + event : event, listeners = this._events[evt];
if (!listeners) return 0;
if (listeners.fn) return 1;
return listeners.length;
};
EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
var evt = prefix ? prefix + event : event;
if (!this._events[evt]) return false;
var listeners = this._events[evt], len = arguments.length, args, i;
if (listeners.fn) {
if (listeners.once) this.removeListener(event, listeners.fn, void 0, true);
switch (len) {
case 1:
return listeners.fn.call(listeners.context), true;
case 2:
return listeners.fn.call(listeners.context, a1), true;
case 3:
return listeners.fn.call(listeners.context, a1, a2), true;
case 4:
return listeners.fn.call(listeners.context, a1, a2, a3), true;
case 5:
return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
case 6:
return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
}
for (i = 1, args = new Array(len - 1); i < len; i++) {
args[i - 1] = arguments[i];
}
listeners.fn.apply(listeners.context, args);
} else {
var length = listeners.length, j;
for (i = 0; i < length; i++) {
if (listeners[i].once) this.removeListener(event, listeners[i].fn, void 0, true);
switch (len) {
case 1:
listeners[i].fn.call(listeners[i].context);
break;
case 2:
listeners[i].fn.call(listeners[i].context, a1);
break;
case 3:
listeners[i].fn.call(listeners[i].context, a1, a2);
break;
case 4:
listeners[i].fn.call(listeners[i].context, a1, a2, a3);
break;
default:
if (!args) for (j = 1, args = new Array(len - 1); j < len; j++) {
args[j - 1] = arguments[j];
}
listeners[i].fn.apply(listeners[i].context, args);
}
}
}
return true;
};
EventEmitter.prototype.on = function on(event, fn, context) {
return addListener(this, event, fn, context, false);
};
EventEmitter.prototype.once = function once(event, fn, context) {
return addListener(this, event, fn, context, true);
};
EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
var evt = prefix ? prefix + event : event;
if (!this._events[evt]) return this;
if (!fn) {
clearEvent(this, evt);
return this;
}
var listeners = this._events[evt];
if (listeners.fn) {
if (listeners.fn === fn && (!once || listeners.once) && (!context || listeners.context === context)) {
clearEvent(this, evt);
}
} else {
for (var i = 0, events = [], length = listeners.length; i < length; i++) {
if (listeners[i].fn !== fn || once && !listeners[i].once || context && listeners[i].context !== context) {
events.push(listeners[i]);
}
}
if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
else clearEvent(this, evt);
}
return this;
};
EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
var evt;
if (event) {
evt = prefix ? prefix + event : event;
if (this._events[evt]) clearEvent(this, evt);
} else {
this._events = new Events();
this._eventsCount = 0;
}
return this;
};
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
EventEmitter.prototype.addListener = EventEmitter.prototype.on;
EventEmitter.prefixed = prefix;
EventEmitter.EventEmitter = EventEmitter;
if (true) {
module2.exports = EventEmitter;
}
}
),
/***/
11517: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var QuickSet = __webpack_require__2(38829);
var AlignTo = function(items, position, offsetX, offsetY) {
var target = items[0];
for (var i = 1; i < items.length; i++) {
var item = items[i];
QuickSet(item, target, position, offsetX, offsetY);
target = item;
}
return items;
};
module2.exports = AlignTo;
}
),
/***/
80318: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PropertyValueInc = __webpack_require__2(66979);
var Angle = function(items, value, step, index, direction) {
return PropertyValueInc(items, "angle", value, step, index, direction);
};
module2.exports = Angle;
}
),
/***/
60757: (
/***/
(module2) => {
var Call = function(items, callback, context) {
for (var i = 0; i < items.length; i++) {
var item = items[i];
callback.call(context, item);
}
return items;
};
module2.exports = Call;
}
),
/***/
69927: (
/***/
(module2) => {
var GetFirst = function(items, compare, index) {
if (index === void 0) {
index = 0;
}
for (var i = index; i < items.length; i++) {
var item = items[i];
var match = true;
for (var property in compare) {
if (item[property] !== compare[property]) {
match = false;
}
}
if (match) {
return item;
}
}
return null;
};
module2.exports = GetFirst;
}
),
/***/
32265: (
/***/
(module2) => {
var GetLast = function(items, compare, index) {
if (index === void 0) {
index = 0;
}
for (var i = items.length - 1; i >= index; i--) {
var item = items[i];
var match = true;
for (var property in compare) {
if (item[property] !== compare[property]) {
match = false;
}
}
if (match) {
return item;
}
}
return null;
};
module2.exports = GetLast;
}
),
/***/
94420: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var AlignIn = __webpack_require__2(11879);
var CONST = __webpack_require__2(60461);
var GetFastValue = __webpack_require__2(95540);
var NOOP = __webpack_require__2(29747);
var Zone = __webpack_require__2(41481);
var tempZone = new Zone({ sys: { queueDepthSort: NOOP, events: { once: NOOP } } }, 0, 0, 1, 1).setOrigin(0, 0);
var GridAlign = function(items, options) {
if (options === void 0) {
options = {};
}
var widthSet = options.hasOwnProperty("width");
var heightSet = options.hasOwnProperty("height");
var width = GetFastValue(options, "width", -1);
var height = GetFastValue(options, "height", -1);
var cellWidth = GetFastValue(options, "cellWidth", 1);
var cellHeight = GetFastValue(options, "cellHeight", cellWidth);
var position = GetFastValue(options, "position", CONST.TOP_LEFT);
var x = GetFastValue(options, "x", 0);
var y = GetFastValue(options, "y", 0);
var cx = 0;
var cy = 0;
var w = width * cellWidth;
var h = height * cellHeight;
tempZone.setPosition(x, y);
tempZone.setSize(cellWidth, cellHeight);
for (var i = 0; i < items.length; i++) {
AlignIn(items[i], tempZone, position);
if (widthSet && width === -1) {
tempZone.x += cellWidth;
} else if (heightSet && height === -1) {
tempZone.y += cellHeight;
} else if (heightSet && !widthSet) {
cy += cellHeight;
tempZone.y += cellHeight;
if (cy === h) {
cy = 0;
cx += cellWidth;
tempZone.y = y;
tempZone.x += cellWidth;
if (cx === w) {
break;
}
}
} else {
cx += cellWidth;
tempZone.x += cellWidth;
if (cx === w) {
cx = 0;
cy += cellHeight;
tempZone.x = x;
tempZone.y += cellHeight;
if (cy === h) {
break;
}
}
}
}
return items;
};
module2.exports = GridAlign;
}
),
/***/
41721: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PropertyValueInc = __webpack_require__2(66979);
var IncAlpha = function(items, value, step, index, direction) {
return PropertyValueInc(items, "alpha", value, step, index, direction);
};
module2.exports = IncAlpha;
}
),
/***/
67285: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PropertyValueInc = __webpack_require__2(66979);
var IncX = function(items, value, step, index, direction) {
return PropertyValueInc(items, "x", value, step, index, direction);
};
module2.exports = IncX;
}
),
/***/
9074: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PropertyValueInc = __webpack_require__2(66979);
var IncXY = function(items, x, y, stepX, stepY, index, direction) {
if (y === void 0 || y === null) {
y = x;
}
PropertyValueInc(items, "x", x, stepX, index, direction);
return PropertyValueInc(items, "y", y, stepY, index, direction);
};
module2.exports = IncXY;
}
),
/***/
75222: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PropertyValueInc = __webpack_require__2(66979);
var IncY = function(items, value, step, index, direction) {
return PropertyValueInc(items, "y", value, step, index, direction);
};
module2.exports = IncY;
}
),
/***/
22983: (
/***/
(module2) => {
var PlaceOnCircle = function(items, circle, startAngle, endAngle) {
if (startAngle === void 0) {
startAngle = 0;
}
if (endAngle === void 0) {
endAngle = 6.28;
}
var angle = startAngle;
var angleStep = (endAngle - startAngle) / items.length;
var cx = circle.x;
var cy = circle.y;
var radius = circle.radius;
for (var i = 0; i < items.length; i++) {
items[i].x = cx + radius * Math.cos(angle);
items[i].y = cy + radius * Math.sin(angle);
angle += angleStep;
}
return items;
};
module2.exports = PlaceOnCircle;
}
),
/***/
95253: (
/***/
(module2) => {
var PlaceOnEllipse = function(items, ellipse, startAngle, endAngle) {
if (startAngle === void 0) {
startAngle = 0;
}
if (endAngle === void 0) {
endAngle = 6.28;
}
var angle = startAngle;
var angleStep = (endAngle - startAngle) / items.length;
var a = ellipse.width / 2;
var b = ellipse.height / 2;
for (var i = 0; i < items.length; i++) {
items[i].x = ellipse.x + a * Math.cos(angle);
items[i].y = ellipse.y + b * Math.sin(angle);
angle += angleStep;
}
return items;
};
module2.exports = PlaceOnEllipse;
}
),
/***/
88505: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetPoints = __webpack_require__2(15258);
var GetEasedPoints = __webpack_require__2(26708);
var PlaceOnLine = function(items, line, ease) {
var points;
if (ease) {
points = GetEasedPoints(line, ease, items.length);
} else {
points = GetPoints(line, items.length);
}
for (var i = 0; i < items.length; i++) {
var item = items[i];
var point = points[i];
item.x = point.x;
item.y = point.y;
}
return items;
};
module2.exports = PlaceOnLine;
}
),
/***/
41346: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var MarchingAnts = __webpack_require__2(14649);
var RotateLeft = __webpack_require__2(86003);
var RotateRight = __webpack_require__2(49498);
var PlaceOnRectangle = function(items, rect, shift) {
if (shift === void 0) {
shift = 0;
}
var points = MarchingAnts(rect, false, items.length);
if (shift > 0) {
RotateLeft(points, shift);
} else if (shift < 0) {
RotateRight(points, Math.abs(shift));
}
for (var i = 0; i < items.length; i++) {
items[i].x = points[i].x;
items[i].y = points[i].y;
}
return items;
};
module2.exports = PlaceOnRectangle;
}
),
/***/
11575: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BresenhamPoints = __webpack_require__2(84993);
var PlaceOnTriangle = function(items, triangle, stepRate) {
var p1 = BresenhamPoints({ x1: triangle.x1, y1: triangle.y1, x2: triangle.x2, y2: triangle.y2 }, stepRate);
var p2 = BresenhamPoints({ x1: triangle.x2, y1: triangle.y2, x2: triangle.x3, y2: triangle.y3 }, stepRate);
var p3 = BresenhamPoints({ x1: triangle.x3, y1: triangle.y3, x2: triangle.x1, y2: triangle.y1 }, stepRate);
p1.pop();
p2.pop();
p3.pop();
p1 = p1.concat(p2, p3);
var step = p1.length / items.length;
var p = 0;
for (var i = 0; i < items.length; i++) {
var item = items[i];
var point = p1[Math.floor(p)];
item.x = point.x;
item.y = point.y;
p += step;
}
return items;
};
module2.exports = PlaceOnTriangle;
}
),
/***/
29953: (
/***/
(module2) => {
var PlayAnimation = function(items, key, ignoreIfPlaying) {
for (var i = 0; i < items.length; i++) {
var gameObject = items[i];
if (gameObject.anims) {
gameObject.anims.play(key, ignoreIfPlaying);
}
}
return items;
};
module2.exports = PlayAnimation;
}
),
/***/
66979: (
/***/
(module2) => {
var PropertyValueInc = function(items, key, value, step, index, direction) {
if (step === void 0) {
step = 0;
}
if (index === void 0) {
index = 0;
}
if (direction === void 0) {
direction = 1;
}
var i;
var t = 0;
var end = items.length;
if (direction === 1) {
for (i = index; i < end; i++) {
items[i][key] += value + t * step;
t++;
}
} else {
for (i = index; i >= 0; i--) {
items[i][key] += value + t * step;
t++;
}
}
return items;
};
module2.exports = PropertyValueInc;
}
),
/***/
43967: (
/***/
(module2) => {
var PropertyValueSet = function(items, key, value, step, index, direction) {
if (step === void 0) {
step = 0;
}
if (index === void 0) {
index = 0;
}
if (direction === void 0) {
direction = 1;
}
var i;
var t = 0;
var end = items.length;
if (direction === 1) {
for (i = index; i < end; i++) {
items[i][key] = value + t * step;
t++;
}
} else {
for (i = index; i >= 0; i--) {
items[i][key] = value + t * step;
t++;
}
}
return items;
};
module2.exports = PropertyValueSet;
}
),
/***/
88926: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Random = __webpack_require__2(28176);
var RandomCircle = function(items, circle) {
for (var i = 0; i < items.length; i++) {
Random(circle, items[i]);
}
return items;
};
module2.exports = RandomCircle;
}
),
/***/
33286: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Random = __webpack_require__2(24820);
var RandomEllipse = function(items, ellipse) {
for (var i = 0; i < items.length; i++) {
Random(ellipse, items[i]);
}
return items;
};
module2.exports = RandomEllipse;
}
),
/***/
96e3: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Random = __webpack_require__2(65822);
var RandomLine = function(items, line) {
for (var i = 0; i < items.length; i++) {
Random(line, items[i]);
}
return items;
};
module2.exports = RandomLine;
}
),
/***/
28789: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Random = __webpack_require__2(26597);
var RandomRectangle = function(items, rect) {
for (var i = 0; i < items.length; i++) {
Random(rect, items[i]);
}
return items;
};
module2.exports = RandomRectangle;
}
),
/***/
97154: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Random = __webpack_require__2(90260);
var RandomTriangle = function(items, triangle) {
for (var i = 0; i < items.length; i++) {
Random(triangle, items[i]);
}
return items;
};
module2.exports = RandomTriangle;
}
),
/***/
20510: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PropertyValueInc = __webpack_require__2(66979);
var Rotate = function(items, value, step, index, direction) {
return PropertyValueInc(items, "rotation", value, step, index, direction);
};
module2.exports = Rotate;
}
),
/***/
91051: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var RotateAroundDistance = __webpack_require__2(1163);
var DistanceBetween = __webpack_require__2(20339);
var RotateAround = function(items, point, angle) {
var x = point.x;
var y = point.y;
for (var i = 0; i < items.length; i++) {
var item = items[i];
RotateAroundDistance(item, x, y, angle, Math.max(1, DistanceBetween(item.x, item.y, x, y)));
}
return items;
};
module2.exports = RotateAround;
}
),
/***/
76332: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var MathRotateAroundDistance = __webpack_require__2(1163);
var RotateAroundDistance = function(items, point, angle, distance) {
var x = point.x;
var y = point.y;
if (distance === 0) {
return items;
}
for (var i = 0; i < items.length; i++) {
MathRotateAroundDistance(items[i], x, y, angle, distance);
}
return items;
};
module2.exports = RotateAroundDistance;
}
),
/***/
61619: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PropertyValueInc = __webpack_require__2(66979);
var ScaleX = function(items, value, step, index, direction) {
return PropertyValueInc(items, "scaleX", value, step, index, direction);
};
module2.exports = ScaleX;
}
),
/***/
94868: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PropertyValueInc = __webpack_require__2(66979);
var ScaleXY = function(items, scaleX, scaleY, stepX, stepY, index, direction) {
if (scaleY === void 0 || scaleY === null) {
scaleY = scaleX;
}
PropertyValueInc(items, "scaleX", scaleX, stepX, index, direction);
return PropertyValueInc(items, "scaleY", scaleY, stepY, index, direction);
};
module2.exports = ScaleXY;
}
),
/***/
95532: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PropertyValueInc = __webpack_require__2(66979);
var ScaleY = function(items, value, step, index, direction) {
return PropertyValueInc(items, "scaleY", value, step, index, direction);
};
module2.exports = ScaleY;
}
),
/***/
8689: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PropertyValueSet = __webpack_require__2(43967);
var SetAlpha = function(items, value, step, index, direction) {
return PropertyValueSet(items, "alpha", value, step, index, direction);
};
module2.exports = SetAlpha;
}
),
/***/
2645: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PropertyValueSet = __webpack_require__2(43967);
var SetBlendMode = function(items, value, index, direction) {
return PropertyValueSet(items, "blendMode", value, 0, index, direction);
};
module2.exports = SetBlendMode;
}
),
/***/
32372: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PropertyValueSet = __webpack_require__2(43967);
var SetDepth = function(items, value, step, index, direction) {
return PropertyValueSet(items, "depth", value, step, index, direction);
};
module2.exports = SetDepth;
}
),
/***/
85373: (
/***/
(module2) => {
var SetHitArea = function(items, hitArea, hitAreaCallback) {
for (var i = 0; i < items.length; i++) {
items[i].setInteractive(hitArea, hitAreaCallback);
}
return items;
};
module2.exports = SetHitArea;
}
),
/***/
81583: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PropertyValueSet = __webpack_require__2(43967);
var SetOrigin = function(items, originX, originY, stepX, stepY, index, direction) {
if (originY === void 0 || originY === null) {
originY = originX;
}
PropertyValueSet(items, "originX", originX, stepX, index, direction);
PropertyValueSet(items, "originY", originY, stepY, index, direction);
items.forEach(function(item) {
item.updateDisplayOrigin();
});
return items;
};
module2.exports = SetOrigin;
}
),
/***/
79939: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PropertyValueSet = __webpack_require__2(43967);
var SetRotation = function(items, value, step, index, direction) {
return PropertyValueSet(items, "rotation", value, step, index, direction);
};
module2.exports = SetRotation;
}
),
/***/
2699: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PropertyValueSet = __webpack_require__2(43967);
var SetScale = function(items, scaleX, scaleY, stepX, stepY, index, direction) {
if (scaleY === void 0 || scaleY === null) {
scaleY = scaleX;
}
PropertyValueSet(items, "scaleX", scaleX, stepX, index, direction);
return PropertyValueSet(items, "scaleY", scaleY, stepY, index, direction);
};
module2.exports = SetScale;
}
),
/***/
98739: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PropertyValueSet = __webpack_require__2(43967);
var SetScaleX = function(items, value, step, index, direction) {
return PropertyValueSet(items, "scaleX", value, step, index, direction);
};
module2.exports = SetScaleX;
}
),
/***/
98476: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PropertyValueSet = __webpack_require__2(43967);
var SetScaleY = function(items, value, step, index, direction) {
return PropertyValueSet(items, "scaleY", value, step, index, direction);
};
module2.exports = SetScaleY;
}
),
/***/
6207: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PropertyValueSet = __webpack_require__2(43967);
var SetScrollFactor = function(items, scrollFactorX, scrollFactorY, stepX, stepY, index, direction) {
if (scrollFactorY === void 0 || scrollFactorY === null) {
scrollFactorY = scrollFactorX;
}
PropertyValueSet(items, "scrollFactorX", scrollFactorX, stepX, index, direction);
return PropertyValueSet(items, "scrollFactorY", scrollFactorY, stepY, index, direction);
};
module2.exports = SetScrollFactor;
}
),
/***/
6607: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PropertyValueSet = __webpack_require__2(43967);
var SetScrollFactorX = function(items, value, step, index, direction) {
return PropertyValueSet(items, "scrollFactorX", value, step, index, direction);
};
module2.exports = SetScrollFactorX;
}
),
/***/
72248: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PropertyValueSet = __webpack_require__2(43967);
var SetScrollFactorY = function(items, value, step, index, direction) {
return PropertyValueSet(items, "scrollFactorY", value, step, index, direction);
};
module2.exports = SetScrollFactorY;
}
),
/***/
14036: (
/***/
(module2) => {
var SetTint = function(items, topLeft, topRight, bottomLeft, bottomRight) {
for (var i = 0; i < items.length; i++) {
items[i].setTint(topLeft, topRight, bottomLeft, bottomRight);
}
return items;
};
module2.exports = SetTint;
}
),
/***/
50159: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PropertyValueSet = __webpack_require__2(43967);
var SetVisible = function(items, value, index, direction) {
return PropertyValueSet(items, "visible", value, 0, index, direction);
};
module2.exports = SetVisible;
}
),
/***/
77597: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PropertyValueSet = __webpack_require__2(43967);
var SetX = function(items, value, step, index, direction) {
return PropertyValueSet(items, "x", value, step, index, direction);
};
module2.exports = SetX;
}
),
/***/
83194: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PropertyValueSet = __webpack_require__2(43967);
var SetXY = function(items, x, y, stepX, stepY, index, direction) {
if (y === void 0 || y === null) {
y = x;
}
PropertyValueSet(items, "x", x, stepX, index, direction);
return PropertyValueSet(items, "y", y, stepY, index, direction);
};
module2.exports = SetXY;
}
),
/***/
67678: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PropertyValueSet = __webpack_require__2(43967);
var SetY = function(items, value, step, index, direction) {
return PropertyValueSet(items, "y", value, step, index, direction);
};
module2.exports = SetY;
}
),
/***/
35850: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Vector2 = __webpack_require__2(26099);
var ShiftPosition = function(items, x, y, direction, output) {
if (direction === void 0) {
direction = 0;
}
if (output === void 0) {
output = new Vector2();
}
var px;
var py;
var len = items.length;
if (len === 1) {
px = items[0].x;
py = items[0].y;
items[0].x = x;
items[0].y = y;
} else {
var i = 1;
var pos = 0;
if (direction === 0) {
pos = len - 1;
i = len - 2;
}
px = items[pos].x;
py = items[pos].y;
items[pos].x = x;
items[pos].y = y;
for (var c = 0; c < len; c++) {
if (i >= len || i === -1) {
continue;
}
var cur = items[i];
var cx = cur.x;
var cy = cur.y;
cur.x = px;
cur.y = py;
px = cx;
py = cy;
if (direction === 0) {
i--;
} else {
i++;
}
}
}
output.x = px;
output.y = py;
return output;
};
module2.exports = ShiftPosition;
}
),
/***/
8628: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var ArrayShuffle = __webpack_require__2(33680);
var Shuffle = function(items) {
return ArrayShuffle(items);
};
module2.exports = Shuffle;
}
),
/***/
21837: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var MathSmoothStep = __webpack_require__2(7602);
var SmoothStep = function(items, property, min, max, inc) {
if (inc === void 0) {
inc = false;
}
var step = Math.abs(max - min) / items.length;
var i;
if (inc) {
for (i = 0; i < items.length; i++) {
items[i][property] += MathSmoothStep(i * step, min, max);
}
} else {
for (i = 0; i < items.length; i++) {
items[i][property] = MathSmoothStep(i * step, min, max);
}
}
return items;
};
module2.exports = SmoothStep;
}
),
/***/
21910: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var MathSmootherStep = __webpack_require__2(54261);
var SmootherStep = function(items, property, min, max, inc) {
if (inc === void 0) {
inc = false;
}
var step = Math.abs(max - min) / items.length;
var i;
if (inc) {
for (i = 0; i < items.length; i++) {
items[i][property] += MathSmootherStep(i * step, min, max);
}
} else {
for (i = 0; i < items.length; i++) {
items[i][property] = MathSmootherStep(i * step, min, max);
}
}
return items;
};
module2.exports = SmootherStep;
}
),
/***/
62054: (
/***/
(module2) => {
var Spread = function(items, property, min, max, inc) {
if (inc === void 0) {
inc = false;
}
if (items.length === 0) {
return items;
}
if (items.length === 1) {
if (inc) {
items[0][property] += (max + min) / 2;
} else {
items[0][property] = (max + min) / 2;
}
return items;
}
var step = Math.abs(max - min) / (items.length - 1);
var i;
if (inc) {
for (i = 0; i < items.length; i++) {
items[i][property] += i * step + min;
}
} else {
for (i = 0; i < items.length; i++) {
items[i][property] = i * step + min;
}
}
return items;
};
module2.exports = Spread;
}
),
/***/
79815: (
/***/
(module2) => {
var ToggleVisible = function(items) {
for (var i = 0; i < items.length; i++) {
items[i].visible = !items[i].visible;
}
return items;
};
module2.exports = ToggleVisible;
}
),
/***/
39665: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Wrap = __webpack_require__2(15994);
var WrapInRectangle = function(items, rect, padding) {
if (padding === void 0) {
padding = 0;
}
for (var i = 0; i < items.length; i++) {
var item = items[i];
item.x = Wrap(item.x, rect.left - padding, rect.right + padding);
item.y = Wrap(item.y, rect.top - padding, rect.bottom + padding);
}
return items;
};
module2.exports = WrapInRectangle;
}
),
/***/
61061: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
AlignTo: __webpack_require__2(11517),
Angle: __webpack_require__2(80318),
Call: __webpack_require__2(60757),
GetFirst: __webpack_require__2(69927),
GetLast: __webpack_require__2(32265),
GridAlign: __webpack_require__2(94420),
IncAlpha: __webpack_require__2(41721),
IncX: __webpack_require__2(67285),
IncXY: __webpack_require__2(9074),
IncY: __webpack_require__2(75222),
PlaceOnCircle: __webpack_require__2(22983),
PlaceOnEllipse: __webpack_require__2(95253),
PlaceOnLine: __webpack_require__2(88505),
PlaceOnRectangle: __webpack_require__2(41346),
PlaceOnTriangle: __webpack_require__2(11575),
PlayAnimation: __webpack_require__2(29953),
PropertyValueInc: __webpack_require__2(66979),
PropertyValueSet: __webpack_require__2(43967),
RandomCircle: __webpack_require__2(88926),
RandomEllipse: __webpack_require__2(33286),
RandomLine: __webpack_require__2(96e3),
RandomRectangle: __webpack_require__2(28789),
RandomTriangle: __webpack_require__2(97154),
Rotate: __webpack_require__2(20510),
RotateAround: __webpack_require__2(91051),
RotateAroundDistance: __webpack_require__2(76332),
ScaleX: __webpack_require__2(61619),
ScaleXY: __webpack_require__2(94868),
ScaleY: __webpack_require__2(95532),
SetAlpha: __webpack_require__2(8689),
SetBlendMode: __webpack_require__2(2645),
SetDepth: __webpack_require__2(32372),
SetHitArea: __webpack_require__2(85373),
SetOrigin: __webpack_require__2(81583),
SetRotation: __webpack_require__2(79939),
SetScale: __webpack_require__2(2699),
SetScaleX: __webpack_require__2(98739),
SetScaleY: __webpack_require__2(98476),
SetScrollFactor: __webpack_require__2(6207),
SetScrollFactorX: __webpack_require__2(6607),
SetScrollFactorY: __webpack_require__2(72248),
SetTint: __webpack_require__2(14036),
SetVisible: __webpack_require__2(50159),
SetX: __webpack_require__2(77597),
SetXY: __webpack_require__2(83194),
SetY: __webpack_require__2(67678),
ShiftPosition: __webpack_require__2(35850),
Shuffle: __webpack_require__2(8628),
SmootherStep: __webpack_require__2(21910),
SmoothStep: __webpack_require__2(21837),
Spread: __webpack_require__2(62054),
ToggleVisible: __webpack_require__2(79815),
WrapInRectangle: __webpack_require__2(39665)
};
}
),
/***/
42099: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Clamp = __webpack_require__2(45319);
var Class = __webpack_require__2(83419);
var Events = __webpack_require__2(74943);
var FindClosestInSorted = __webpack_require__2(81957);
var Frame = __webpack_require__2(41138);
var GetValue = __webpack_require__2(35154);
var SortByDigits = __webpack_require__2(90126);
var Animation = new Class({
initialize: function Animation2(manager, key, config) {
this.manager = manager;
this.key = key;
this.type = "frame";
this.frames = this.getFrames(
manager.textureManager,
GetValue(config, "frames", []),
GetValue(config, "defaultTextureKey", null),
GetValue(config, "sortFrames", true)
);
this.frameRate = GetValue(config, "frameRate", null);
this.duration = GetValue(config, "duration", null);
this.msPerFrame;
this.skipMissedFrames = GetValue(config, "skipMissedFrames", true);
this.delay = GetValue(config, "delay", 0);
this.repeat = GetValue(config, "repeat", 0);
this.repeatDelay = GetValue(config, "repeatDelay", 0);
this.yoyo = GetValue(config, "yoyo", false);
this.showBeforeDelay = GetValue(config, "showBeforeDelay", false);
this.showOnStart = GetValue(config, "showOnStart", false);
this.hideOnComplete = GetValue(config, "hideOnComplete", false);
this.randomFrame = GetValue(config, "randomFrame", false);
this.paused = false;
this.calculateDuration(this, this.getTotalFrames(), this.duration, this.frameRate);
if (this.manager.on) {
this.manager.on(Events.PAUSE_ALL, this.pause, this);
this.manager.on(Events.RESUME_ALL, this.resume, this);
}
},
/**
* Gets the total number of frames in this animation.
*
* @method Phaser.Animations.Animation#getTotalFrames
* @since 3.50.0
*
* @return {number} The total number of frames in this animation.
*/
getTotalFrames: function() {
return this.frames.length;
},
/**
* Calculates the duration, frame rate and msPerFrame values.
*
* @method Phaser.Animations.Animation#calculateDuration
* @since 3.50.0
*
* @param {Phaser.Animations.Animation} target - The target to set the values on.
* @param {number} totalFrames - The total number of frames in the animation.
* @param {?number} [duration] - The duration to calculate the frame rate from. Pass `null` if you wish to set the `frameRate` instead.
* @param {?number} [frameRate] - The frame rate to calculate the duration from.
*/
calculateDuration: function(target, totalFrames, duration, frameRate) {
if (duration === null && frameRate === null) {
target.frameRate = 24;
target.duration = 24 / totalFrames * 1e3;
} else if (duration && frameRate === null) {
target.duration = duration;
target.frameRate = totalFrames / (duration / 1e3);
} else {
target.frameRate = frameRate;
target.duration = totalFrames / frameRate * 1e3;
}
target.msPerFrame = 1e3 / target.frameRate;
},
/**
* Add frames to the end of the animation.
*
* @method Phaser.Animations.Animation#addFrame
* @since 3.0.0
*
* @param {(string|Phaser.Types.Animations.AnimationFrame[])} config - Either a string, in which case it will use all frames from a texture with the matching key, or an array of Animation Frame configuration objects.
*
* @return {this} This Animation object.
*/
addFrame: function(config) {
return this.addFrameAt(this.frames.length, config);
},
/**
* Add frame/s into the animation.
*
* @method Phaser.Animations.Animation#addFrameAt
* @since 3.0.0
*
* @param {number} index - The index to insert the frame at within the animation.
* @param {(string|Phaser.Types.Animations.AnimationFrame[])} config - Either a string, in which case it will use all frames from a texture with the matching key, or an array of Animation Frame configuration objects.
*
* @return {this} This Animation object.
*/
addFrameAt: function(index, config) {
var newFrames = this.getFrames(this.manager.textureManager, config);
if (newFrames.length > 0) {
if (index === 0) {
this.frames = newFrames.concat(this.frames);
} else if (index === this.frames.length) {
this.frames = this.frames.concat(newFrames);
} else {
var pre = this.frames.slice(0, index);
var post = this.frames.slice(index);
this.frames = pre.concat(newFrames, post);
}
this.updateFrameSequence();
}
return this;
},
/**
* Check if the given frame index is valid.
*
* @method Phaser.Animations.Animation#checkFrame
* @since 3.0.0
*
* @param {number} index - The index to be checked.
*
* @return {boolean} `true` if the index is valid, otherwise `false`.
*/
checkFrame: function(index) {
return index >= 0 && index < this.frames.length;
},
/**
* Called internally when this Animation first starts to play.
* Sets the accumulator and nextTick properties.
*
* @method Phaser.Animations.Animation#getFirstTick
* @protected
* @since 3.0.0
*
* @param {Phaser.Animations.AnimationState} state - The Animation State belonging to the Game Object invoking this call.
*/
getFirstTick: function(state) {
state.accumulator = 0;
state.nextTick = state.currentFrame.duration ? state.currentFrame.duration : state.msPerFrame;
},
/**
* Returns the AnimationFrame at the provided index
*
* @method Phaser.Animations.Animation#getFrameAt
* @since 3.0.0
*
* @param {number} index - The index in the AnimationFrame array
*
* @return {Phaser.Animations.AnimationFrame} The frame at the index provided from the animation sequence
*/
getFrameAt: function(index) {
return this.frames[index];
},
/**
* Creates AnimationFrame instances based on the given frame data.
*
* @method Phaser.Animations.Animation#getFrames
* @since 3.0.0
*
* @param {Phaser.Textures.TextureManager} textureManager - A reference to the global Texture Manager.
* @param {(string|Phaser.Types.Animations.AnimationFrame[])} frames - Either a string, in which case it will use all frames from a texture with the matching key, or an array of Animation Frame configuration objects.
* @param {string} [defaultTextureKey] - The key to use if no key is set in the frame configuration object.
*
* @return {Phaser.Animations.AnimationFrame[]} An array of newly created AnimationFrame instances.
*/
getFrames: function(textureManager, frames, defaultTextureKey, sortFrames) {
if (sortFrames === void 0) {
sortFrames = true;
}
var out = [];
var prev;
var animationFrame;
var index = 1;
var i;
var textureKey;
if (typeof frames === "string") {
textureKey = frames;
if (!textureManager.exists(textureKey)) {
console.warn('Texture "%s" not found', textureKey);
return out;
}
var texture = textureManager.get(textureKey);
var frameKeys = texture.getFrameNames();
if (sortFrames) {
SortByDigits(frameKeys);
}
frames = [];
frameKeys.forEach(function(value) {
frames.push({ key: textureKey, frame: value });
});
}
if (!Array.isArray(frames) || frames.length === 0) {
return out;
}
for (i = 0; i < frames.length; i++) {
var item = frames[i];
var key = GetValue(item, "key", defaultTextureKey);
if (!key) {
continue;
}
var frame = GetValue(item, "frame", 0);
var textureFrame = textureManager.getFrame(key, frame);
if (!textureFrame) {
console.warn('Texture "%s" not found', key);
continue;
}
animationFrame = new Frame(key, frame, index, textureFrame);
animationFrame.duration = GetValue(item, "duration", 0);
animationFrame.isFirst = !prev;
if (prev) {
prev.nextFrame = animationFrame;
animationFrame.prevFrame = prev;
}
out.push(animationFrame);
prev = animationFrame;
index++;
}
if (out.length > 0) {
animationFrame.isLast = true;
animationFrame.nextFrame = out[0];
out[0].prevFrame = animationFrame;
var slice = 1 / (out.length - 1);
for (i = 0; i < out.length; i++) {
out[i].progress = i * slice;
}
}
return out;
},
/**
* Called internally. Sets the accumulator and nextTick values of the current Animation.
*
* @method Phaser.Animations.Animation#getNextTick
* @since 3.0.0
*
* @param {Phaser.Animations.AnimationState} state - The Animation State belonging to the Game Object invoking this call.
*/
getNextTick: function(state) {
state.accumulator -= state.nextTick;
state.nextTick = state.currentFrame.duration ? state.currentFrame.duration : state.msPerFrame;
},
/**
* Returns the frame closest to the given progress value between 0 and 1.
*
* @method Phaser.Animations.Animation#getFrameByProgress
* @since 3.4.0
*
* @param {number} value - A value between 0 and 1.
*
* @return {Phaser.Animations.AnimationFrame} The frame closest to the given progress value.
*/
getFrameByProgress: function(value) {
value = Clamp(value, 0, 1);
return FindClosestInSorted(value, this.frames, "progress");
},
/**
* Advance the animation frame.
*
* @method Phaser.Animations.Animation#nextFrame
* @since 3.0.0
*
* @param {Phaser.Animations.AnimationState} state - The Animation State to advance.
*/
nextFrame: function(state) {
var frame = state.currentFrame;
if (frame.isLast) {
if (state.yoyo) {
this.handleYoyoFrame(state, false);
} else if (state.repeatCounter > 0) {
if (state.inReverse && state.forward) {
state.forward = false;
} else {
this.repeatAnimation(state);
}
} else {
state.complete();
}
} else {
this.updateAndGetNextTick(state, frame.nextFrame);
}
},
/**
* Handle the yoyo functionality in nextFrame and previousFrame methods.
*
* @method Phaser.Animations.Animation#handleYoyoFrame
* @private
* @since 3.12.0
*
* @param {Phaser.Animations.AnimationState} state - The Animation State to advance.
* @param {boolean} isReverse - Is animation in reverse mode? (Default: false)
*/
handleYoyoFrame: function(state, isReverse) {
if (!isReverse) {
isReverse = false;
}
if (state.inReverse === !isReverse && state.repeatCounter > 0) {
if (state.repeatDelay === 0 || state.pendingRepeat) {
state.forward = isReverse;
}
this.repeatAnimation(state);
return;
}
if (state.inReverse !== isReverse && state.repeatCounter === 0) {
state.complete();
return;
}
state.forward = isReverse;
var frame = isReverse ? state.currentFrame.nextFrame : state.currentFrame.prevFrame;
this.updateAndGetNextTick(state, frame);
},
/**
* Returns the animation last frame.
*
* @method Phaser.Animations.Animation#getLastFrame
* @since 3.12.0
*
* @return {Phaser.Animations.AnimationFrame} The last Animation Frame.
*/
getLastFrame: function() {
return this.frames[this.frames.length - 1];
},
/**
* Called internally when the Animation is playing backwards.
* Sets the previous frame, causing a yoyo, repeat, complete or update, accordingly.
*
* @method Phaser.Animations.Animation#previousFrame
* @since 3.0.0
*
* @param {Phaser.Animations.AnimationState} state - The Animation State belonging to the Game Object invoking this call.
*/
previousFrame: function(state) {
var frame = state.currentFrame;
if (frame.isFirst) {
if (state.yoyo) {
this.handleYoyoFrame(state, true);
} else if (state.repeatCounter > 0) {
if (state.inReverse && !state.forward) {
this.repeatAnimation(state);
} else {
state.forward = true;
this.repeatAnimation(state);
}
} else {
state.complete();
}
} else {
this.updateAndGetNextTick(state, frame.prevFrame);
}
},
/**
* Update Frame and Wait next tick.
*
* @method Phaser.Animations.Animation#updateAndGetNextTick
* @private
* @since 3.12.0
*
* @param {Phaser.Animations.AnimationState} state - The Animation State.
* @param {Phaser.Animations.AnimationFrame} frame - An Animation frame.
*/
updateAndGetNextTick: function(state, frame) {
state.setCurrentFrame(frame);
this.getNextTick(state);
},
/**
* Removes the given AnimationFrame from this Animation instance.
* This is a global action. Any Game Object using this Animation will be impacted by this change.
*
* @method Phaser.Animations.Animation#removeFrame
* @since 3.0.0
*
* @param {Phaser.Animations.AnimationFrame} frame - The AnimationFrame to be removed.
*
* @return {this} This Animation object.
*/
removeFrame: function(frame) {
var index = this.frames.indexOf(frame);
if (index !== -1) {
this.removeFrameAt(index);
}
return this;
},
/**
* Removes a frame from the AnimationFrame array at the provided index
* and updates the animation accordingly.
*
* @method Phaser.Animations.Animation#removeFrameAt
* @since 3.0.0
*
* @param {number} index - The index in the AnimationFrame array
*
* @return {this} This Animation object.
*/
removeFrameAt: function(index) {
this.frames.splice(index, 1);
this.updateFrameSequence();
return this;
},
/**
* Called internally during playback. Forces the animation to repeat, providing there are enough counts left
* in the repeat counter.
*
* @method Phaser.Animations.Animation#repeatAnimation
* @fires Phaser.Animations.Events#ANIMATION_REPEAT
* @fires Phaser.Animations.Events#SPRITE_ANIMATION_REPEAT
* @fires Phaser.Animations.Events#SPRITE_ANIMATION_KEY_REPEAT
* @since 3.0.0
*
* @param {Phaser.Animations.AnimationState} state - The Animation State belonging to the Game Object invoking this call.
*/
repeatAnimation: function(state) {
if (state._pendingStop === 2) {
if (state._pendingStopValue === 0) {
return state.stop();
} else {
state._pendingStopValue--;
}
}
if (state.repeatDelay > 0 && !state.pendingRepeat) {
state.pendingRepeat = true;
state.accumulator -= state.nextTick;
state.nextTick += state.repeatDelay;
} else {
state.repeatCounter--;
if (state.forward) {
state.setCurrentFrame(state.currentFrame.nextFrame);
} else {
state.setCurrentFrame(state.currentFrame.prevFrame);
}
if (state.isPlaying) {
this.getNextTick(state);
state.handleRepeat();
}
}
},
/**
* Converts the animation data to JSON.
*
* @method Phaser.Animations.Animation#toJSON
* @since 3.0.0
*
* @return {Phaser.Types.Animations.JSONAnimation} The resulting JSONAnimation formatted object.
*/
toJSON: function() {
var output = {
key: this.key,
type: this.type,
frames: [],
frameRate: this.frameRate,
duration: this.duration,
skipMissedFrames: this.skipMissedFrames,
delay: this.delay,
repeat: this.repeat,
repeatDelay: this.repeatDelay,
yoyo: this.yoyo,
showBeforeDelay: this.showBeforeDelay,
showOnStart: this.showOnStart,
randomFrame: this.randomFrame,
hideOnComplete: this.hideOnComplete
};
this.frames.forEach(function(frame) {
output.frames.push(frame.toJSON());
});
return output;
},
/**
* Called internally whenever frames are added to, or removed from, this Animation.
*
* @method Phaser.Animations.Animation#updateFrameSequence
* @since 3.0.0
*
* @return {this} This Animation object.
*/
updateFrameSequence: function() {
var len = this.frames.length;
var slice = 1 / (len - 1);
var frame;
for (var i = 0; i < len; i++) {
frame = this.frames[i];
frame.index = i + 1;
frame.isFirst = false;
frame.isLast = false;
frame.progress = i * slice;
if (i === 0) {
frame.isFirst = true;
if (len === 1) {
frame.isLast = true;
frame.nextFrame = frame;
frame.prevFrame = frame;
} else {
frame.isLast = false;
frame.prevFrame = this.frames[len - 1];
frame.nextFrame = this.frames[i + 1];
}
} else if (i === len - 1 && len > 1) {
frame.isLast = true;
frame.prevFrame = this.frames[len - 2];
frame.nextFrame = this.frames[0];
} else if (len > 1) {
frame.prevFrame = this.frames[i - 1];
frame.nextFrame = this.frames[i + 1];
}
}
return this;
},
/**
* Pauses playback of this Animation. The paused state is set immediately.
*
* @method Phaser.Animations.Animation#pause
* @since 3.0.0
*
* @return {this} This Animation object.
*/
pause: function() {
this.paused = true;
return this;
},
/**
* Resumes playback of this Animation. The paused state is reset immediately.
*
* @method Phaser.Animations.Animation#resume
* @since 3.0.0
*
* @return {this} This Animation object.
*/
resume: function() {
this.paused = false;
return this;
},
/**
* Destroys this Animation instance. It will remove all event listeners,
* remove this animation and its key from the global Animation Manager,
* and then destroy all Animation Frames in turn.
*
* @method Phaser.Animations.Animation#destroy
* @since 3.0.0
*/
destroy: function() {
if (this.manager.off) {
this.manager.off(Events.PAUSE_ALL, this.pause, this);
this.manager.off(Events.RESUME_ALL, this.resume, this);
}
this.manager.remove(this.key);
for (var i = 0; i < this.frames.length; i++) {
this.frames[i].destroy();
}
this.frames = [];
this.manager = null;
}
});
module2.exports = Animation;
}
),
/***/
41138: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var AnimationFrame = new Class({
initialize: function AnimationFrame2(textureKey, textureFrame, index, frame, isKeyFrame) {
if (isKeyFrame === void 0) {
isKeyFrame = false;
}
this.textureKey = textureKey;
this.textureFrame = textureFrame;
this.index = index;
this.frame = frame;
this.isFirst = false;
this.isLast = false;
this.prevFrame = null;
this.nextFrame = null;
this.duration = 0;
this.progress = 0;
this.isKeyFrame = isKeyFrame;
},
/**
* Generates a JavaScript object suitable for converting to JSON.
*
* @method Phaser.Animations.AnimationFrame#toJSON
* @since 3.0.0
*
* @return {Phaser.Types.Animations.JSONAnimationFrame} The AnimationFrame data.
*/
toJSON: function() {
return {
key: this.textureKey,
frame: this.textureFrame,
duration: this.duration,
keyframe: this.isKeyFrame
};
},
/**
* Destroys this object by removing references to external resources and callbacks.
*
* @method Phaser.Animations.AnimationFrame#destroy
* @since 3.0.0
*/
destroy: function() {
this.frame = void 0;
}
});
module2.exports = AnimationFrame;
}
),
/***/
60848: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Animation = __webpack_require__2(42099);
var Class = __webpack_require__2(83419);
var CustomMap = __webpack_require__2(90330);
var EventEmitter = __webpack_require__2(50792);
var Events = __webpack_require__2(74943);
var GameEvents = __webpack_require__2(8443);
var GetFastValue = __webpack_require__2(95540);
var GetValue = __webpack_require__2(35154);
var MATH_CONST = __webpack_require__2(36383);
var NumberArray = __webpack_require__2(20283);
var Pad = __webpack_require__2(41836);
var AnimationManager = new Class({
Extends: EventEmitter,
initialize: function AnimationManager2(game) {
EventEmitter.call(this);
this.game = game;
this.textureManager = null;
this.globalTimeScale = 1;
this.anims = new CustomMap();
this.mixes = new CustomMap();
this.paused = false;
this.name = "AnimationManager";
game.events.once(GameEvents.BOOT, this.boot, this);
},
/**
* Registers event listeners after the Game boots.
*
* @method Phaser.Animations.AnimationManager#boot
* @listens Phaser.Core.Events#DESTROY
* @since 3.0.0
*/
boot: function() {
this.textureManager = this.game.textures;
this.game.events.once(GameEvents.DESTROY, this.destroy, this);
},
/**
* Adds a mix between two animations.
*
* Mixing allows you to specify a unique delay between a pairing of animations.
*
* When playing Animation A on a Game Object, if you then play Animation B, and a
* mix exists, it will wait for the specified delay to be over before playing Animation B.
*
* This allows you to customise smoothing between different types of animation, such
* as blending between an idle and a walk state, or a running and a firing state.
*
* Note that mixing is only applied if you use the `Sprite.play` method. If you opt to use
* `playAfterRepeat` or `playAfterDelay` instead, those will take priority and the mix
* delay will not be used.
*
* To update an existing mix, just call this method with the new delay.
*
* To remove a mix pairing, see the `removeMix` method.
*
* @method Phaser.Animations.AnimationManager#addMix
* @since 3.50.0
*
* @param {(string|Phaser.Animations.Animation)} animA - The string-based key, or instance of, Animation A.
* @param {(string|Phaser.Animations.Animation)} animB - The string-based key, or instance of, Animation B.
* @param {number} delay - The delay, in milliseconds, to wait when transitioning from Animation A to B.
*
* @return {this} This Animation Manager.
*/
addMix: function(animA, animB, delay) {
var anims = this.anims;
var mixes = this.mixes;
var keyA = typeof animA === "string" ? animA : animA.key;
var keyB = typeof animB === "string" ? animB : animB.key;
if (anims.has(keyA) && anims.has(keyB)) {
var mixObj = mixes.get(keyA);
if (!mixObj) {
mixObj = {};
}
mixObj[keyB] = delay;
mixes.set(keyA, mixObj);
}
return this;
},
/**
* Removes a mix between two animations.
*
* Mixing allows you to specify a unique delay between a pairing of animations.
*
* Calling this method lets you remove those pairings. You can either remove
* it between `animA` and `animB`, or if you do not provide the `animB` parameter,
* it will remove all `animA` mixes.
*
* If you wish to update an existing mix instead, call the `addMix` method with the
* new delay.
*
* @method Phaser.Animations.AnimationManager#removeMix
* @since 3.50.0
*
* @param {(string|Phaser.Animations.Animation)} animA - The string-based key, or instance of, Animation A.
* @param {(string|Phaser.Animations.Animation)} [animB] - The string-based key, or instance of, Animation B. If not given, all mixes for Animation A will be removed.
*
* @return {this} This Animation Manager.
*/
removeMix: function(animA, animB) {
var mixes = this.mixes;
var keyA = typeof animA === "string" ? animA : animA.key;
var mixObj = mixes.get(keyA);
if (mixObj) {
if (animB) {
var keyB = typeof animB === "string" ? animB : animB.key;
if (mixObj.hasOwnProperty(keyB)) {
delete mixObj[keyB];
}
} else if (!animB) {
mixes.delete(keyA);
}
}
return this;
},
/**
* Returns the mix delay between two animations.
*
* If no mix has been set-up, this method will return zero.
*
* If you wish to create, or update, a new mix, call the `addMix` method.
* If you wish to remove a mix, call the `removeMix` method.
*
* @method Phaser.Animations.AnimationManager#getMix
* @since 3.50.0
*
* @param {(string|Phaser.Animations.Animation)} animA - The string-based key, or instance of, Animation A.
* @param {(string|Phaser.Animations.Animation)} animB - The string-based key, or instance of, Animation B.
*
* @return {number} The mix duration, or zero if no mix exists.
*/
getMix: function(animA, animB) {
var mixes = this.mixes;
var keyA = typeof animA === "string" ? animA : animA.key;
var keyB = typeof animB === "string" ? animB : animB.key;
var mixObj = mixes.get(keyA);
if (mixObj && mixObj.hasOwnProperty(keyB)) {
return mixObj[keyB];
} else {
return 0;
}
},
/**
* Adds an existing Animation to the Animation Manager.
*
* @method Phaser.Animations.AnimationManager#add
* @fires Phaser.Animations.Events#ADD_ANIMATION
* @since 3.0.0
*
* @param {string} key - The key under which the Animation should be added. The Animation will be updated with it. Must be unique.
* @param {Phaser.Animations.Animation} animation - The Animation which should be added to the Animation Manager.
*
* @return {this} This Animation Manager.
*/
add: function(key, animation) {
if (this.anims.has(key)) {
console.warn("Animation key exists: " + key);
return this;
}
animation.key = key;
this.anims.set(key, animation);
this.emit(Events.ADD_ANIMATION, key, animation);
return this;
},
/**
* Checks to see if the given key is already in use within the Animation Manager or not.
*
* Animations are global. Keys created in one scene can be used from any other Scene in your game. They are not Scene specific.
*
* @method Phaser.Animations.AnimationManager#exists
* @since 3.16.0
*
* @param {string} key - The key of the Animation to check.
*
* @return {boolean} `true` if the Animation already exists in the Animation Manager, or `false` if the key is available.
*/
exists: function(key) {
return this.anims.has(key);
},
/**
* Create one, or more animations from a loaded Aseprite JSON file.
*
* Aseprite is a powerful animated sprite editor and pixel art tool.
*
* You can find more details at https://www.aseprite.org/
*
* To export a compatible JSON file in Aseprite, please do the following:
*
* 1. Go to "File - Export Sprite Sheet"
*
* 2. On the **Layout** tab:
* 2a. Set the "Sheet type" to "Packed"
* 2b. Set the "Constraints" to "None"
* 2c. Check the "Merge Duplicates" checkbox
*
* 3. On the **Sprite** tab:
* 3a. Set "Layers" to "Visible layers"
* 3b. Set "Frames" to "All frames", unless you only wish to export a sub-set of tags
*
* 4. On the **Borders** tab:
* 4a. Check the "Trim Sprite" and "Trim Cells" options
* 4b. Ensure "Border Padding", "Spacing" and "Inner Padding" are all > 0 (1 is usually enough)
*
* 5. On the **Output** tab:
* 5a. Check "Output File", give your image a name and make sure you choose "png files" as the file type
* 5b. Check "JSON Data" and give your json file a name
* 5c. The JSON Data type can be either a Hash or Array, Phaser doesn't mind.
* 5d. Make sure "Tags" is checked in the Meta options
* 5e. In the "Item Filename" input box, make sure it says just "{frame}" and nothing more.
*
* 6. Click export
*
* This was tested with Aseprite 1.2.25.
*
* This will export a png and json file which you can load using the Aseprite Loader, i.e.:
*
* ```javascript
* function preload ()
* {
* this.load.path = 'assets/animations/aseprite/';
* this.load.aseprite('paladin', 'paladin.png', 'paladin.json');
* }
* ```
*
* Once loaded, you can call this method from within a Scene with the 'atlas' key:
*
* ```javascript
* this.anims.createFromAseprite('paladin');
* ```
*
* Any animations defined in the JSON will now be available to use in Phaser and you play them
* via their Tag name. For example, if you have an animation called 'War Cry' on your Aseprite timeline,
* you can play it in Phaser using that Tag name:
*
* ```javascript
* this.add.sprite(400, 300).play('War Cry');
* ```
*
* When calling this method you can optionally provide an array of tag names, and only those animations
* will be created. For example:
*
* ```javascript
* this.anims.createFromAseprite('paladin', [ 'step', 'War Cry', 'Magnum Break' ]);
* ```
*
* This will only create the 3 animations defined. Note that the tag names are case-sensitive.
*
* @method Phaser.Animations.AnimationManager#createFromAseprite
* @since 3.50.0
*
* @param {string} key - The key of the loaded Aseprite atlas. It must have been loaded prior to calling this method.
* @param {string[]} [tags] - An array of Tag names. If provided, only animations found in this array will be created.
* @param {(Phaser.Animations.AnimationManager|Phaser.GameObjects.GameObject)} [target] - Create the animations on this target Sprite. If not given, they will be created globally in this Animation Manager.
*
* @return {Phaser.Animations.Animation[]} An array of Animation instances that were successfully created.
*/
createFromAseprite: function(key, tags, target) {
var output = [];
var data = this.game.cache.json.get(key);
if (!data) {
console.warn("No Aseprite data found for: " + key);
return output;
}
var _this = this;
var meta = GetValue(data, "meta", null);
var frames = GetValue(data, "frames", null);
if (meta && frames) {
var frameTags = GetValue(meta, "frameTags", []);
frameTags.forEach(function(tag) {
var animFrames = [];
var name = GetFastValue(tag, "name", null);
var from = GetFastValue(tag, "from", 0);
var to = GetFastValue(tag, "to", 0);
var direction = GetFastValue(tag, "direction", "forward");
if (!name) {
return;
}
if (!tags || tags && tags.indexOf(name) > -1) {
var totalDuration = 0;
for (var i = from; i <= to; i++) {
var frameKey = i.toString();
var frame = frames[frameKey];
if (frame) {
var frameDuration = GetFastValue(frame, "duration", MATH_CONST.MAX_SAFE_INTEGER);
animFrames.push({ key, frame: frameKey, duration: frameDuration });
totalDuration += frameDuration;
}
}
if (direction === "reverse") {
animFrames = animFrames.reverse();
}
var createConfig = {
key: name,
frames: animFrames,
duration: totalDuration,
yoyo: direction === "pingpong"
};
var result;
if (target) {
if (target.anims) {
result = target.anims.create(createConfig);
}
} else {
result = _this.create(createConfig);
}
if (result) {
output.push(result);
}
}
});
}
return output;
},
/**
* Creates a new Animation and adds it to the Animation Manager.
*
* Animations are global. Once created, you can use them in any Scene in your game. They are not Scene specific.
*
* If an invalid key is given this method will return `false`.
*
* If you pass the key of an animation that already exists in the Animation Manager, that animation will be returned.
*
* A brand new animation is only created if the key is valid and not already in use.
*
* If you wish to re-use an existing key, call `AnimationManager.remove` first, then this method.
*
* @method Phaser.Animations.AnimationManager#create
* @fires Phaser.Animations.Events#ADD_ANIMATION
* @since 3.0.0
*
* @param {Phaser.Types.Animations.Animation} config - The configuration settings for the Animation.
*
* @return {(Phaser.Animations.Animation|false)} The Animation that was created, or `false` if the key is already in use.
*/
create: function(config) {
var key = config.key;
var anim = false;
if (key) {
anim = this.get(key);
if (!anim) {
anim = new Animation(this, key, config);
this.anims.set(key, anim);
this.emit(Events.ADD_ANIMATION, key, anim);
} else {
console.warn("AnimationManager key already exists: " + key);
}
}
return anim;
},
/**
* Loads this Animation Manager's Animations and settings from a JSON object.
*
* @method Phaser.Animations.AnimationManager#fromJSON
* @since 3.0.0
*
* @param {(string|Phaser.Types.Animations.JSONAnimations|Phaser.Types.Animations.JSONAnimation)} data - The JSON object to parse.
* @param {boolean} [clearCurrentAnimations=false] - If set to `true`, the current animations will be removed (`anims.clear()`). If set to `false` (default), the animations in `data` will be added.
*
* @return {Phaser.Animations.Animation[]} An array containing all of the Animation objects that were created as a result of this call.
*/
fromJSON: function(data, clearCurrentAnimations) {
if (clearCurrentAnimations === void 0) {
clearCurrentAnimations = false;
}
if (clearCurrentAnimations) {
this.anims.clear();
}
if (typeof data === "string") {
data = JSON.parse(data);
}
var output = [];
if (data.hasOwnProperty("anims") && Array.isArray(data.anims)) {
for (var i = 0; i < data.anims.length; i++) {
output.push(this.create(data.anims[i]));
}
if (data.hasOwnProperty("globalTimeScale")) {
this.globalTimeScale = data.globalTimeScale;
}
} else if (data.hasOwnProperty("key") && data.type === "frame") {
output.push(this.create(data));
}
return output;
},
/**
* Generate an array of {@link Phaser.Types.Animations.AnimationFrame} objects from a texture key and configuration object.
*
* Generates objects with string based frame names, as configured by the given {@link Phaser.Types.Animations.GenerateFrameNames}.
*
* It's a helper method, designed to make it easier for you to extract all of the frame names from texture atlases.
*
* If you're working with a sprite sheet, see the `generateFrameNumbers` method instead.
*
* Example:
*
* If you have a texture atlases loaded called `gems` and it contains 6 frames called `ruby_0001`, `ruby_0002`, and so on,
* then you can call this method using: `this.anims.generateFrameNames('gems', { prefix: 'ruby_', start: 1, end: 6, zeroPad: 4 })`.
*
* The `end` value tells it to select frames 1 through 6, incrementally numbered, all starting with the prefix `ruby_`. The `zeroPad`
* value tells it how many zeroes pad out the numbers. To create an animation using this method, you can do:
*
* ```javascript
* this.anims.create({
* key: 'ruby',
* repeat: -1,
* frames: this.anims.generateFrameNames('gems', {
* prefix: 'ruby_',
* end: 6,
* zeroPad: 4
* })
* });
* ```
*
* Please see the animation examples for further details.
*
* @method Phaser.Animations.AnimationManager#generateFrameNames
* @since 3.0.0
*
* @param {string} key - The key for the texture containing the animation frames.
* @param {Phaser.Types.Animations.GenerateFrameNames} [config] - The configuration object for the animation frame names.
*
* @return {Phaser.Types.Animations.AnimationFrame[]} The array of {@link Phaser.Types.Animations.AnimationFrame} objects.
*/
generateFrameNames: function(key, config) {
var prefix = GetValue(config, "prefix", "");
var start = GetValue(config, "start", 0);
var end = GetValue(config, "end", 0);
var suffix = GetValue(config, "suffix", "");
var zeroPad = GetValue(config, "zeroPad", 0);
var out = GetValue(config, "outputArray", []);
var frames = GetValue(config, "frames", false);
if (!this.textureManager.exists(key)) {
console.warn('Texture "%s" not found', key);
return out;
}
var texture = this.textureManager.get(key);
if (!texture) {
return out;
}
var i;
if (!config) {
frames = texture.getFrameNames();
for (i = 0; i < frames.length; i++) {
out.push({ key, frame: frames[i] });
}
} else {
if (!frames) {
frames = NumberArray(start, end);
}
for (i = 0; i < frames.length; i++) {
var frame = prefix + Pad(frames[i], zeroPad, "0", 1) + suffix;
if (texture.has(frame)) {
out.push({ key, frame });
} else {
console.warn('Frame "%s" not found in texture "%s"', frame, key);
}
}
}
return out;
},
/**
* Generate an array of {@link Phaser.Types.Animations.AnimationFrame} objects from a texture key and configuration object.
*
* Generates objects with numbered frame names, as configured by the given {@link Phaser.Types.Animations.GenerateFrameNumbers}.
*
* If you're working with a texture atlas, see the `generateFrameNames` method instead.
*
* It's a helper method, designed to make it easier for you to extract frames from sprite sheets.
*
* Example:
*
* If you have a sprite sheet loaded called `explosion` and it contains 12 frames, then you can call this method using:
*
* `this.anims.generateFrameNumbers('explosion', { start: 0, end: 11 })`.
*
* The `end` value of 11 tells it to stop after the 12th frame has been added, because it started at zero.
*
* To create an animation using this method, you can do:
*
* ```javascript
* this.anims.create({
* key: 'boom',
* frames: this.anims.generateFrameNumbers('explosion', {
* start: 0,
* end: 11
* })
* });
* ```
*
* Note that `start` is optional and you don't need to include it if the animation starts from frame 0.
*
* To specify an animation in reverse, swap the `start` and `end` values.
*
* If the frames are not sequential, you may pass an array of frame numbers instead, for example:
*
* `this.anims.generateFrameNumbers('explosion', { frames: [ 0, 1, 2, 1, 2, 3, 4, 0, 1, 2 ] })`
*
* Please see the animation examples and `GenerateFrameNumbers` config docs for further details.
*
* @method Phaser.Animations.AnimationManager#generateFrameNumbers
* @since 3.0.0
*
* @param {string} key - The key for the texture containing the animation frames.
* @param {Phaser.Types.Animations.GenerateFrameNumbers} [config] - The configuration object for the animation frames.
*
* @return {Phaser.Types.Animations.AnimationFrame[]} The array of {@link Phaser.Types.Animations.AnimationFrame} objects.
*/
generateFrameNumbers: function(key, config) {
var start = GetValue(config, "start", 0);
var end = GetValue(config, "end", -1);
var first = GetValue(config, "first", false);
var out = GetValue(config, "outputArray", []);
var frames = GetValue(config, "frames", false);
if (!this.textureManager.exists(key)) {
console.warn('Texture "%s" not found', key);
return out;
}
var texture = this.textureManager.get(key);
if (!texture) {
return out;
}
if (first && texture.has(first)) {
out.push({ key, frame: first });
}
if (!frames) {
if (end === -1) {
end = texture.frameTotal - 2;
}
frames = NumberArray(start, end);
}
for (var i = 0; i < frames.length; i++) {
var frameName = frames[i];
if (texture.has(frameName)) {
out.push({ key, frame: frameName });
} else {
console.warn('Frame "%s" not found in texture "%s"', frameName, key);
}
}
return out;
},
/**
* Get an Animation.
*
* @method Phaser.Animations.AnimationManager#get
* @since 3.0.0
*
* @param {string} key - The key of the Animation to retrieve.
*
* @return {Phaser.Animations.Animation} The Animation.
*/
get: function(key) {
return this.anims.get(key);
},
/**
* Returns an array of all Animation keys that are using the given
* Texture. Only Animations that have at least one AnimationFrame
* entry using this texture will be included in the result.
*
* @method Phaser.Animations.AnimationManager#getAnimsFromTexture
* @since 3.60.0
*
* @param {(string|Phaser.Textures.Texture|Phaser.Textures.Frame)} key - The unique string-based key of the Texture, or a Texture, or Frame instance.
*
* @return {string[]} An array of Animation keys that feature the given Texture.
*/
getAnimsFromTexture: function(key) {
var texture = this.textureManager.get(key);
var match = texture.key;
var anims = this.anims.getArray();
var out = [];
for (var i = 0; i < anims.length; i++) {
var anim = anims[i];
var frames = anim.frames;
for (var c = 0; c < frames.length; c++) {
if (frames[c].textureKey === match) {
out.push(anim.key);
break;
}
}
}
return out;
},
/**
* Pause all animations.
*
* @method Phaser.Animations.AnimationManager#pauseAll
* @fires Phaser.Animations.Events#PAUSE_ALL
* @since 3.0.0
*
* @return {this} This Animation Manager.
*/
pauseAll: function() {
if (!this.paused) {
this.paused = true;
this.emit(Events.PAUSE_ALL);
}
return this;
},
/**
* Play an animation on the given Game Objects that have an Animation Component.
*
* @method Phaser.Animations.AnimationManager#play
* @since 3.0.0
*
* @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object.
* @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} children - An array of Game Objects to play the animation on. They must have an Animation Component.
*
* @return {this} This Animation Manager.
*/
play: function(key, children) {
if (!Array.isArray(children)) {
children = [children];
}
for (var i = 0; i < children.length; i++) {
children[i].anims.play(key);
}
return this;
},
/**
* Takes an array of Game Objects that have an Animation Component and then
* starts the given animation playing on them. The start time of each Game Object
* is offset, incrementally, by the `stagger` amount.
*
* For example, if you pass an array with 4 children and a stagger time of 1000,
* the delays will be:
*
* child 1: 1000ms delay
* child 2: 2000ms delay
* child 3: 3000ms delay
* child 4: 4000ms delay
*
* If you set the `staggerFirst` parameter to `false` they would be:
*
* child 1: 0ms delay
* child 2: 1000ms delay
* child 3: 2000ms delay
* child 4: 3000ms delay
*
* You can also set `stagger` to be a negative value. If it was -1000, the above would be:
*
* child 1: 3000ms delay
* child 2: 2000ms delay
* child 3: 1000ms delay
* child 4: 0ms delay
*
* @method Phaser.Animations.AnimationManager#staggerPlay
* @since 3.0.0
*
* @generic {Phaser.GameObjects.GameObject[]} G - [items,$return]
*
* @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object.
* @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} children - An array of Game Objects to play the animation on. They must have an Animation Component.
* @param {number} stagger - The amount of time, in milliseconds, to offset each play time by. If a negative value is given, it's applied to the children in reverse order.
* @param {boolean} [staggerFirst=true] -Should the first child be staggered as well?
*
* @return {this} This Animation Manager.
*/
staggerPlay: function(key, children, stagger, staggerFirst) {
if (stagger === void 0) {
stagger = 0;
}
if (staggerFirst === void 0) {
staggerFirst = true;
}
if (!Array.isArray(children)) {
children = [children];
}
var len = children.length;
if (!staggerFirst) {
len--;
}
for (var i = 0; i < children.length; i++) {
var time = stagger < 0 ? Math.abs(stagger) * (len - i) : stagger * i;
children[i].anims.playAfterDelay(key, time);
}
return this;
},
/**
* Removes an Animation from this Animation Manager, based on the given key.
*
* This is a global action. Once an Animation has been removed, no Game Objects
* can carry on using it.
*
* @method Phaser.Animations.AnimationManager#remove
* @fires Phaser.Animations.Events#REMOVE_ANIMATION
* @since 3.0.0
*
* @param {string} key - The key of the animation to remove.
*
* @return {Phaser.Animations.Animation} The Animation instance that was removed from the Animation Manager.
*/
remove: function(key) {
var anim = this.get(key);
if (anim) {
this.emit(Events.REMOVE_ANIMATION, key, anim);
this.anims.delete(key);
this.removeMix(key);
}
return anim;
},
/**
* Resume all paused animations.
*
* @method Phaser.Animations.AnimationManager#resumeAll
* @fires Phaser.Animations.Events#RESUME_ALL
* @since 3.0.0
*
* @return {this} This Animation Manager.
*/
resumeAll: function() {
if (this.paused) {
this.paused = false;
this.emit(Events.RESUME_ALL);
}
return this;
},
/**
* Returns the Animation data as JavaScript object based on the given key.
* Or, if not key is defined, it will return the data of all animations as array of objects.
*
* @method Phaser.Animations.AnimationManager#toJSON
* @since 3.0.0
*
* @param {string} [key] - The animation to get the JSONAnimation data from. If not provided, all animations are returned as an array.
*
* @return {Phaser.Types.Animations.JSONAnimations} The resulting JSONAnimations formatted object.
*/
toJSON: function(key) {
var output = {
anims: [],
globalTimeScale: this.globalTimeScale
};
if (key !== void 0 && key !== "") {
output.anims.push(this.anims.get(key).toJSON());
} else {
this.anims.each(function(animationKey, animation) {
output.anims.push(animation.toJSON());
});
}
return output;
},
/**
* Destroy this Animation Manager and clean up animation definitions and references to other objects.
* This method should not be called directly. It will be called automatically as a response to a `destroy` event from the Phaser.Game instance.
*
* @method Phaser.Animations.AnimationManager#destroy
* @since 3.0.0
*/
destroy: function() {
this.anims.clear();
this.mixes.clear();
this.textureManager = null;
this.game = null;
}
});
module2.exports = AnimationManager;
}
),
/***/
9674: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Animation = __webpack_require__2(42099);
var Between = __webpack_require__2(30976);
var Class = __webpack_require__2(83419);
var CustomMap = __webpack_require__2(90330);
var Events = __webpack_require__2(74943);
var GetFastValue = __webpack_require__2(95540);
var AnimationState = new Class({
initialize: function AnimationState2(parent) {
this.parent = parent;
this.animationManager = parent.scene.sys.anims;
this.animationManager.on(Events.REMOVE_ANIMATION, this.globalRemove, this);
this.textureManager = this.animationManager.textureManager;
this.anims = null;
this.isPlaying = false;
this.hasStarted = false;
this.currentAnim = null;
this.currentFrame = null;
this.nextAnim = null;
this.nextAnimsQueue = [];
this.timeScale = 1;
this.frameRate = 0;
this.duration = 0;
this.msPerFrame = 0;
this.skipMissedFrames = true;
this.randomFrame = false;
this.delay = 0;
this.repeat = 0;
this.repeatDelay = 0;
this.yoyo = false;
this.showBeforeDelay = false;
this.showOnStart = false;
this.hideOnComplete = false;
this.forward = true;
this.inReverse = false;
this.accumulator = 0;
this.nextTick = 0;
this.delayCounter = 0;
this.repeatCounter = 0;
this.pendingRepeat = false;
this._paused = false;
this._wasPlaying = false;
this._pendingStop = 0;
this._pendingStopValue;
},
/**
* Sets an animation, or an array of animations, to be played in the future, after the current one completes or stops.
*
* The current animation must enter a 'completed' state for this to happen, i.e. finish all of its repeats, delays, etc,
* or have one of the `stop` methods called.
*
* An animation set to repeat forever will never enter a completed state unless stopped.
*
* You can chain a new animation at any point, including before the current one starts playing, during it, or when it ends (via its `animationcomplete` event).
*
* Chained animations are specific to a Game Object, meaning different Game Objects can have different chained animations without impacting the global animation they're playing.
*
* Call this method with no arguments to reset all currently chained animations.
*
* @method Phaser.Animations.AnimationState#chain
* @since 3.16.0
*
* @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig|string[]|Phaser.Animations.Animation[]|Phaser.Types.Animations.PlayAnimationConfig[])} [key] - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object, or an array of them.
*
* @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component.
*/
chain: function(key) {
var parent = this.parent;
if (key === void 0) {
this.nextAnimsQueue.length = 0;
this.nextAnim = null;
return parent;
}
if (!Array.isArray(key)) {
key = [key];
}
for (var i = 0; i < key.length; i++) {
var anim = key[i];
if (!this.nextAnim) {
this.nextAnim = anim;
} else {
this.nextAnimsQueue.push(anim);
}
}
return this.parent;
},
/**
* Returns the key of the animation currently loaded into this component.
*
* Prior to Phaser 3.50 this method was called `getCurrentKey`.
*
* @method Phaser.Animations.AnimationState#getName
* @since 3.50.0
*
* @return {string} The key of the Animation currently loaded into this component, or an empty string if none loaded.
*/
getName: function() {
return this.currentAnim ? this.currentAnim.key : "";
},
/**
* Returns the key of the animation frame currently displayed by this component.
*
* @method Phaser.Animations.AnimationState#getFrameName
* @since 3.50.0
*
* @return {string} The key of the Animation Frame currently displayed by this component, or an empty string if no animation has been loaded.
*/
getFrameName: function() {
return this.currentFrame ? this.currentFrame.textureFrame : "";
},
/**
* Internal method used to load an animation into this component.
*
* @method Phaser.Animations.AnimationState#load
* @protected
* @since 3.0.0
*
* @param {(string|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or a `PlayAnimationConfig` object.
*
* @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component.
*/
load: function(key) {
if (this.isPlaying) {
this.stop();
}
var manager = this.animationManager;
var animKey = typeof key === "string" ? key : GetFastValue(key, "key", null);
var anim = this.exists(animKey) ? this.get(animKey) : manager.get(animKey);
if (!anim) {
console.warn("Missing animation: " + animKey);
} else {
this.currentAnim = anim;
var totalFrames = anim.getTotalFrames();
var frameRate = GetFastValue(key, "frameRate", anim.frameRate);
var duration = GetFastValue(key, "duration", anim.duration);
anim.calculateDuration(this, totalFrames, duration, frameRate);
this.delay = GetFastValue(key, "delay", anim.delay);
this.repeat = GetFastValue(key, "repeat", anim.repeat);
this.repeatDelay = GetFastValue(key, "repeatDelay", anim.repeatDelay);
this.yoyo = GetFastValue(key, "yoyo", anim.yoyo);
this.showBeforeDelay = GetFastValue(key, "showBeforeDelay", anim.showBeforeDelay);
this.showOnStart = GetFastValue(key, "showOnStart", anim.showOnStart);
this.hideOnComplete = GetFastValue(key, "hideOnComplete", anim.hideOnComplete);
this.skipMissedFrames = GetFastValue(key, "skipMissedFrames", anim.skipMissedFrames);
this.randomFrame = GetFastValue(key, "randomFrame", anim.randomFrame);
this.timeScale = GetFastValue(key, "timeScale", this.timeScale);
var startFrame = GetFastValue(key, "startFrame", 0);
if (startFrame > totalFrames) {
startFrame = 0;
}
if (this.randomFrame) {
startFrame = Between(0, totalFrames - 1);
}
var frame = anim.frames[startFrame];
if (startFrame === 0 && !this.forward) {
frame = anim.getLastFrame();
}
this.currentFrame = frame;
}
return this.parent;
},
/**
* Pause the current animation and set the `isPlaying` property to `false`.
* You can optionally pause it at a specific frame.
*
* @method Phaser.Animations.AnimationState#pause
* @since 3.0.0
*
* @param {Phaser.Animations.AnimationFrame} [atFrame] - An optional frame to set after pausing the animation.
*
* @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component.
*/
pause: function(atFrame) {
if (!this._paused) {
this._paused = true;
this._wasPlaying = this.isPlaying;
this.isPlaying = false;
}
if (atFrame !== void 0) {
this.setCurrentFrame(atFrame);
}
return this.parent;
},
/**
* Resumes playback of a paused animation and sets the `isPlaying` property to `true`.
* You can optionally tell it to start playback from a specific frame.
*
* @method Phaser.Animations.AnimationState#resume
* @since 3.0.0
*
* @param {Phaser.Animations.AnimationFrame} [fromFrame] - An optional frame to set before restarting playback.
*
* @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component.
*/
resume: function(fromFrame) {
if (this._paused) {
this._paused = false;
this.isPlaying = this._wasPlaying;
}
if (fromFrame !== void 0) {
this.setCurrentFrame(fromFrame);
}
return this.parent;
},
/**
* Waits for the specified delay, in milliseconds, then starts playback of the given animation.
*
* If the animation _also_ has a delay value set in its config, it will be **added** to the delay given here.
*
* If an animation is already running and a new animation is given to this method, it will wait for
* the given delay before starting the new animation.
*
* If no animation is currently running, the given one begins after the delay.
*
* Prior to Phaser 3.50 this method was called 'delayedPlay' and the parameters were in the reverse order.
*
* @method Phaser.Animations.AnimationState#playAfterDelay
* @fires Phaser.Animations.Events#ANIMATION_START
* @since 3.50.0
*
* @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object.
* @param {number} delay - The delay, in milliseconds, to wait before starting the animation playing.
*
* @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component.
*/
playAfterDelay: function(key, delay) {
if (!this.isPlaying) {
this.delayCounter = delay;
this.play(key, true);
} else {
var nextAnim = this.nextAnim;
var queue = this.nextAnimsQueue;
if (nextAnim) {
queue.unshift(nextAnim);
}
this.nextAnim = key;
this._pendingStop = 1;
this._pendingStopValue = delay;
}
return this.parent;
},
/**
* Waits for the current animation to complete the `repeatCount` number of repeat cycles, then starts playback
* of the given animation.
*
* You can use this to ensure there are no harsh jumps between two sets of animations, i.e. going from an
* idle animation to a walking animation, by making them blend smoothly into each other.
*
* If no animation is currently running, the given one will start immediately.
*
* @method Phaser.Animations.AnimationState#playAfterRepeat
* @fires Phaser.Animations.Events#ANIMATION_START
* @since 3.50.0
*
* @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object.
* @param {number} [repeatCount=1] - How many times should the animation repeat before the next one starts?
*
* @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component.
*/
playAfterRepeat: function(key, repeatCount) {
if (repeatCount === void 0) {
repeatCount = 1;
}
if (!this.isPlaying) {
this.play(key);
} else {
var nextAnim = this.nextAnim;
var queue = this.nextAnimsQueue;
if (nextAnim) {
queue.unshift(nextAnim);
}
if (this.repeatCounter !== -1 && repeatCount > this.repeatCounter) {
repeatCount = this.repeatCounter;
}
this.nextAnim = key;
this._pendingStop = 2;
this._pendingStopValue = repeatCount;
}
return this.parent;
},
/**
* Start playing the given animation on this Sprite.
*
* Animations in Phaser can either belong to the global Animation Manager, or specifically to this Sprite.
*
* The benefit of a global animation is that multiple Sprites can all play the same animation, without
* having to duplicate the data. You can just create it once and then play it on any Sprite.
*
* The following code shows how to create a global repeating animation. The animation will be created
* from all of the frames within the sprite sheet that was loaded with the key 'muybridge':
*
* ```javascript
* var config = {
* key: 'run',
* frames: 'muybridge',
* frameRate: 15,
* repeat: -1
* };
*
* // This code should be run from within a Scene:
* this.anims.create(config);
* ```
*
* However, if you wish to create an animation that is unique to this Sprite, and this Sprite alone,
* you can call the `Animation.create` method instead. It accepts the exact same parameters as when
* creating a global animation, however the resulting data is kept locally in this Sprite.
*
* With the animation created, either globally or locally, you can now play it on this Sprite:
*
* ```javascript
* this.add.sprite(x, y).play('run');
* ```
*
* Alternatively, if you wish to run it at a different frame rate, for example, you can pass a config
* object instead:
*
* ```javascript
* this.add.sprite(x, y).play({ key: 'run', frameRate: 24 });
* ```
*
* When playing an animation on a Sprite it will first check to see if it can find a matching key
* locally within the Sprite. If it can, it will play the local animation. If not, it will then
* search the global Animation Manager and look for it there.
*
* If you need a Sprite to be able to play both local and global animations, make sure they don't
* have conflicting keys.
*
* See the documentation for the `PlayAnimationConfig` config object for more details about this.
*
* Also, see the documentation in the Animation Manager for further details on creating animations.
*
* @method Phaser.Animations.AnimationState#play
* @fires Phaser.Animations.Events#ANIMATION_START
* @since 3.0.0
*
* @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object.
* @param {boolean} [ignoreIfPlaying=false] - If this animation is already playing then ignore this call.
*
* @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component.
*/
play: function(key, ignoreIfPlaying) {
if (ignoreIfPlaying === void 0) {
ignoreIfPlaying = false;
}
var currentAnim = this.currentAnim;
var parent = this.parent;
var animKey = typeof key === "string" ? key : key.key;
if (ignoreIfPlaying && this.isPlaying && currentAnim.key === animKey) {
return parent;
}
if (currentAnim && this.isPlaying) {
var mix = this.animationManager.getMix(currentAnim.key, key);
if (mix > 0) {
return this.playAfterDelay(key, mix);
}
}
this.forward = true;
this.inReverse = false;
this._paused = false;
this._wasPlaying = true;
return this.startAnimation(key);
},
/**
* Start playing the given animation on this Sprite, in reverse.
*
* Animations in Phaser can either belong to the global Animation Manager, or specifically to this Sprite.
*
* The benefit of a global animation is that multiple Sprites can all play the same animation, without
* having to duplicate the data. You can just create it once and then play it on any Sprite.
*
* The following code shows how to create a global repeating animation. The animation will be created
* from all of the frames within the sprite sheet that was loaded with the key 'muybridge':
*
* ```javascript
* var config = {
* key: 'run',
* frames: 'muybridge',
* frameRate: 15,
* repeat: -1
* };
*
* // This code should be run from within a Scene:
* this.anims.create(config);
* ```
*
* However, if you wish to create an animation that is unique to this Sprite, and this Sprite alone,
* you can call the `Animation.create` method instead. It accepts the exact same parameters as when
* creating a global animation, however the resulting data is kept locally in this Sprite.
*
* With the animation created, either globally or locally, you can now play it on this Sprite:
*
* ```javascript
* this.add.sprite(x, y).playReverse('run');
* ```
*
* Alternatively, if you wish to run it at a different frame rate, for example, you can pass a config
* object instead:
*
* ```javascript
* this.add.sprite(x, y).playReverse({ key: 'run', frameRate: 24 });
* ```
*
* When playing an animation on a Sprite it will first check to see if it can find a matching key
* locally within the Sprite. If it can, it will play the local animation. If not, it will then
* search the global Animation Manager and look for it there.
*
* If you need a Sprite to be able to play both local and global animations, make sure they don't
* have conflicting keys.
*
* See the documentation for the `PlayAnimationConfig` config object for more details about this.
*
* Also, see the documentation in the Animation Manager for further details on creating animations.
*
* @method Phaser.Animations.AnimationState#playReverse
* @fires Phaser.Animations.Events#ANIMATION_START
* @since 3.12.0
*
* @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object.
* @param {boolean} [ignoreIfPlaying=false] - If an animation is already playing then ignore this call.
*
* @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component.
*/
playReverse: function(key, ignoreIfPlaying) {
if (ignoreIfPlaying === void 0) {
ignoreIfPlaying = false;
}
var animKey = typeof key === "string" ? key : key.key;
if (ignoreIfPlaying && this.isPlaying && this.currentAnim.key === animKey) {
return this.parent;
}
this.forward = false;
this.inReverse = true;
this._paused = false;
this._wasPlaying = true;
return this.startAnimation(key);
},
/**
* Load the animation based on the key and set-up all of the internal values
* needed for playback to start. If there is no delay, it will also fire the start events.
*
* @method Phaser.Animations.AnimationState#startAnimation
* @fires Phaser.Animations.Events#ANIMATION_START
* @since 3.50.0
*
* @param {(string|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or a `PlayAnimationConfig` object.
*
* @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component.
*/
startAnimation: function(key) {
this.load(key);
var anim = this.currentAnim;
var gameObject = this.parent;
if (!anim) {
return gameObject;
}
this.repeatCounter = this.repeat === -1 ? Number.MAX_VALUE : this.repeat;
anim.getFirstTick(this);
this.isPlaying = true;
this.pendingRepeat = false;
this.hasStarted = false;
this._pendingStop = 0;
this._pendingStopValue = 0;
this._paused = false;
this.delayCounter += this.delay;
if (this.delayCounter === 0) {
this.handleStart();
} else if (this.showBeforeDelay) {
this.setCurrentFrame(this.currentFrame);
}
return gameObject;
},
/**
* Handles the start of an animation playback.
*
* @method Phaser.Animations.AnimationState#handleStart
* @private
* @since 3.50.0
*/
handleStart: function() {
if (this.showOnStart) {
this.parent.setVisible(true);
}
this.setCurrentFrame(this.currentFrame);
this.hasStarted = true;
this.emitEvents(Events.ANIMATION_START);
},
/**
* Handles the repeat of an animation.
*
* @method Phaser.Animations.AnimationState#handleRepeat
* @private
* @since 3.50.0
*/
handleRepeat: function() {
this.pendingRepeat = false;
this.emitEvents(Events.ANIMATION_REPEAT);
},
/**
* Handles the stop of an animation playback.
*
* @method Phaser.Animations.AnimationState#handleStop
* @private
* @since 3.50.0
*/
handleStop: function() {
this._pendingStop = 0;
this.isPlaying = false;
this.emitEvents(Events.ANIMATION_STOP);
},
/**
* Handles the completion of an animation playback.
*
* @method Phaser.Animations.AnimationState#handleComplete
* @private
* @since 3.50.0
*/
handleComplete: function() {
this._pendingStop = 0;
this.isPlaying = false;
if (this.hideOnComplete) {
this.parent.setVisible(false);
}
this.emitEvents(Events.ANIMATION_COMPLETE, Events.ANIMATION_COMPLETE_KEY);
},
/**
* Fires the given animation event.
*
* @method Phaser.Animations.AnimationState#emitEvents
* @private
* @since 3.50.0
*
* @param {string} event - The Animation Event to dispatch.
*/
emitEvents: function(event, keyEvent) {
var anim = this.currentAnim;
if (anim) {
var frame = this.currentFrame;
var gameObject = this.parent;
var frameKey = frame.textureFrame;
gameObject.emit(event, anim, frame, gameObject, frameKey);
if (keyEvent) {
gameObject.emit(keyEvent + anim.key, anim, frame, gameObject, frameKey);
}
}
},
/**
* Reverse the Animation that is already playing on the Game Object.
*
* @method Phaser.Animations.AnimationState#reverse
* @since 3.12.0
*
* @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component.
*/
reverse: function() {
if (this.isPlaying) {
this.inReverse = !this.inReverse;
this.forward = !this.forward;
}
return this.parent;
},
/**
* Returns a value between 0 and 1 indicating how far this animation is through, ignoring repeats and yoyos.
*
* The value is based on the current frame and how far that is in the animation, it is not based on
* the duration of the animation.
*
* @method Phaser.Animations.AnimationState#getProgress
* @since 3.4.0
*
* @return {number} The progress of the current animation in frames, between 0 and 1.
*/
getProgress: function() {
var frame = this.currentFrame;
if (!frame) {
return 0;
}
var p = frame.progress;
if (this.inReverse) {
p *= -1;
}
return p;
},
/**
* Takes a value between 0 and 1 and uses it to set how far this animation is through playback.
*
* Does not factor in repeats or yoyos, but does handle playing forwards or backwards.
*
* The value is based on the current frame and how far that is in the animation, it is not based on
* the duration of the animation.
*
* @method Phaser.Animations.AnimationState#setProgress
* @since 3.4.0
*
* @param {number} [value=0] - The progress value, between 0 and 1.
*
* @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component.
*/
setProgress: function(value) {
if (!this.forward) {
value = 1 - value;
}
this.setCurrentFrame(this.currentAnim.getFrameByProgress(value));
return this.parent;
},
/**
* Sets the number of times that the animation should repeat after its first play through.
* For example, if repeat is 1, the animation will play a total of twice: the initial play plus 1 repeat.
*
* To repeat indefinitely, use -1.
* The value should always be an integer.
*
* Calling this method only works if the animation is already running. Otherwise, any
* value specified here will be overwritten when the next animation loads in. To avoid this,
* use the `repeat` property of the `PlayAnimationConfig` object instead.
*
* @method Phaser.Animations.AnimationState#setRepeat
* @since 3.4.0
*
* @param {number} value - The number of times that the animation should repeat.
*
* @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component.
*/
setRepeat: function(value) {
this.repeatCounter = value === -1 ? Number.MAX_VALUE : value;
return this.parent;
},
/**
* Handle the removal of an animation from the Animation Manager.
*
* @method Phaser.Animations.AnimationState#globalRemove
* @since 3.50.0
*
* @param {string} [key] - The key of the removed Animation.
* @param {Phaser.Animations.Animation} [animation] - The removed Animation.
*/
globalRemove: function(key, animation) {
if (animation === void 0) {
animation = this.currentAnim;
}
if (this.isPlaying && animation.key === this.currentAnim.key) {
this.stop();
this.setCurrentFrame(this.currentAnim.frames[0]);
}
},
/**
* Restarts the current animation from its beginning.
*
* You can optionally reset the delay and repeat counters as well.
*
* Calling this will fire the `ANIMATION_RESTART` event immediately.
*
* If you `includeDelay` then it will also fire the `ANIMATION_START` event once
* the delay has expired, otherwise, playback will just begin immediately.
*
* @method Phaser.Animations.AnimationState#restart
* @fires Phaser.Animations.Events#ANIMATION_RESTART
* @since 3.0.0
*
* @param {boolean} [includeDelay=false] - Whether to include the delay value of the animation when restarting.
* @param {boolean} [resetRepeats=false] - Whether to reset the repeat counter or not?
*
* @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component.
*/
restart: function(includeDelay, resetRepeats) {
if (includeDelay === void 0) {
includeDelay = false;
}
if (resetRepeats === void 0) {
resetRepeats = false;
}
var anim = this.currentAnim;
var gameObject = this.parent;
if (!anim) {
return gameObject;
}
if (resetRepeats) {
this.repeatCounter = this.repeat === -1 ? Number.MAX_VALUE : this.repeat;
}
anim.getFirstTick(this);
this.emitEvents(Events.ANIMATION_RESTART);
this.isPlaying = true;
this.pendingRepeat = false;
this.hasStarted = !includeDelay;
this._pendingStop = 0;
this._pendingStopValue = 0;
this._paused = false;
this.setCurrentFrame(anim.frames[0]);
return this.parent;
},
/**
* The current animation has completed. This dispatches the `ANIMATION_COMPLETE` event.
*
* This method is called by the Animation instance and should not usually be invoked directly.
*
* If no animation is loaded, no events will be dispatched.
*
* If another animation has been queued for playback, it will be started after the events fire.
*
* @method Phaser.Animations.AnimationState#complete
* @fires Phaser.Animations.Events#ANIMATION_COMPLETE
* @since 3.50.0
*
* @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component.
*/
complete: function() {
this._pendingStop = 0;
this.isPlaying = false;
if (this.currentAnim) {
this.handleComplete();
}
if (this.nextAnim) {
var key = this.nextAnim;
this.nextAnim = this.nextAnimsQueue.length > 0 ? this.nextAnimsQueue.shift() : null;
this.play(key);
}
return this.parent;
},
/**
* Immediately stops the current animation from playing and dispatches the `ANIMATION_STOP` event.
*
* If no animation is running, no events will be dispatched.
*
* If there is another animation in the queue (set via the `chain` method) then it will start playing.
*
* @method Phaser.Animations.AnimationState#stop
* @fires Phaser.Animations.Events#ANIMATION_STOP
* @since 3.0.0
*
* @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component.
*/
stop: function() {
this._pendingStop = 0;
this.isPlaying = false;
this.delayCounter = 0;
if (this.currentAnim) {
this.handleStop();
}
if (this.nextAnim) {
var key = this.nextAnim;
this.nextAnim = this.nextAnimsQueue.shift();
this.play(key);
}
return this.parent;
},
/**
* Stops the current animation from playing after the specified time delay, given in milliseconds.
*
* It then dispatches the `ANIMATION_STOP` event.
*
* If no animation is running, no events will be dispatched.
*
* If there is another animation in the queue (set via the `chain` method) then it will start playing,
* when the current one stops.
*
* @method Phaser.Animations.AnimationState#stopAfterDelay
* @fires Phaser.Animations.Events#ANIMATION_STOP
* @since 3.4.0
*
* @param {number} delay - The number of milliseconds to wait before stopping this animation.
*
* @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component.
*/
stopAfterDelay: function(delay) {
this._pendingStop = 1;
this._pendingStopValue = delay;
return this.parent;
},
/**
* Stops the current animation from playing when it next repeats.
*
* It then dispatches the `ANIMATION_STOP` event.
*
* If no animation is running, no events will be dispatched.
*
* If there is another animation in the queue (set via the `chain` method) then it will start playing,
* when the current one stops.
*
* Prior to Phaser 3.50 this method was called `stopOnRepeat` and had no parameters.
*
* @method Phaser.Animations.AnimationState#stopAfterRepeat
* @fires Phaser.Animations.Events#ANIMATION_STOP
* @since 3.50.0
*
* @param {number} [repeatCount=1] - How many times should the animation repeat before stopping?
*
* @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component.
*/
stopAfterRepeat: function(repeatCount) {
if (repeatCount === void 0) {
repeatCount = 1;
}
if (this.repeatCounter !== -1 && repeatCount > this.repeatCounter) {
repeatCount = this.repeatCounter;
}
this._pendingStop = 2;
this._pendingStopValue = repeatCount;
return this.parent;
},
/**
* Stops the current animation from playing when it next sets the given frame.
* If this frame doesn't exist within the animation it will not stop it from playing.
*
* It then dispatches the `ANIMATION_STOP` event.
*
* If no animation is running, no events will be dispatched.
*
* If there is another animation in the queue (set via the `chain` method) then it will start playing,
* when the current one stops.
*
* @method Phaser.Animations.AnimationState#stopOnFrame
* @fires Phaser.Animations.Events#ANIMATION_STOP
* @since 3.4.0
*
* @param {Phaser.Animations.AnimationFrame} frame - The frame to check before stopping this animation.
*
* @return {Phaser.GameObjects.GameObject} The Game Object that owns this Animation Component.
*/
stopOnFrame: function(frame) {
this._pendingStop = 3;
this._pendingStopValue = frame;
return this.parent;
},
/**
* Returns the total number of frames in this animation, or returns zero if no
* animation has been loaded.
*
* @method Phaser.Animations.AnimationState#getTotalFrames
* @since 3.4.0
*
* @return {number} The total number of frames in the current animation, or zero if no animation has been loaded.
*/
getTotalFrames: function() {
return this.currentAnim ? this.currentAnim.getTotalFrames() : 0;
},
/**
* The internal update loop for the AnimationState Component.
*
* This is called automatically by the `Sprite.preUpdate` method.
*
* @method Phaser.Animations.AnimationState#update
* @since 3.0.0
*
* @param {number} time - The current timestamp.
* @param {number} delta - The delta time, in ms, elapsed since the last frame.
*/
update: function(time, delta) {
var anim = this.currentAnim;
if (!this.isPlaying || !anim || anim.paused) {
return;
}
this.accumulator += delta * this.timeScale * this.animationManager.globalTimeScale;
if (this._pendingStop === 1) {
this._pendingStopValue -= delta;
if (this._pendingStopValue <= 0) {
return this.stop();
}
}
if (!this.hasStarted) {
if (this.accumulator >= this.delayCounter) {
this.accumulator -= this.delayCounter;
this.handleStart();
}
} else if (this.accumulator >= this.nextTick) {
if (this.forward) {
anim.nextFrame(this);
} else {
anim.previousFrame(this);
}
if (this.isPlaying && this._pendingStop === 0 && this.skipMissedFrames && this.accumulator > this.nextTick) {
var safetyNet = 0;
do {
if (this.forward) {
anim.nextFrame(this);
} else {
anim.previousFrame(this);
}
safetyNet++;
} while (this.isPlaying && this.accumulator > this.nextTick && safetyNet < 60);
}
}
},
/**
* Sets the given Animation Frame as being the current frame
* and applies it to the parent Game Object, adjusting size and origin as needed.
*
* @method Phaser.Animations.AnimationState#setCurrentFrame
* @fires Phaser.Animations.Events#ANIMATION_UPDATE
* @fires Phaser.Animations.Events#ANIMATION_STOP
* @since 3.4.0
*
* @param {Phaser.Animations.AnimationFrame} animationFrame - The animation frame to change to.
*
* @return {Phaser.GameObjects.GameObject} The Game Object this Animation Component belongs to.
*/
setCurrentFrame: function(animationFrame) {
var gameObject = this.parent;
this.currentFrame = animationFrame;
gameObject.texture = animationFrame.frame.texture;
gameObject.frame = animationFrame.frame;
if (gameObject.isCropped) {
gameObject.frame.updateCropUVs(gameObject._crop, gameObject.flipX, gameObject.flipY);
}
if (animationFrame.setAlpha) {
gameObject.alpha = animationFrame.alpha;
}
gameObject.setSizeToFrame();
if (gameObject._originComponent) {
if (animationFrame.frame.customPivot) {
gameObject.setOrigin(animationFrame.frame.pivotX, animationFrame.frame.pivotY);
} else {
gameObject.updateDisplayOrigin();
}
}
if (this.isPlaying && this.hasStarted) {
this.emitEvents(Events.ANIMATION_UPDATE);
if (this._pendingStop === 3 && this._pendingStopValue === animationFrame) {
this.stop();
}
}
return gameObject;
},
/**
* Advances the animation to the next frame, regardless of the time or animation state.
* If the animation is set to repeat, or yoyo, this will still take effect.
*
* Calling this does not change the direction of the animation. I.e. if it was currently
* playing in reverse, calling this method doesn't then change the direction to forwards.
*
* @method Phaser.Animations.AnimationState#nextFrame
* @since 3.16.0
*
* @return {Phaser.GameObjects.GameObject} The Game Object this Animation Component belongs to.
*/
nextFrame: function() {
if (this.currentAnim) {
this.currentAnim.nextFrame(this);
}
return this.parent;
},
/**
* Advances the animation to the previous frame, regardless of the time or animation state.
* If the animation is set to repeat, or yoyo, this will still take effect.
*
* Calling this does not change the direction of the animation. I.e. if it was currently
* playing in forwards, calling this method doesn't then change the direction to backwards.
*
* @method Phaser.Animations.AnimationState#previousFrame
* @since 3.16.0
*
* @return {Phaser.GameObjects.GameObject} The Game Object this Animation Component belongs to.
*/
previousFrame: function() {
if (this.currentAnim) {
this.currentAnim.previousFrame(this);
}
return this.parent;
},
/**
* Get an Animation instance that has been created locally on this Sprite.
*
* See the `create` method for more details.
*
* @method Phaser.Animations.AnimationState#get
* @since 3.50.0
*
* @param {string} key - The key of the Animation to retrieve.
*
* @return {Phaser.Animations.Animation} The Animation, or `null` if the key is invalid.
*/
get: function(key) {
return this.anims ? this.anims.get(key) : null;
},
/**
* Checks to see if the given key is already used locally within the animations stored on this Sprite.
*
* @method Phaser.Animations.AnimationState#exists
* @since 3.50.0
*
* @param {string} key - The key of the Animation to check.
*
* @return {boolean} `true` if the Animation exists locally, or `false` if the key is available, or there are no local animations.
*/
exists: function(key) {
return this.anims ? this.anims.has(key) : false;
},
/**
* Creates a new Animation that is local specifically to this Sprite.
*
* When a Sprite owns an animation, it is kept out of the global Animation Manager, which means
* you're free to use keys that may be already defined there. Unless you specifically need a Sprite
* to have a unique animation, you should favor using global animations instead, as they allow for
* the same animation to be used across multiple Sprites, saving on memory. However, if this Sprite
* is the only one to use this animation, it's sensible to create it here.
*
* If an invalid key is given this method will return `false`.
*
* If you pass the key of an animation that already exists locally, that animation will be returned.
*
* A brand new animation is only created if the key is valid and not already in use by this Sprite.
*
* If you wish to re-use an existing key, call the `remove` method first, then this method.
*
* @method Phaser.Animations.AnimationState#create
* @since 3.50.0
*
* @param {Phaser.Types.Animations.Animation} config - The configuration settings for the Animation.
*
* @return {(Phaser.Animations.Animation|false)} The Animation that was created, or `false` if the key is already in use.
*/
create: function(config) {
var key = config.key;
var anim = false;
if (key) {
anim = this.get(key);
if (!anim) {
anim = new Animation(this, key, config);
if (!this.anims) {
this.anims = new CustomMap();
}
this.anims.set(key, anim);
} else {
console.warn("Animation key already exists: " + key);
}
}
return anim;
},
/**
* Create one, or more animations from a loaded Aseprite JSON file.
*
* Aseprite is a powerful animated sprite editor and pixel art tool.
*
* You can find more details at https://www.aseprite.org/
*
* To export a compatible JSON file in Aseprite, please do the following:
*
* 1. Go to "File - Export Sprite Sheet"
*
* 2. On the **Layout** tab:
* 2a. Set the "Sheet type" to "Packed"
* 2b. Set the "Constraints" to "None"
* 2c. Check the "Merge Duplicates" checkbox
*
* 3. On the **Sprite** tab:
* 3a. Set "Layers" to "Visible layers"
* 3b. Set "Frames" to "All frames", unless you only wish to export a sub-set of tags
*
* 4. On the **Borders** tab:
* 4a. Check the "Trim Sprite" and "Trim Cells" options
* 4b. Ensure "Border Padding", "Spacing" and "Inner Padding" are all > 0 (1 is usually enough)
*
* 5. On the **Output** tab:
* 5a. Check "Output File", give your image a name and make sure you choose "png files" as the file type
* 5b. Check "JSON Data" and give your json file a name
* 5c. The JSON Data type can be either a Hash or Array, Phaser doesn't mind.
* 5d. Make sure "Tags" is checked in the Meta options
* 5e. In the "Item Filename" input box, make sure it says just "{frame}" and nothing more.
*
* 6. Click export
*
* This was tested with Aseprite 1.2.25.
*
* This will export a png and json file which you can load using the Aseprite Loader, i.e.:
*
* ```javascript
* function preload ()
* {
* this.load.path = 'assets/animations/aseprite/';
* this.load.aseprite('paladin', 'paladin.png', 'paladin.json');
* }
* ```
*
* Once loaded, you can call this method on a Sprite with the 'atlas' key:
*
* ```javascript
* const sprite = this.add.sprite(400, 300);
*
* sprite.anims.createFromAseprite('paladin');
* ```
*
* Any animations defined in the JSON will now be available to use on this Sprite and you play them
* via their Tag name. For example, if you have an animation called 'War Cry' on your Aseprite timeline,
* you can play it on the Sprite using that Tag name:
*
* ```javascript
* const sprite = this.add.sprite(400, 300);
*
* sprite.anims.createFromAseprite('paladin');
*
* sprite.play('War Cry');
* ```
*
* When calling this method you can optionally provide an array of tag names, and only those animations
* will be created. For example:
*
* ```javascript
* sprite.anims.createFromAseprite('paladin', [ 'step', 'War Cry', 'Magnum Break' ]);
* ```
*
* This will only create the 3 animations defined. Note that the tag names are case-sensitive.
*
* @method Phaser.Animations.AnimationState#createFromAseprite
* @since 3.60.0
*
* @param {string} key - The key of the loaded Aseprite atlas. It must have been loaded prior to calling this method.
* @param {string[]} [tags] - An array of Tag names. If provided, only animations found in this array will be created.
*
* @return {Phaser.Animations.Animation[]} An array of Animation instances that were successfully created.
*/
createFromAseprite: function(key, tags) {
return this.animationManager.createFromAseprite(key, tags, this.parent);
},
/**
* Generate an array of {@link Phaser.Types.Animations.AnimationFrame} objects from a texture key and configuration object.
*
* Generates objects with string based frame names, as configured by the given {@link Phaser.Types.Animations.GenerateFrameNames}.
*
* It's a helper method, designed to make it easier for you to extract all of the frame names from texture atlases.
* If you're working with a sprite sheet, see the `generateFrameNumbers` method instead.
*
* Example:
*
* If you have a texture atlases loaded called `gems` and it contains 6 frames called `ruby_0001`, `ruby_0002`, and so on,
* then you can call this method using: `this.anims.generateFrameNames('gems', { prefix: 'ruby_', end: 6, zeroPad: 4 })`.
*
* The `end` value tells it to look for 6 frames, incrementally numbered, all starting with the prefix `ruby_`. The `zeroPad`
* value tells it how many zeroes pad out the numbers. To create an animation using this method, you can do:
*
* ```javascript
* this.anims.create({
* key: 'ruby',
* repeat: -1,
* frames: this.anims.generateFrameNames('gems', {
* prefix: 'ruby_',
* end: 6,
* zeroPad: 4
* })
* });
* ```
*
* Please see the animation examples for further details.
*
* @method Phaser.Animations.AnimationState#generateFrameNames
* @since 3.50.0
*
* @param {string} key - The key for the texture containing the animation frames.
* @param {Phaser.Types.Animations.GenerateFrameNames} [config] - The configuration object for the animation frame names.
*
* @return {Phaser.Types.Animations.AnimationFrame[]} The array of {@link Phaser.Types.Animations.AnimationFrame} objects.
*/
generateFrameNames: function(key, config) {
return this.animationManager.generateFrameNames(key, config);
},
/**
* Generate an array of {@link Phaser.Types.Animations.AnimationFrame} objects from a texture key and configuration object.
*
* Generates objects with numbered frame names, as configured by the given {@link Phaser.Types.Animations.GenerateFrameNumbers}.
*
* If you're working with a texture atlas, see the `generateFrameNames` method instead.
*
* It's a helper method, designed to make it easier for you to extract frames from sprite sheets.
* If you're working with a texture atlas, see the `generateFrameNames` method instead.
*
* Example:
*
* If you have a sprite sheet loaded called `explosion` and it contains 12 frames, then you can call this method using:
* `this.anims.generateFrameNumbers('explosion', { start: 0, end: 11 })`.
*
* The `end` value tells it to stop after 12 frames. To create an animation using this method, you can do:
*
* ```javascript
* this.anims.create({
* key: 'boom',
* frames: this.anims.generateFrameNumbers('explosion', {
* start: 0,
* end: 11
* })
* });
* ```
*
* Note that `start` is optional and you don't need to include it if the animation starts from frame 0.
*
* To specify an animation in reverse, swap the `start` and `end` values.
*
* If the frames are not sequential, you may pass an array of frame numbers instead, for example:
*
* `this.anims.generateFrameNumbers('explosion', { frames: [ 0, 1, 2, 1, 2, 3, 4, 0, 1, 2 ] })`
*
* Please see the animation examples and `GenerateFrameNumbers` config docs for further details.
*
* @method Phaser.Animations.AnimationState#generateFrameNumbers
* @since 3.50.0
*
* @param {string} key - The key for the texture containing the animation frames.
* @param {Phaser.Types.Animations.GenerateFrameNumbers} [config] - The configuration object for the animation frames.
*
* @return {Phaser.Types.Animations.AnimationFrame[]} The array of {@link Phaser.Types.Animations.AnimationFrame} objects.
*/
generateFrameNumbers: function(key, config) {
return this.animationManager.generateFrameNumbers(key, config);
},
/**
* Removes a locally created Animation from this Sprite, based on the given key.
*
* Once an Animation has been removed, this Sprite cannot play it again without re-creating it.
*
* @method Phaser.Animations.AnimationState#remove
* @since 3.50.0
*
* @param {string} key - The key of the animation to remove.
*
* @return {Phaser.Animations.Animation} The Animation instance that was removed from this Sprite, if the key was valid.
*/
remove: function(key) {
var anim = this.get(key);
if (anim) {
if (this.currentAnim === anim) {
this.stop();
}
this.anims.delete(key);
}
return anim;
},
/**
* Destroy this Animation component.
*
* Unregisters event listeners and cleans up its references.
*
* @method Phaser.Animations.AnimationState#destroy
* @since 3.0.0
*/
destroy: function() {
this.animationManager.off(Events.REMOVE_ANIMATION, this.globalRemove, this);
if (this.anims) {
this.anims.clear();
}
this.animationManager = null;
this.parent = null;
this.nextAnim = null;
this.nextAnimsQueue.length = 0;
this.currentAnim = null;
this.currentFrame = null;
},
/**
* `true` if the current animation is paused, otherwise `false`.
*
* @name Phaser.Animations.AnimationState#isPaused
* @readonly
* @type {boolean}
* @since 3.4.0
*/
isPaused: {
get: function() {
return this._paused;
}
}
});
module2.exports = AnimationState;
}
),
/***/
57090: (
/***/
(module2) => {
module2.exports = "add";
}
),
/***/
25312: (
/***/
(module2) => {
module2.exports = "animationcomplete";
}
),
/***/
89580: (
/***/
(module2) => {
module2.exports = "animationcomplete-";
}
),
/***/
52860: (
/***/
(module2) => {
module2.exports = "animationrepeat";
}
),
/***/
63850: (
/***/
(module2) => {
module2.exports = "animationrestart";
}
),
/***/
99085: (
/***/
(module2) => {
module2.exports = "animationstart";
}
),
/***/
28087: (
/***/
(module2) => {
module2.exports = "animationstop";
}
),
/***/
1794: (
/***/
(module2) => {
module2.exports = "animationupdate";
}
),
/***/
52562: (
/***/
(module2) => {
module2.exports = "pauseall";
}
),
/***/
57953: (
/***/
(module2) => {
module2.exports = "remove";
}
),
/***/
68339: (
/***/
(module2) => {
module2.exports = "resumeall";
}
),
/***/
74943: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
ADD_ANIMATION: __webpack_require__2(57090),
ANIMATION_COMPLETE: __webpack_require__2(25312),
ANIMATION_COMPLETE_KEY: __webpack_require__2(89580),
ANIMATION_REPEAT: __webpack_require__2(52860),
ANIMATION_RESTART: __webpack_require__2(63850),
ANIMATION_START: __webpack_require__2(99085),
ANIMATION_STOP: __webpack_require__2(28087),
ANIMATION_UPDATE: __webpack_require__2(1794),
PAUSE_ALL: __webpack_require__2(52562),
REMOVE_ANIMATION: __webpack_require__2(57953),
RESUME_ALL: __webpack_require__2(68339)
};
}
),
/***/
60421: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Animation: __webpack_require__2(42099),
AnimationFrame: __webpack_require__2(41138),
AnimationManager: __webpack_require__2(60848),
AnimationState: __webpack_require__2(9674),
Events: __webpack_require__2(74943)
};
}
),
/***/
2161: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CustomMap = __webpack_require__2(90330);
var EventEmitter = __webpack_require__2(50792);
var Events = __webpack_require__2(24736);
var BaseCache = new Class({
initialize: function BaseCache2() {
this.entries = new CustomMap();
this.events = new EventEmitter();
},
/**
* Adds an item to this cache. The item is referenced by a unique string, which you are responsible
* for setting and keeping track of. The item can only be retrieved by using this string.
*
* @method Phaser.Cache.BaseCache#add
* @fires Phaser.Cache.Events#ADD
* @since 3.0.0
*
* @param {string} key - The unique key by which the data added to the cache will be referenced.
* @param {*} data - The data to be stored in the cache.
*
* @return {this} This BaseCache object.
*/
add: function(key, data) {
this.entries.set(key, data);
this.events.emit(Events.ADD, this, key, data);
return this;
},
/**
* Checks if this cache contains an item matching the given key.
* This performs the same action as `BaseCache.exists`.
*
* @method Phaser.Cache.BaseCache#has
* @since 3.0.0
*
* @param {string} key - The unique key of the item to be checked in this cache.
*
* @return {boolean} Returns `true` if the cache contains an item matching the given key, otherwise `false`.
*/
has: function(key) {
return this.entries.has(key);
},
/**
* Checks if this cache contains an item matching the given key.
* This performs the same action as `BaseCache.has` and is called directly by the Loader.
*
* @method Phaser.Cache.BaseCache#exists
* @since 3.7.0
*
* @param {string} key - The unique key of the item to be checked in this cache.
*
* @return {boolean} Returns `true` if the cache contains an item matching the given key, otherwise `false`.
*/
exists: function(key) {
return this.entries.has(key);
},
/**
* Gets an item from this cache based on the given key.
*
* @method Phaser.Cache.BaseCache#get
* @since 3.0.0
*
* @param {string} key - The unique key of the item to be retrieved from this cache.
*
* @return {*} The item in the cache, or `null` if no item matching the given key was found.
*/
get: function(key) {
return this.entries.get(key);
},
/**
* Removes and item from this cache based on the given key.
*
* If an entry matching the key is found it is removed from the cache and a `remove` event emitted.
* No additional checks are done on the item removed. If other systems or parts of your game code
* are relying on this item, it is up to you to sever those relationships prior to removing the item.
*
* @method Phaser.Cache.BaseCache#remove
* @fires Phaser.Cache.Events#REMOVE
* @since 3.0.0
*
* @param {string} key - The unique key of the item to remove from the cache.
*
* @return {this} This BaseCache object.
*/
remove: function(key) {
var entry = this.get(key);
if (entry) {
this.entries.delete(key);
this.events.emit(Events.REMOVE, this, key, entry.data);
}
return this;
},
/**
* Returns all keys in use in this cache.
*
* @method Phaser.Cache.BaseCache#getKeys
* @since 3.17.0
*
* @return {string[]} Array containing all the keys.
*/
getKeys: function() {
return this.entries.keys();
},
/**
* Destroys this cache and all items within it.
*
* @method Phaser.Cache.BaseCache#destroy
* @since 3.0.0
*/
destroy: function() {
this.entries.clear();
this.events.removeAllListeners();
this.entries = null;
this.events = null;
}
});
module2.exports = BaseCache;
}
),
/***/
24047: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BaseCache = __webpack_require__2(2161);
var Class = __webpack_require__2(83419);
var GameEvents = __webpack_require__2(8443);
var CacheManager = new Class({
initialize: function CacheManager2(game) {
this.game = game;
this.binary = new BaseCache();
this.bitmapFont = new BaseCache();
this.json = new BaseCache();
this.physics = new BaseCache();
this.shader = new BaseCache();
this.audio = new BaseCache();
this.video = new BaseCache();
this.text = new BaseCache();
this.html = new BaseCache();
this.obj = new BaseCache();
this.tilemap = new BaseCache();
this.xml = new BaseCache();
this.custom = {};
this.game.events.once(GameEvents.DESTROY, this.destroy, this);
},
/**
* Add your own custom Cache for storing your own files.
* The cache will be available under `Cache.custom.key`.
* The cache will only be created if the key is not already in use.
*
* @method Phaser.Cache.CacheManager#addCustom
* @since 3.0.0
*
* @param {string} key - The unique key of your custom cache.
*
* @return {Phaser.Cache.BaseCache} A reference to the BaseCache that was created. If the key was already in use, a reference to the existing cache is returned instead.
*/
addCustom: function(key) {
if (!this.custom.hasOwnProperty(key)) {
this.custom[key] = new BaseCache();
}
return this.custom[key];
},
/**
* Removes all entries from all BaseCaches and destroys all custom caches.
*
* @method Phaser.Cache.CacheManager#destroy
* @since 3.0.0
*/
destroy: function() {
var keys = [
"binary",
"bitmapFont",
"json",
"physics",
"shader",
"audio",
"video",
"text",
"html",
"obj",
"tilemap",
"xml"
];
for (var i = 0; i < keys.length; i++) {
this[keys[i]].destroy();
this[keys[i]] = null;
}
for (var key in this.custom) {
this.custom[key].destroy();
}
this.custom = null;
this.game = null;
}
});
module2.exports = CacheManager;
}
),
/***/
51464: (
/***/
(module2) => {
module2.exports = "add";
}
),
/***/
59261: (
/***/
(module2) => {
module2.exports = "remove";
}
),
/***/
24736: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
ADD: __webpack_require__2(51464),
REMOVE: __webpack_require__2(59261)
};
}
),
/***/
83388: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
BaseCache: __webpack_require__2(2161),
CacheManager: __webpack_require__2(24047),
Events: __webpack_require__2(24736)
};
}
),
/***/
71911: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31401);
var DegToRad = __webpack_require__2(39506);
var EventEmitter = __webpack_require__2(50792);
var Events = __webpack_require__2(19715);
var Rectangle = __webpack_require__2(87841);
var TransformMatrix = __webpack_require__2(61340);
var ValueToColor = __webpack_require__2(80333);
var Vector2 = __webpack_require__2(26099);
var BaseCamera = new Class({
Extends: EventEmitter,
Mixins: [
Components.AlphaSingle,
Components.Visible
],
initialize: function BaseCamera2(x, y, width, height) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (width === void 0) {
width = 0;
}
if (height === void 0) {
height = 0;
}
EventEmitter.call(this);
this.scene;
this.sceneManager;
this.scaleManager;
this.cameraManager;
this.id = 0;
this.name = "";
this.roundPixels = false;
this.useBounds = false;
this.worldView = new Rectangle();
this.dirty = true;
this._x = x;
this._y = y;
this._width = width;
this._height = height;
this._bounds = new Rectangle();
this._scrollX = 0;
this._scrollY = 0;
this._zoomX = 1;
this._zoomY = 1;
this._rotation = 0;
this.matrix = new TransformMatrix();
this.transparent = true;
this.backgroundColor = ValueToColor("rgba(0,0,0,0)");
this.disableCull = false;
this.culledObjects = [];
this.midPoint = new Vector2(width / 2, height / 2);
this.originX = 0.5;
this.originY = 0.5;
this._customViewport = false;
this.mask = null;
this._maskCamera = null;
this.renderList = [];
this.isSceneCamera = true;
this.renderRoundPixels = true;
},
/**
* Adds the given Game Object to this cameras render list.
*
* This is invoked during the rendering stage. Only objects that are actually rendered
* will appear in the render list.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#addToRenderList
* @since 3.52.0
*
* @param {Phaser.GameObjects.GameObject} child - The Game Object to add to the render list.
*/
addToRenderList: function(child) {
this.renderList.push(child);
},
/**
* Set the Alpha level of this Camera. The alpha controls the opacity of the Camera as it renders.
* Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#setAlpha
* @since 3.11.0
*
* @param {number} [value=1] - The Camera alpha value.
*
* @return {this} This Camera instance.
*/
/**
* Sets the rotation origin of this Camera.
*
* The values are given in the range 0 to 1 and are only used when calculating Camera rotation.
*
* By default the camera rotates around the center of the viewport.
*
* Changing the origin allows you to adjust the point in the viewport from which rotation happens.
* A value of 0 would rotate from the top-left of the viewport. A value of 1 from the bottom right.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#setOrigin
* @since 3.11.0
*
* @param {number} [x=0.5] - The horizontal origin value.
* @param {number} [y=x] - The vertical origin value. If not defined it will be set to the value of `x`.
*
* @return {this} This Camera instance.
*/
setOrigin: function(x, y) {
if (x === void 0) {
x = 0.5;
}
if (y === void 0) {
y = x;
}
this.originX = x;
this.originY = y;
return this;
},
/**
* Calculates what the Camera.scrollX and scrollY values would need to be in order to move
* the Camera so it is centered on the given x and y coordinates, without actually moving
* the Camera there. The results are clamped based on the Camera bounds, if set.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#getScroll
* @since 3.11.0
*
* @param {number} x - The horizontal coordinate to center on.
* @param {number} y - The vertical coordinate to center on.
* @param {Phaser.Math.Vector2} [out] - A Vector2 to store the values in. If not given a new Vector2 is created.
*
* @return {Phaser.Math.Vector2} The scroll coordinates stored in the `x` and `y` properties.
*/
getScroll: function(x, y, out) {
if (out === void 0) {
out = new Vector2();
}
var originX = this.width * 0.5;
var originY = this.height * 0.5;
out.x = x - originX;
out.y = y - originY;
if (this.useBounds) {
out.x = this.clampX(out.x);
out.y = this.clampY(out.y);
}
return out;
},
/**
* Moves the Camera horizontally so that it is centered on the given x coordinate, bounds allowing.
* Calling this does not change the scrollY value.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#centerOnX
* @since 3.16.0
*
* @param {number} x - The horizontal coordinate to center on.
*
* @return {this} This Camera instance.
*/
centerOnX: function(x) {
var originX = this.width * 0.5;
this.midPoint.x = x;
this.scrollX = x - originX;
if (this.useBounds) {
this.scrollX = this.clampX(this.scrollX);
}
return this;
},
/**
* Moves the Camera vertically so that it is centered on the given y coordinate, bounds allowing.
* Calling this does not change the scrollX value.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#centerOnY
* @since 3.16.0
*
* @param {number} y - The vertical coordinate to center on.
*
* @return {this} This Camera instance.
*/
centerOnY: function(y) {
var originY = this.height * 0.5;
this.midPoint.y = y;
this.scrollY = y - originY;
if (this.useBounds) {
this.scrollY = this.clampY(this.scrollY);
}
return this;
},
/**
* Moves the Camera so that it is centered on the given coordinates, bounds allowing.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#centerOn
* @since 3.11.0
*
* @param {number} x - The horizontal coordinate to center on.
* @param {number} y - The vertical coordinate to center on.
*
* @return {this} This Camera instance.
*/
centerOn: function(x, y) {
this.centerOnX(x);
this.centerOnY(y);
return this;
},
/**
* Moves the Camera so that it is looking at the center of the Camera Bounds, if enabled.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#centerToBounds
* @since 3.0.0
*
* @return {this} This Camera instance.
*/
centerToBounds: function() {
if (this.useBounds) {
var bounds = this._bounds;
var originX = this.width * 0.5;
var originY = this.height * 0.5;
this.midPoint.set(bounds.centerX, bounds.centerY);
this.scrollX = bounds.centerX - originX;
this.scrollY = bounds.centerY - originY;
}
return this;
},
/**
* Moves the Camera so that it is re-centered based on its viewport size.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#centerToSize
* @since 3.0.0
*
* @return {this} This Camera instance.
*/
centerToSize: function() {
this.scrollX = this.width * 0.5;
this.scrollY = this.height * 0.5;
return this;
},
/**
* Takes an array of Game Objects and returns a new array featuring only those objects
* visible by this camera.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#cull
* @since 3.0.0
*
* @generic {Phaser.GameObjects.GameObject[]} G - [renderableObjects,$return]
*
* @param {Phaser.GameObjects.GameObject[]} renderableObjects - An array of Game Objects to cull.
*
* @return {Phaser.GameObjects.GameObject[]} An array of Game Objects visible to this Camera.
*/
cull: function(renderableObjects) {
if (this.disableCull) {
return renderableObjects;
}
var cameraMatrix = this.matrix.matrix;
var mva = cameraMatrix[0];
var mvb = cameraMatrix[1];
var mvc = cameraMatrix[2];
var mvd = cameraMatrix[3];
var determinant = mva * mvd - mvb * mvc;
if (!determinant) {
return renderableObjects;
}
var mve = cameraMatrix[4];
var mvf = cameraMatrix[5];
var scrollX = this.scrollX;
var scrollY = this.scrollY;
var cameraW = this.width;
var cameraH = this.height;
var cullTop = this.y;
var cullBottom = cullTop + cameraH;
var cullLeft = this.x;
var cullRight = cullLeft + cameraW;
var culledObjects = this.culledObjects;
var length = renderableObjects.length;
determinant = 1 / determinant;
culledObjects.length = 0;
for (var index = 0; index < length; ++index) {
var object = renderableObjects[index];
if (!object.hasOwnProperty("width") || object.parentContainer) {
culledObjects.push(object);
continue;
}
var objectW = object.width;
var objectH = object.height;
var objectX = object.x - scrollX * object.scrollFactorX - objectW * object.originX;
var objectY = object.y - scrollY * object.scrollFactorY - objectH * object.originY;
var tx = objectX * mva + objectY * mvc + mve;
var ty = objectX * mvb + objectY * mvd + mvf;
var tw = (objectX + objectW) * mva + (objectY + objectH) * mvc + mve;
var th = (objectX + objectW) * mvb + (objectY + objectH) * mvd + mvf;
if (tw > cullLeft && tx < cullRight && (th > cullTop && ty < cullBottom)) {
culledObjects.push(object);
}
}
return culledObjects;
},
/**
* Converts the given `x` and `y` coordinates into World space, based on this Cameras transform.
* You can optionally provide a Vector2, or similar object, to store the results in.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#getWorldPoint
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2} O - [output,$return]
*
* @param {number} x - The x position to convert to world space.
* @param {number} y - The y position to convert to world space.
* @param {(object|Phaser.Math.Vector2)} [output] - An optional object to store the results in. If not provided a new Vector2 will be created.
*
* @return {Phaser.Math.Vector2} An object holding the converted values in its `x` and `y` properties.
*/
getWorldPoint: function(x, y, output) {
if (output === void 0) {
output = new Vector2();
}
var cameraMatrix = this.matrix.matrix;
var mva = cameraMatrix[0];
var mvb = cameraMatrix[1];
var mvc = cameraMatrix[2];
var mvd = cameraMatrix[3];
var mve = cameraMatrix[4];
var mvf = cameraMatrix[5];
var determinant = mva * mvd - mvb * mvc;
if (!determinant) {
output.x = x;
output.y = y;
return output;
}
determinant = 1 / determinant;
var ima = mvd * determinant;
var imb = -mvb * determinant;
var imc = -mvc * determinant;
var imd = mva * determinant;
var ime = (mvc * mvf - mvd * mve) * determinant;
var imf = (mvb * mve - mva * mvf) * determinant;
var c = Math.cos(this.rotation);
var s = Math.sin(this.rotation);
var zoomX = this.zoomX;
var zoomY = this.zoomY;
var scrollX = this.scrollX;
var scrollY = this.scrollY;
var sx = x + (scrollX * c - scrollY * s) * zoomX;
var sy = y + (scrollX * s + scrollY * c) * zoomY;
output.x = sx * ima + sy * imc + ime;
output.y = sx * imb + sy * imd + imf;
return output;
},
/**
* Given a Game Object, or an array of Game Objects, it will update all of their camera filter settings
* so that they are ignored by this Camera. This means they will not be rendered by this Camera.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#ignore
* @since 3.0.0
*
* @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Layer|Phaser.GameObjects.Layer[])} entries - The Game Object, or array of Game Objects, to be ignored by this Camera.
*
* @return {this} This Camera instance.
*/
ignore: function(entries) {
var id = this.id;
if (!Array.isArray(entries)) {
entries = [entries];
}
for (var i = 0; i < entries.length; i++) {
var entry = entries[i];
if (Array.isArray(entry)) {
this.ignore(entry);
} else if (entry.isParent) {
this.ignore(entry.getChildren());
} else {
entry.cameraFilter |= id;
}
}
return this;
},
/**
* Takes an x value and checks it's within the range of the Camera bounds, adjusting if required.
* Do not call this method if you are not using camera bounds.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#clampX
* @since 3.11.0
*
* @param {number} x - The value to horizontally scroll clamp.
*
* @return {number} The adjusted value to use as scrollX.
*/
clampX: function(x) {
var bounds = this._bounds;
var dw = this.displayWidth;
var bx = bounds.x + (dw - this.width) / 2;
var bw = Math.max(bx, bx + bounds.width - dw);
if (x < bx) {
x = bx;
} else if (x > bw) {
x = bw;
}
return x;
},
/**
* Takes a y value and checks it's within the range of the Camera bounds, adjusting if required.
* Do not call this method if you are not using camera bounds.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#clampY
* @since 3.11.0
*
* @param {number} y - The value to vertically scroll clamp.
*
* @return {number} The adjusted value to use as scrollY.
*/
clampY: function(y) {
var bounds = this._bounds;
var dh = this.displayHeight;
var by = bounds.y + (dh - this.height) / 2;
var bh = Math.max(by, by + bounds.height - dh);
if (y < by) {
y = by;
} else if (y > bh) {
y = bh;
}
return y;
},
/*
var gap = this._zoomInversed;
return gap * Math.round((src.x - this.scrollX * src.scrollFactorX) / gap);
*/
/**
* If this Camera has previously had movement bounds set on it, this will remove them.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#removeBounds
* @since 3.0.0
*
* @return {this} This Camera instance.
*/
removeBounds: function() {
this.useBounds = false;
this.dirty = true;
this._bounds.setEmpty();
return this;
},
/**
* Set the rotation of this Camera. This causes everything it renders to appear rotated.
*
* Rotating a camera does not rotate the viewport itself, it is applied during rendering.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#setAngle
* @since 3.0.0
*
* @param {number} [value=0] - The cameras angle of rotation, given in degrees.
*
* @return {this} This Camera instance.
*/
setAngle: function(value) {
if (value === void 0) {
value = 0;
}
this.rotation = DegToRad(value);
return this;
},
/**
* Sets the background color for this Camera.
*
* By default a Camera has a transparent background but it can be given a solid color, with any level
* of transparency, via this method.
*
* The color value can be specified using CSS color notation, hex or numbers.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#setBackgroundColor
* @since 3.0.0
*
* @param {(string|number|Phaser.Types.Display.InputColorObject)} [color='rgba(0,0,0,0)'] - The color value. In CSS, hex or numeric color notation.
*
* @return {this} This Camera instance.
*/
setBackgroundColor: function(color) {
if (color === void 0) {
color = "rgba(0,0,0,0)";
}
this.backgroundColor = ValueToColor(color);
this.transparent = this.backgroundColor.alpha === 0;
return this;
},
/**
* Set the bounds of the Camera. The bounds are an axis-aligned rectangle.
*
* The Camera bounds controls where the Camera can scroll to, stopping it from scrolling off the
* edges and into blank space. It does not limit the placement of Game Objects, or where
* the Camera viewport can be positioned.
*
* Temporarily disable the bounds by changing the boolean `Camera.useBounds`.
*
* Clear the bounds entirely by calling `Camera.removeBounds`.
*
* If you set bounds that are smaller than the viewport it will stop the Camera from being
* able to scroll. The bounds can be positioned where-ever you wish. By default they are from
* 0x0 to the canvas width x height. This means that the coordinate 0x0 is the top left of
* the Camera bounds. However, you can position them anywhere. So if you wanted a game world
* that was 2048x2048 in size, with 0x0 being the center of it, you can set the bounds x/y
* to be -1024, -1024, with a width and height of 2048. Depending on your game you may find
* it easier for 0x0 to be the top-left of the bounds, or you may wish 0x0 to be the middle.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#setBounds
* @since 3.0.0
*
* @param {number} x - The top-left x coordinate of the bounds.
* @param {number} y - The top-left y coordinate of the bounds.
* @param {number} width - The width of the bounds, in pixels.
* @param {number} height - The height of the bounds, in pixels.
* @param {boolean} [centerOn=false] - If `true` the Camera will automatically be centered on the new bounds.
*
* @return {this} This Camera instance.
*/
setBounds: function(x, y, width, height, centerOn) {
if (centerOn === void 0) {
centerOn = false;
}
this._bounds.setTo(x, y, width, height);
this.dirty = true;
this.useBounds = true;
if (centerOn) {
this.centerToBounds();
} else {
this.scrollX = this.clampX(this.scrollX);
this.scrollY = this.clampY(this.scrollY);
}
return this;
},
/**
* Returns a rectangle containing the bounds of the Camera.
*
* If the Camera does not have any bounds the rectangle will be empty.
*
* The rectangle is a copy of the bounds, so is safe to modify.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#getBounds
* @since 3.16.0
*
* @param {Phaser.Geom.Rectangle} [out] - An optional Rectangle to store the bounds in. If not given, a new Rectangle will be created.
*
* @return {Phaser.Geom.Rectangle} A rectangle containing the bounds of this Camera.
*/
getBounds: function(out) {
if (out === void 0) {
out = new Rectangle();
}
var source = this._bounds;
out.setTo(source.x, source.y, source.width, source.height);
return out;
},
/**
* Sets the name of this Camera.
* This value is for your own use and isn't used internally.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#setName
* @since 3.0.0
*
* @param {string} [value=''] - The name of the Camera.
*
* @return {this} This Camera instance.
*/
setName: function(value) {
if (value === void 0) {
value = "";
}
this.name = value;
return this;
},
/**
* Set the position of the Camera viewport within the game.
*
* This does not change where the camera is 'looking'. See `setScroll` to control that.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#setPosition
* @since 3.0.0
*
* @param {number} x - The top-left x coordinate of the Camera viewport.
* @param {number} [y=x] - The top-left y coordinate of the Camera viewport.
*
* @return {this} This Camera instance.
*/
setPosition: function(x, y) {
if (y === void 0) {
y = x;
}
this.x = x;
this.y = y;
return this;
},
/**
* Set the rotation of this Camera. This causes everything it renders to appear rotated.
*
* Rotating a camera does not rotate the viewport itself, it is applied during rendering.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#setRotation
* @since 3.0.0
*
* @param {number} [value=0] - The rotation of the Camera, in radians.
*
* @return {this} This Camera instance.
*/
setRotation: function(value) {
if (value === void 0) {
value = 0;
}
this.rotation = value;
return this;
},
/**
* Should the Camera round pixel values to whole integers when rendering Game Objects?
*
* In some types of game, especially with pixel art, this is required to prevent sub-pixel aliasing.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#setRoundPixels
* @since 3.0.0
*
* @param {boolean} value - `true` to round Camera pixels, `false` to not.
*
* @return {this} This Camera instance.
*/
setRoundPixels: function(value) {
this.roundPixels = value;
return this;
},
/**
* Sets the Scene the Camera is bound to.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#setScene
* @since 3.0.0
*
* @param {Phaser.Scene} scene - The Scene the camera is bound to.
* @param {boolean} [isSceneCamera=true] - Is this Camera being used for a Scene (true) or a Texture? (false)
*
* @return {this} This Camera instance.
*/
setScene: function(scene, isSceneCamera) {
if (isSceneCamera === void 0) {
isSceneCamera = true;
}
if (this.scene && this._customViewport) {
this.sceneManager.customViewports--;
}
this.scene = scene;
this.isSceneCamera = isSceneCamera;
var sys = scene.sys;
this.sceneManager = sys.game.scene;
this.scaleManager = sys.scale;
this.cameraManager = sys.cameras;
this.updateSystem();
return this;
},
/**
* Set the position of where the Camera is looking within the game.
* You can also modify the properties `Camera.scrollX` and `Camera.scrollY` directly.
* Use this method, or the scroll properties, to move your camera around the game world.
*
* This does not change where the camera viewport is placed. See `setPosition` to control that.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#setScroll
* @since 3.0.0
*
* @param {number} x - The x coordinate of the Camera in the game world.
* @param {number} [y=x] - The y coordinate of the Camera in the game world.
*
* @return {this} This Camera instance.
*/
setScroll: function(x, y) {
if (y === void 0) {
y = x;
}
this.scrollX = x;
this.scrollY = y;
return this;
},
/**
* Set the size of the Camera viewport.
*
* By default a Camera is the same size as the game, but can be made smaller via this method,
* allowing you to create mini-cam style effects by creating and positioning a smaller Camera
* viewport within your game.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#setSize
* @since 3.0.0
*
* @param {number} width - The width of the Camera viewport.
* @param {number} [height=width] - The height of the Camera viewport.
*
* @return {this} This Camera instance.
*/
setSize: function(width, height) {
if (height === void 0) {
height = width;
}
this.width = width;
this.height = height;
return this;
},
/**
* This method sets the position and size of the Camera viewport in a single call.
*
* If you're trying to change where the Camera is looking at in your game, then see
* the method `Camera.setScroll` instead. This method is for changing the viewport
* itself, not what the camera can see.
*
* By default a Camera is the same size as the game, but can be made smaller via this method,
* allowing you to create mini-cam style effects by creating and positioning a smaller Camera
* viewport within your game.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#setViewport
* @since 3.0.0
*
* @param {number} x - The top-left x coordinate of the Camera viewport.
* @param {number} y - The top-left y coordinate of the Camera viewport.
* @param {number} width - The width of the Camera viewport.
* @param {number} [height=width] - The height of the Camera viewport.
*
* @return {this} This Camera instance.
*/
setViewport: function(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
return this;
},
/**
* Set the zoom value of the Camera.
*
* Changing to a smaller value, such as 0.5, will cause the camera to 'zoom out'.
* Changing to a larger value, such as 2, will cause the camera to 'zoom in'.
*
* A value of 1 means 'no zoom' and is the default.
*
* Changing the zoom does not impact the Camera viewport in any way, it is only applied during rendering.
*
* As of Phaser 3.50 you can now set the horizontal and vertical zoom values independently.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#setZoom
* @since 3.0.0
*
* @param {number} [x=1] - The horizontal zoom value of the Camera. The minimum it can be is 0.001.
* @param {number} [y=x] - The vertical zoom value of the Camera. The minimum it can be is 0.001.
*
* @return {this} This Camera instance.
*/
setZoom: function(x, y) {
if (x === void 0) {
x = 1;
}
if (y === void 0) {
y = x;
}
if (x === 0) {
x = 1e-3;
}
if (y === 0) {
y = 1e-3;
}
this.zoomX = x;
this.zoomY = y;
return this;
},
/**
* Sets the mask to be applied to this Camera during rendering.
*
* The mask must have been previously created and can be either a GeometryMask or a BitmapMask.
*
* Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas.
*
* If a mask is already set on this Camera it will be immediately replaced.
*
* Masks have no impact on physics or input detection. They are purely a rendering component
* that allows you to limit what is visible during the render pass.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#setMask
* @since 3.17.0
*
* @param {(Phaser.Display.Masks.BitmapMask|Phaser.Display.Masks.GeometryMask)} mask - The mask this Camera will use when rendering.
* @param {boolean} [fixedPosition=true] - Should the mask translate along with the Camera, or be fixed in place and not impacted by the Cameras transform?
*
* @return {this} This Camera instance.
*/
setMask: function(mask, fixedPosition) {
if (fixedPosition === void 0) {
fixedPosition = true;
}
this.mask = mask;
this._maskCamera = fixedPosition ? this.cameraManager.default : this;
return this;
},
/**
* Clears the mask that this Camera was using.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#clearMask
* @since 3.17.0
*
* @param {boolean} [destroyMask=false] - Destroy the mask before clearing it?
*
* @return {this} This Camera instance.
*/
clearMask: function(destroyMask) {
if (destroyMask === void 0) {
destroyMask = false;
}
if (destroyMask && this.mask) {
this.mask.destroy();
}
this.mask = null;
return this;
},
/**
* Sets the visibility of this Camera.
*
* An invisible Camera will skip rendering and input tests of everything it can see.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#setVisible
* @since 3.10.0
*
* @param {boolean} value - The visible state of the Camera.
*
* @return {this} This Camera instance.
*/
/**
* Returns an Object suitable for JSON storage containing all of the Camera viewport and rendering properties.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#toJSON
* @since 3.0.0
*
* @return {Phaser.Types.Cameras.Scene2D.JSONCamera} A well-formed object suitable for conversion to JSON.
*/
toJSON: function() {
var output = {
name: this.name,
x: this.x,
y: this.y,
width: this.width,
height: this.height,
zoom: this.zoom,
rotation: this.rotation,
roundPixels: this.roundPixels,
scrollX: this.scrollX,
scrollY: this.scrollY,
backgroundColor: this.backgroundColor.rgba
};
if (this.useBounds) {
output["bounds"] = {
x: this._bounds.x,
y: this._bounds.y,
width: this._bounds.width,
height: this._bounds.height
};
}
return output;
},
/**
* Internal method called automatically by the Camera Manager.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#update
* @protected
* @since 3.0.0
*
* @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout.
* @param {number} delta - The delta time, in ms, elapsed since the last frame.
*/
update: function() {
},
/**
* Set if this Camera is being used as a Scene Camera, or a Texture
* Camera.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#setIsSceneCamera
* @since 3.60.0
*
* @param {boolean} value - Is this being used as a Scene Camera, or a Texture camera?
*/
setIsSceneCamera: function(value) {
this.isSceneCamera = value;
return this;
},
/**
* Internal method called automatically when the viewport changes.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#updateSystem
* @private
* @since 3.12.0
*/
updateSystem: function() {
if (!this.scaleManager || !this.isSceneCamera) {
return;
}
var custom = this._x !== 0 || this._y !== 0 || this.scaleManager.width !== this._width || this.scaleManager.height !== this._height;
var sceneManager = this.sceneManager;
if (custom && !this._customViewport) {
sceneManager.customViewports++;
} else if (!custom && this._customViewport) {
sceneManager.customViewports--;
}
this.dirty = true;
this._customViewport = custom;
},
/**
* Destroys this Camera instance and its internal properties and references.
* Once destroyed you cannot use this Camera again, even if re-added to a Camera Manager.
*
* This method is called automatically by `CameraManager.remove` if that methods `runDestroy` argument is `true`, which is the default.
*
* Unless you have a specific reason otherwise, always use `CameraManager.remove` and allow it to handle the camera destruction,
* rather than calling this method directly.
*
* @method Phaser.Cameras.Scene2D.BaseCamera#destroy
* @fires Phaser.Cameras.Scene2D.Events#DESTROY
* @since 3.0.0
*/
destroy: function() {
this.emit(Events.DESTROY, this);
this.removeAllListeners();
this.matrix.destroy();
this.culledObjects = [];
if (this._customViewport) {
this.sceneManager.customViewports--;
}
this.renderList = [];
this._bounds = null;
this.scene = null;
this.scaleManager = null;
this.sceneManager = null;
this.cameraManager = null;
},
/**
* The x position of the Camera viewport, relative to the top-left of the game canvas.
* The viewport is the area into which the camera renders.
* To adjust the position the camera is looking at in the game world, see the `scrollX` value.
*
* @name Phaser.Cameras.Scene2D.BaseCamera#x
* @type {number}
* @since 3.0.0
*/
x: {
get: function() {
return this._x;
},
set: function(value) {
this._x = value;
this.updateSystem();
}
},
/**
* The y position of the Camera viewport, relative to the top-left of the game canvas.
* The viewport is the area into which the camera renders.
* To adjust the position the camera is looking at in the game world, see the `scrollY` value.
*
* @name Phaser.Cameras.Scene2D.BaseCamera#y
* @type {number}
* @since 3.0.0
*/
y: {
get: function() {
return this._y;
},
set: function(value) {
this._y = value;
this.updateSystem();
}
},
/**
* The width of the Camera viewport, in pixels.
*
* The viewport is the area into which the Camera renders. Setting the viewport does
* not restrict where the Camera can scroll to.
*
* @name Phaser.Cameras.Scene2D.BaseCamera#width
* @type {number}
* @since 3.0.0
*/
width: {
get: function() {
return this._width;
},
set: function(value) {
this._width = value;
this.updateSystem();
}
},
/**
* The height of the Camera viewport, in pixels.
*
* The viewport is the area into which the Camera renders. Setting the viewport does
* not restrict where the Camera can scroll to.
*
* @name Phaser.Cameras.Scene2D.BaseCamera#height
* @type {number}
* @since 3.0.0
*/
height: {
get: function() {
return this._height;
},
set: function(value) {
this._height = value;
this.updateSystem();
}
},
/**
* The horizontal scroll position of this Camera.
*
* Change this value to cause the Camera to scroll around your Scene.
*
* Alternatively, setting the Camera to follow a Game Object, via the `startFollow` method,
* will automatically adjust the Camera scroll values accordingly.
*
* You can set the bounds within which the Camera can scroll via the `setBounds` method.
*
* @name Phaser.Cameras.Scene2D.BaseCamera#scrollX
* @type {number}
* @default 0
* @since 3.0.0
*/
scrollX: {
get: function() {
return this._scrollX;
},
set: function(value) {
if (value !== this._scrollX) {
this._scrollX = value;
this.dirty = true;
}
}
},
/**
* The vertical scroll position of this Camera.
*
* Change this value to cause the Camera to scroll around your Scene.
*
* Alternatively, setting the Camera to follow a Game Object, via the `startFollow` method,
* will automatically adjust the Camera scroll values accordingly.
*
* You can set the bounds within which the Camera can scroll via the `setBounds` method.
*
* @name Phaser.Cameras.Scene2D.BaseCamera#scrollY
* @type {number}
* @default 0
* @since 3.0.0
*/
scrollY: {
get: function() {
return this._scrollY;
},
set: function(value) {
if (value !== this._scrollY) {
this._scrollY = value;
this.dirty = true;
}
}
},
/**
* The Camera zoom value. Change this value to zoom in, or out of, a Scene.
*
* A value of 0.5 would zoom the Camera out, so you can now see twice as much
* of the Scene as before. A value of 2 would zoom the Camera in, so every pixel
* now takes up 2 pixels when rendered.
*
* Set to 1 to return to the default zoom level.
*
* Be careful to never set this value to zero.
*
* @name Phaser.Cameras.Scene2D.BaseCamera#zoom
* @type {number}
* @default 1
* @since 3.0.0
*/
zoom: {
get: function() {
return (this._zoomX + this._zoomY) / 2;
},
set: function(value) {
this._zoomX = value;
this._zoomY = value;
this.dirty = true;
}
},
/**
* The Camera horizontal zoom value. Change this value to zoom in, or out of, a Scene.
*
* A value of 0.5 would zoom the Camera out, so you can now see twice as much
* of the Scene as before. A value of 2 would zoom the Camera in, so every pixel
* now takes up 2 pixels when rendered.
*
* Set to 1 to return to the default zoom level.
*
* Be careful to never set this value to zero.
*
* @name Phaser.Cameras.Scene2D.BaseCamera#zoomX
* @type {number}
* @default 1
* @since 3.50.0
*/
zoomX: {
get: function() {
return this._zoomX;
},
set: function(value) {
this._zoomX = value;
this.dirty = true;
}
},
/**
* The Camera vertical zoom value. Change this value to zoom in, or out of, a Scene.
*
* A value of 0.5 would zoom the Camera out, so you can now see twice as much
* of the Scene as before. A value of 2 would zoom the Camera in, so every pixel
* now takes up 2 pixels when rendered.
*
* Set to 1 to return to the default zoom level.
*
* Be careful to never set this value to zero.
*
* @name Phaser.Cameras.Scene2D.BaseCamera#zoomY
* @type {number}
* @default 1
* @since 3.50.0
*/
zoomY: {
get: function() {
return this._zoomY;
},
set: function(value) {
this._zoomY = value;
this.dirty = true;
}
},
/**
* The rotation of the Camera in radians.
*
* Camera rotation always takes place based on the Camera viewport. By default, rotation happens
* in the center of the viewport. You can adjust this with the `originX` and `originY` properties.
*
* Rotation influences the rendering of _all_ Game Objects visible by this Camera. However, it does not
* rotate the Camera viewport itself, which always remains an axis-aligned rectangle.
*
* @name Phaser.Cameras.Scene2D.BaseCamera#rotation
* @type {number}
* @private
* @default 0
* @since 3.11.0
*/
rotation: {
get: function() {
return this._rotation;
},
set: function(value) {
this._rotation = value;
this.dirty = true;
}
},
/**
* The horizontal position of the center of the Camera's viewport, relative to the left of the game canvas.
*
* @name Phaser.Cameras.Scene2D.BaseCamera#centerX
* @type {number}
* @readonly
* @since 3.10.0
*/
centerX: {
get: function() {
return this.x + 0.5 * this.width;
}
},
/**
* The vertical position of the center of the Camera's viewport, relative to the top of the game canvas.
*
* @name Phaser.Cameras.Scene2D.BaseCamera#centerY
* @type {number}
* @readonly
* @since 3.10.0
*/
centerY: {
get: function() {
return this.y + 0.5 * this.height;
}
},
/**
* The displayed width of the camera viewport, factoring in the camera zoom level.
*
* If a camera has a viewport width of 800 and a zoom of 0.5 then its display width
* would be 1600, as it's displaying twice as many pixels as zoom level 1.
*
* Equally, a camera with a width of 800 and zoom of 2 would have a display width
* of 400 pixels.
*
* @name Phaser.Cameras.Scene2D.BaseCamera#displayWidth
* @type {number}
* @readonly
* @since 3.11.0
*/
displayWidth: {
get: function() {
return this.width / this.zoomX;
}
},
/**
* The displayed height of the camera viewport, factoring in the camera zoom level.
*
* If a camera has a viewport height of 600 and a zoom of 0.5 then its display height
* would be 1200, as it's displaying twice as many pixels as zoom level 1.
*
* Equally, a camera with a height of 600 and zoom of 2 would have a display height
* of 300 pixels.
*
* @name Phaser.Cameras.Scene2D.BaseCamera#displayHeight
* @type {number}
* @readonly
* @since 3.11.0
*/
displayHeight: {
get: function() {
return this.height / this.zoomY;
}
}
});
module2.exports = BaseCamera;
}
),
/***/
38058: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BaseCamera = __webpack_require__2(71911);
var CenterOn = __webpack_require__2(67502);
var Clamp = __webpack_require__2(45319);
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31401);
var Effects = __webpack_require__2(20052);
var Events = __webpack_require__2(19715);
var Linear = __webpack_require__2(28915);
var Rectangle = __webpack_require__2(87841);
var Vector2 = __webpack_require__2(26099);
var Camera = new Class({
Extends: BaseCamera,
Mixins: [
Components.PostPipeline
],
initialize: function Camera2(x, y, width, height) {
BaseCamera.call(this, x, y, width, height);
this.initPostPipeline();
this.inputEnabled = true;
this.fadeEffect = new Effects.Fade(this);
this.flashEffect = new Effects.Flash(this);
this.shakeEffect = new Effects.Shake(this);
this.panEffect = new Effects.Pan(this);
this.rotateToEffect = new Effects.RotateTo(this);
this.zoomEffect = new Effects.Zoom(this);
this.lerp = new Vector2(1, 1);
this.followOffset = new Vector2();
this.deadzone = null;
this._follow = null;
},
/**
* Sets the Camera dead zone.
*
* The deadzone is only used when the camera is following a target.
*
* It defines a rectangular region within which if the target is present, the camera will not scroll.
* If the target moves outside of this area, the camera will begin scrolling in order to follow it.
*
* The deadzone rectangle is re-positioned every frame so that it is centered on the mid-point
* of the camera. This allows you to use the object for additional game related checks, such as
* testing if an object is within it or not via a Rectangle.contains call.
*
* The `lerp` values that you can set for a follower target also apply when using a deadzone.
*
* Calling this method with no arguments will reset an active deadzone.
*
* @method Phaser.Cameras.Scene2D.Camera#setDeadzone
* @since 3.11.0
*
* @param {number} [width] - The width of the deadzone rectangle in pixels. If not specified the deadzone is removed.
* @param {number} [height] - The height of the deadzone rectangle in pixels.
*
* @return {this} This Camera instance.
*/
setDeadzone: function(width, height) {
if (width === void 0) {
this.deadzone = null;
} else {
if (this.deadzone) {
this.deadzone.width = width;
this.deadzone.height = height;
} else {
this.deadzone = new Rectangle(0, 0, width, height);
}
if (this._follow) {
var originX = this.width / 2;
var originY = this.height / 2;
var fx = this._follow.x - this.followOffset.x;
var fy = this._follow.y - this.followOffset.y;
this.midPoint.set(fx, fy);
this.scrollX = fx - originX;
this.scrollY = fy - originY;
}
CenterOn(this.deadzone, this.midPoint.x, this.midPoint.y);
}
return this;
},
/**
* Fades the Camera in from the given color over the duration specified.
*
* @method Phaser.Cameras.Scene2D.Camera#fadeIn
* @fires Phaser.Cameras.Scene2D.Events#FADE_IN_START
* @fires Phaser.Cameras.Scene2D.Events#FADE_IN_COMPLETE
* @since 3.3.0
*
* @param {number} [duration=1000] - The duration of the effect in milliseconds.
* @param {number} [red=0] - The amount to fade the red channel towards. A value between 0 and 255.
* @param {number} [green=0] - The amount to fade the green channel towards. A value between 0 and 255.
* @param {number} [blue=0] - The amount to fade the blue channel towards. A value between 0 and 255.
* @param {function} [callback] - This callback will be invoked every frame for the duration of the effect.
* It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is.
* @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
*
* @return {this} This Camera instance.
*/
fadeIn: function(duration, red, green, blue, callback, context) {
return this.fadeEffect.start(false, duration, red, green, blue, true, callback, context);
},
/**
* Fades the Camera out to the given color over the duration specified.
* This is an alias for Camera.fade that forces the fade to start, regardless of existing fades.
*
* @method Phaser.Cameras.Scene2D.Camera#fadeOut
* @fires Phaser.Cameras.Scene2D.Events#FADE_OUT_START
* @fires Phaser.Cameras.Scene2D.Events#FADE_OUT_COMPLETE
* @since 3.3.0
*
* @param {number} [duration=1000] - The duration of the effect in milliseconds.
* @param {number} [red=0] - The amount to fade the red channel towards. A value between 0 and 255.
* @param {number} [green=0] - The amount to fade the green channel towards. A value between 0 and 255.
* @param {number} [blue=0] - The amount to fade the blue channel towards. A value between 0 and 255.
* @param {function} [callback] - This callback will be invoked every frame for the duration of the effect.
* It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is.
* @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
*
* @return {this} This Camera instance.
*/
fadeOut: function(duration, red, green, blue, callback, context) {
return this.fadeEffect.start(true, duration, red, green, blue, true, callback, context);
},
/**
* Fades the Camera from the given color to transparent over the duration specified.
*
* @method Phaser.Cameras.Scene2D.Camera#fadeFrom
* @fires Phaser.Cameras.Scene2D.Events#FADE_IN_START
* @fires Phaser.Cameras.Scene2D.Events#FADE_IN_COMPLETE
* @since 3.5.0
*
* @param {number} [duration=1000] - The duration of the effect in milliseconds.
* @param {number} [red=0] - The amount to fade the red channel towards. A value between 0 and 255.
* @param {number} [green=0] - The amount to fade the green channel towards. A value between 0 and 255.
* @param {number} [blue=0] - The amount to fade the blue channel towards. A value between 0 and 255.
* @param {boolean} [force=false] - Force the effect to start immediately, even if already running.
* @param {function} [callback] - This callback will be invoked every frame for the duration of the effect.
* It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is.
* @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
*
* @return {this} This Camera instance.
*/
fadeFrom: function(duration, red, green, blue, force, callback, context) {
return this.fadeEffect.start(false, duration, red, green, blue, force, callback, context);
},
/**
* Fades the Camera from transparent to the given color over the duration specified.
*
* @method Phaser.Cameras.Scene2D.Camera#fade
* @fires Phaser.Cameras.Scene2D.Events#FADE_OUT_START
* @fires Phaser.Cameras.Scene2D.Events#FADE_OUT_COMPLETE
* @since 3.0.0
*
* @param {number} [duration=1000] - The duration of the effect in milliseconds.
* @param {number} [red=0] - The amount to fade the red channel towards. A value between 0 and 255.
* @param {number} [green=0] - The amount to fade the green channel towards. A value between 0 and 255.
* @param {number} [blue=0] - The amount to fade the blue channel towards. A value between 0 and 255.
* @param {boolean} [force=false] - Force the effect to start immediately, even if already running.
* @param {function} [callback] - This callback will be invoked every frame for the duration of the effect.
* It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is.
* @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
*
* @return {this} This Camera instance.
*/
fade: function(duration, red, green, blue, force, callback, context) {
return this.fadeEffect.start(true, duration, red, green, blue, force, callback, context);
},
/**
* Flashes the Camera by setting it to the given color immediately and then fading it away again quickly over the duration specified.
*
* @method Phaser.Cameras.Scene2D.Camera#flash
* @fires Phaser.Cameras.Scene2D.Events#FLASH_START
* @fires Phaser.Cameras.Scene2D.Events#FLASH_COMPLETE
* @since 3.0.0
*
* @param {number} [duration=250] - The duration of the effect in milliseconds.
* @param {number} [red=255] - The amount to fade the red channel towards. A value between 0 and 255.
* @param {number} [green=255] - The amount to fade the green channel towards. A value between 0 and 255.
* @param {number} [blue=255] - The amount to fade the blue channel towards. A value between 0 and 255.
* @param {boolean} [force=false] - Force the effect to start immediately, even if already running.
* @param {function} [callback] - This callback will be invoked every frame for the duration of the effect.
* It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is.
* @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
*
* @return {this} This Camera instance.
*/
flash: function(duration, red, green, blue, force, callback, context) {
return this.flashEffect.start(duration, red, green, blue, force, callback, context);
},
/**
* Shakes the Camera by the given intensity over the duration specified.
*
* @method Phaser.Cameras.Scene2D.Camera#shake
* @fires Phaser.Cameras.Scene2D.Events#SHAKE_START
* @fires Phaser.Cameras.Scene2D.Events#SHAKE_COMPLETE
* @since 3.0.0
*
* @param {number} [duration=100] - The duration of the effect in milliseconds.
* @param {(number|Phaser.Math.Vector2)} [intensity=0.05] - The intensity of the shake.
* @param {boolean} [force=false] - Force the shake effect to start immediately, even if already running.
* @param {function} [callback] - This callback will be invoked every frame for the duration of the effect.
* It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is.
* @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
*
* @return {this} This Camera instance.
*/
shake: function(duration, intensity, force, callback, context) {
return this.shakeEffect.start(duration, intensity, force, callback, context);
},
/**
* This effect will scroll the Camera so that the center of its viewport finishes at the given destination,
* over the duration and with the ease specified.
*
* @method Phaser.Cameras.Scene2D.Camera#pan
* @fires Phaser.Cameras.Scene2D.Events#PAN_START
* @fires Phaser.Cameras.Scene2D.Events#PAN_COMPLETE
* @since 3.11.0
*
* @param {number} x - The destination x coordinate to scroll the center of the Camera viewport to.
* @param {number} y - The destination y coordinate to scroll the center of the Camera viewport to.
* @param {number} [duration=1000] - The duration of the effect in milliseconds.
* @param {(string|function)} [ease='Linear'] - The ease to use for the pan. Can be any of the Phaser Easing constants or a custom function.
* @param {boolean} [force=false] - Force the pan effect to start immediately, even if already running.
* @param {Phaser.Types.Cameras.Scene2D.CameraPanCallback} [callback] - This callback will be invoked every frame for the duration of the effect.
* It is sent four arguments: A reference to the camera, a progress amount between 0 and 1 indicating how complete the effect is,
* the current camera scroll x coordinate and the current camera scroll y coordinate.
* @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
*
* @return {this} This Camera instance.
*/
pan: function(x, y, duration, ease, force, callback, context) {
return this.panEffect.start(x, y, duration, ease, force, callback, context);
},
/**
* This effect will rotate the Camera so that the viewport finishes at the given angle in radians,
* over the duration and with the ease specified.
*
* @method Phaser.Cameras.Scene2D.Camera#rotateTo
* @since 3.23.0
*
* @param {number} radians - The destination angle in radians to rotate the Camera viewport to. If the angle is positive then the rotation is clockwise else anticlockwise
* @param {boolean} [shortestPath=false] - If shortest path is set to true the camera will rotate in the quickest direction clockwise or anti-clockwise.
* @param {number} [duration=1000] - The duration of the effect in milliseconds.
* @param {(string|function)} [ease='Linear'] - The ease to use for the rotation. Can be any of the Phaser Easing constants or a custom function.
* @param {boolean} [force=false] - Force the rotation effect to start immediately, even if already running.
* @param {CameraRotateCallback} [callback] - This callback will be invoked every frame for the duration of the effect.
* It is sent four arguments: A reference to the camera, a progress amount between 0 and 1 indicating how complete the effect is,
* the current camera rotation angle in radians.
* @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
*
* @return {Phaser.Cameras.Scene2D.Camera} This Camera instance.
*/
rotateTo: function(radians, shortestPath, duration, ease, force, callback, context) {
return this.rotateToEffect.start(radians, shortestPath, duration, ease, force, callback, context);
},
/**
* This effect will zoom the Camera to the given scale, over the duration and with the ease specified.
*
* @method Phaser.Cameras.Scene2D.Camera#zoomTo
* @fires Phaser.Cameras.Scene2D.Events#ZOOM_START
* @fires Phaser.Cameras.Scene2D.Events#ZOOM_COMPLETE
* @since 3.11.0
*
* @param {number} zoom - The target Camera zoom value.
* @param {number} [duration=1000] - The duration of the effect in milliseconds.
* @param {(string|function)} [ease='Linear'] - The ease to use for the pan. Can be any of the Phaser Easing constants or a custom function.
* @param {boolean} [force=false] - Force the pan effect to start immediately, even if already running.
* @param {Phaser.Types.Cameras.Scene2D.CameraPanCallback} [callback] - This callback will be invoked every frame for the duration of the effect.
* It is sent four arguments: A reference to the camera, a progress amount between 0 and 1 indicating how complete the effect is,
* the current camera scroll x coordinate and the current camera scroll y coordinate.
* @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
*
* @return {this} This Camera instance.
*/
zoomTo: function(zoom, duration, ease, force, callback, context) {
return this.zoomEffect.start(zoom, duration, ease, force, callback, context);
},
/**
* Internal preRender step.
*
* @method Phaser.Cameras.Scene2D.Camera#preRender
* @protected
* @since 3.0.0
*/
preRender: function() {
this.renderList.length = 0;
var width = this.width;
var height = this.height;
var halfWidth = width * 0.5;
var halfHeight = height * 0.5;
var zoomX = this.zoomX;
var zoomY = this.zoomY;
var matrix = this.matrix;
this.renderRoundPixels = this.roundPixels && Number.isInteger(zoomX) && Number.isInteger(zoomY);
var originX = width * this.originX;
var originY = height * this.originY;
var follow = this._follow;
var deadzone = this.deadzone;
var sx = this.scrollX;
var sy = this.scrollY;
if (deadzone) {
CenterOn(deadzone, this.midPoint.x, this.midPoint.y);
}
var emitFollowEvent = false;
if (follow && !this.panEffect.isRunning) {
var lerp = this.lerp;
var fx = follow.x - this.followOffset.x;
var fy = follow.y - this.followOffset.y;
if (deadzone) {
if (fx < deadzone.x) {
sx = Linear(sx, sx - (deadzone.x - fx), lerp.x);
} else if (fx > deadzone.right) {
sx = Linear(sx, sx + (fx - deadzone.right), lerp.x);
}
if (fy < deadzone.y) {
sy = Linear(sy, sy - (deadzone.y - fy), lerp.y);
} else if (fy > deadzone.bottom) {
sy = Linear(sy, sy + (fy - deadzone.bottom), lerp.y);
}
} else {
sx = Linear(sx, fx - originX, lerp.x);
sy = Linear(sy, fy - originY, lerp.y);
}
emitFollowEvent = true;
}
if (this.roundPixels) {
sx = Math.floor(sx);
sy = Math.floor(sy);
}
if (this.useBounds) {
sx = this.clampX(sx);
sy = this.clampY(sy);
}
this.scrollX = sx;
this.scrollY = sy;
var midX = sx + halfWidth;
var midY = sy + halfHeight;
this.midPoint.set(midX, midY);
var displayWidth = Math.floor(width / zoomX + 0.5);
var displayHeight = Math.floor(height / zoomY + 0.5);
var vwx = Math.floor(midX - displayWidth / 2 + 0.5);
var vwy = Math.floor(midY - displayHeight / 2 + 0.5);
this.worldView.setTo(vwx, vwy, displayWidth, displayHeight);
matrix.applyITRS(
Math.floor(this.x + originX + 0.5),
Math.floor(this.y + originY + 0.5),
this.rotation,
zoomX,
zoomY
);
matrix.translate(-originX, -originY);
this.shakeEffect.preRender();
if (emitFollowEvent) {
this.emit(Events.FOLLOW_UPDATE, this, follow);
}
},
/**
* Sets the linear interpolation value to use when following a target.
*
* The default values of 1 means the camera will instantly snap to the target coordinates.
* A lower value, such as 0.1 means the camera will more slowly track the target, giving
* a smooth transition. You can set the horizontal and vertical values independently, and also
* adjust this value in real-time during your game.
*
* Be sure to keep the value between 0 and 1. A value of zero will disable tracking on that axis.
*
* @method Phaser.Cameras.Scene2D.Camera#setLerp
* @since 3.9.0
*
* @param {number} [x=1] - The amount added to the horizontal linear interpolation of the follow target.
* @param {number} [y=1] - The amount added to the vertical linear interpolation of the follow target.
*
* @return {this} This Camera instance.
*/
setLerp: function(x, y) {
if (x === void 0) {
x = 1;
}
if (y === void 0) {
y = x;
}
this.lerp.set(x, y);
return this;
},
/**
* Sets the horizontal and vertical offset of the camera from its follow target.
* The values are subtracted from the targets position during the Cameras update step.
*
* @method Phaser.Cameras.Scene2D.Camera#setFollowOffset
* @since 3.9.0
*
* @param {number} [x=0] - The horizontal offset from the camera follow target.x position.
* @param {number} [y=0] - The vertical offset from the camera follow target.y position.
*
* @return {this} This Camera instance.
*/
setFollowOffset: function(x, y) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
this.followOffset.set(x, y);
return this;
},
/**
* Sets the Camera to follow a Game Object.
*
* When enabled the Camera will automatically adjust its scroll position to keep the target Game Object
* in its center.
*
* You can set the linear interpolation value used in the follow code.
* Use low lerp values (such as 0.1) to automatically smooth the camera motion.
*
* If you find you're getting a slight "jitter" effect when following an object it's probably to do with sub-pixel
* rendering of the targets position. This can be rounded by setting the `roundPixels` argument to `true` to
* force full pixel rounding rendering. Note that this can still be broken if you have specified a non-integer zoom
* value on the camera. So be sure to keep the camera zoom to integers.
*
* @method Phaser.Cameras.Scene2D.Camera#startFollow
* @since 3.0.0
*
* @param {(Phaser.GameObjects.GameObject|object)} target - The target for the Camera to follow.
* @param {boolean} [roundPixels=false] - Round the camera position to whole integers to avoid sub-pixel rendering?
* @param {number} [lerpX=1] - A value between 0 and 1. This value specifies the amount of linear interpolation to use when horizontally tracking the target. The closer the value to 1, the faster the camera will track.
* @param {number} [lerpY=1] - A value between 0 and 1. This value specifies the amount of linear interpolation to use when vertically tracking the target. The closer the value to 1, the faster the camera will track.
* @param {number} [offsetX=0] - The horizontal offset from the camera follow target.x position.
* @param {number} [offsetY=0] - The vertical offset from the camera follow target.y position.
*
* @return {this} This Camera instance.
*/
startFollow: function(target, roundPixels, lerpX, lerpY, offsetX, offsetY) {
if (roundPixels === void 0) {
roundPixels = false;
}
if (lerpX === void 0) {
lerpX = 1;
}
if (lerpY === void 0) {
lerpY = lerpX;
}
if (offsetX === void 0) {
offsetX = 0;
}
if (offsetY === void 0) {
offsetY = offsetX;
}
this._follow = target;
this.roundPixels = roundPixels;
lerpX = Clamp(lerpX, 0, 1);
lerpY = Clamp(lerpY, 0, 1);
this.lerp.set(lerpX, lerpY);
this.followOffset.set(offsetX, offsetY);
var originX = this.width / 2;
var originY = this.height / 2;
var fx = target.x - offsetX;
var fy = target.y - offsetY;
this.midPoint.set(fx, fy);
this.scrollX = fx - originX;
this.scrollY = fy - originY;
if (this.useBounds) {
this.scrollX = this.clampX(this.scrollX);
this.scrollY = this.clampY(this.scrollY);
}
return this;
},
/**
* Stops a Camera from following a Game Object, if previously set via `Camera.startFollow`.
*
* @method Phaser.Cameras.Scene2D.Camera#stopFollow
* @since 3.0.0
*
* @return {this} This Camera instance.
*/
stopFollow: function() {
this._follow = null;
return this;
},
/**
* Resets any active FX, such as a fade, flash or shake. Useful to call after a fade in order to
* remove the fade.
*
* @method Phaser.Cameras.Scene2D.Camera#resetFX
* @since 3.0.0
*
* @return {this} This Camera instance.
*/
resetFX: function() {
this.rotateToEffect.reset();
this.panEffect.reset();
this.shakeEffect.reset();
this.flashEffect.reset();
this.fadeEffect.reset();
return this;
},
/**
* Internal method called automatically by the Camera Manager.
*
* @method Phaser.Cameras.Scene2D.Camera#update
* @protected
* @since 3.0.0
*
* @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout.
* @param {number} delta - The delta time, in ms, elapsed since the last frame.
*/
update: function(time, delta) {
if (this.visible) {
this.rotateToEffect.update(time, delta);
this.panEffect.update(time, delta);
this.zoomEffect.update(time, delta);
this.shakeEffect.update(time, delta);
this.flashEffect.update(time, delta);
this.fadeEffect.update(time, delta);
}
},
/**
* Destroys this Camera instance. You rarely need to call this directly.
*
* Called by the Camera Manager. If you wish to destroy a Camera please use `CameraManager.remove` as
* cameras are stored in a pool, ready for recycling later, and calling this directly will prevent that.
*
* @method Phaser.Cameras.Scene2D.Camera#destroy
* @fires Phaser.Cameras.Scene2D.Events#DESTROY
* @since 3.0.0
*/
destroy: function() {
this.resetFX();
BaseCamera.prototype.destroy.call(this);
this._follow = null;
this.deadzone = null;
}
});
module2.exports = Camera;
}
),
/***/
32743: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Camera = __webpack_require__2(38058);
var Class = __webpack_require__2(83419);
var GetFastValue = __webpack_require__2(95540);
var PluginCache = __webpack_require__2(37277);
var RectangleContains = __webpack_require__2(37303);
var ScaleEvents = __webpack_require__2(97480);
var SceneEvents = __webpack_require__2(44594);
var CameraManager = new Class({
initialize: function CameraManager2(scene) {
this.scene = scene;
this.systems = scene.sys;
this.roundPixels = scene.sys.game.config.roundPixels;
this.cameras = [];
this.main;
this.default;
scene.sys.events.once(SceneEvents.BOOT, this.boot, this);
scene.sys.events.on(SceneEvents.START, this.start, this);
},
/**
* This method is called automatically, only once, when the Scene is first created.
* Do not invoke it directly.
*
* @method Phaser.Cameras.Scene2D.CameraManager#boot
* @private
* @listens Phaser.Scenes.Events#DESTROY
* @since 3.5.1
*/
boot: function() {
var sys = this.systems;
if (sys.settings.cameras) {
this.fromJSON(sys.settings.cameras);
} else {
this.add();
}
this.main = this.cameras[0];
this.default = new Camera(0, 0, sys.scale.width, sys.scale.height).setScene(this.scene);
sys.game.scale.on(ScaleEvents.RESIZE, this.onResize, this);
this.systems.events.once(SceneEvents.DESTROY, this.destroy, this);
},
/**
* This method is called automatically by the Scene when it is starting up.
* It is responsible for creating local systems, properties and listening for Scene events.
* Do not invoke it directly.
*
* @method Phaser.Cameras.Scene2D.CameraManager#start
* @private
* @listens Phaser.Scenes.Events#UPDATE
* @listens Phaser.Scenes.Events#SHUTDOWN
* @since 3.5.0
*/
start: function() {
if (!this.main) {
var sys = this.systems;
if (sys.settings.cameras) {
this.fromJSON(sys.settings.cameras);
} else {
this.add();
}
this.main = this.cameras[0];
}
var eventEmitter = this.systems.events;
eventEmitter.on(SceneEvents.UPDATE, this.update, this);
eventEmitter.once(SceneEvents.SHUTDOWN, this.shutdown, this);
},
/**
* Adds a new Camera into the Camera Manager. The Camera Manager can support up to 31 different Cameras.
*
* Each Camera has its own viewport, which controls the size of the Camera and its position within the canvas.
*
* Use the `Camera.scrollX` and `Camera.scrollY` properties to change where the Camera is looking, or the
* Camera methods such as `centerOn`. Cameras also have built in special effects, such as fade, flash, shake,
* pan and zoom.
*
* By default Cameras are transparent and will render anything that they can see based on their `scrollX`
* and `scrollY` values. Game Objects can be set to be ignored by a Camera by using the `Camera.ignore` method.
*
* The Camera will have its `roundPixels` property set to whatever `CameraManager.roundPixels` is. You can change
* it after creation if required.
*
* See the Camera class documentation for more details.
*
* @method Phaser.Cameras.Scene2D.CameraManager#add
* @since 3.0.0
*
* @param {number} [x=0] - The horizontal position of the Camera viewport.
* @param {number} [y=0] - The vertical position of the Camera viewport.
* @param {number} [width] - The width of the Camera viewport. If not given it'll be the game config size.
* @param {number} [height] - The height of the Camera viewport. If not given it'll be the game config size.
* @param {boolean} [makeMain=false] - Set this Camera as being the 'main' camera. This just makes the property `main` a reference to it.
* @param {string} [name=''] - The name of the Camera.
*
* @return {Phaser.Cameras.Scene2D.Camera} The newly created Camera.
*/
add: function(x, y, width, height, makeMain, name) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (width === void 0) {
width = this.scene.sys.scale.width;
}
if (height === void 0) {
height = this.scene.sys.scale.height;
}
if (makeMain === void 0) {
makeMain = false;
}
if (name === void 0) {
name = "";
}
var camera = new Camera(x, y, width, height);
camera.setName(name);
camera.setScene(this.scene);
camera.setRoundPixels(this.roundPixels);
camera.id = this.getNextID();
this.cameras.push(camera);
if (makeMain) {
this.main = camera;
}
return camera;
},
/**
* Adds an existing Camera into the Camera Manager.
*
* The Camera should either be a `Phaser.Cameras.Scene2D.Camera` instance, or a class that extends from it.
*
* The Camera will have its `roundPixels` property set to whatever `CameraManager.roundPixels` is. You can change
* it after addition if required.
*
* The Camera will be assigned an ID, which is used for Game Object exclusion and then added to the
* manager. As long as it doesn't already exist in the manager it will be added then returned.
*
* If this method returns `null` then the Camera already exists in this Camera Manager.
*
* @method Phaser.Cameras.Scene2D.CameraManager#addExisting
* @since 3.0.0
*
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to be added to the Camera Manager.
* @param {boolean} [makeMain=false] - Set this Camera as being the 'main' camera. This just makes the property `main` a reference to it.
*
* @return {?Phaser.Cameras.Scene2D.Camera} The Camera that was added to the Camera Manager, or `null` if it couldn't be added.
*/
addExisting: function(camera, makeMain) {
if (makeMain === void 0) {
makeMain = false;
}
var index = this.cameras.indexOf(camera);
if (index === -1) {
camera.id = this.getNextID();
camera.setRoundPixels(this.roundPixels);
this.cameras.push(camera);
if (makeMain) {
this.main = camera;
}
return camera;
}
return null;
},
/**
* Gets the next available Camera ID number.
*
* The Camera Manager supports up to 31 unique cameras, after which the ID returned will always be zero.
* You can create additional cameras beyond 31, but they cannot be used for Game Object exclusion.
*
* @method Phaser.Cameras.Scene2D.CameraManager#getNextID
* @private
* @since 3.11.0
*
* @return {number} The next available Camera ID, or 0 if they're all already in use.
*/
getNextID: function() {
var cameras = this.cameras;
var testID = 1;
for (var t = 0; t < 32; t++) {
var found = false;
for (var i = 0; i < cameras.length; i++) {
var camera = cameras[i];
if (camera && camera.id === testID) {
found = true;
continue;
}
}
if (found) {
testID = testID << 1;
} else {
return testID;
}
}
return 0;
},
/**
* Gets the total number of Cameras in this Camera Manager.
*
* If the optional `isVisible` argument is set it will only count Cameras that are currently visible.
*
* @method Phaser.Cameras.Scene2D.CameraManager#getTotal
* @since 3.11.0
*
* @param {boolean} [isVisible=false] - Set the `true` to only include visible Cameras in the total.
*
* @return {number} The total number of Cameras in this Camera Manager.
*/
getTotal: function(isVisible) {
if (isVisible === void 0) {
isVisible = false;
}
var total = 0;
var cameras = this.cameras;
for (var i = 0; i < cameras.length; i++) {
var camera = cameras[i];
if (!isVisible || isVisible && camera.visible) {
total++;
}
}
return total;
},
/**
* Populates this Camera Manager based on the given configuration object, or an array of config objects.
*
* See the `Phaser.Types.Cameras.Scene2D.CameraConfig` documentation for details of the object structure.
*
* @method Phaser.Cameras.Scene2D.CameraManager#fromJSON
* @since 3.0.0
*
* @param {(Phaser.Types.Cameras.Scene2D.CameraConfig|Phaser.Types.Cameras.Scene2D.CameraConfig[])} config - A Camera configuration object, or an array of them, to be added to this Camera Manager.
*
* @return {this} This Camera Manager instance.
*/
fromJSON: function(config) {
if (!Array.isArray(config)) {
config = [config];
}
var gameWidth = this.scene.sys.scale.width;
var gameHeight = this.scene.sys.scale.height;
for (var i = 0; i < config.length; i++) {
var cameraConfig = config[i];
var x = GetFastValue(cameraConfig, "x", 0);
var y = GetFastValue(cameraConfig, "y", 0);
var width = GetFastValue(cameraConfig, "width", gameWidth);
var height = GetFastValue(cameraConfig, "height", gameHeight);
var camera = this.add(x, y, width, height);
camera.name = GetFastValue(cameraConfig, "name", "");
camera.zoom = GetFastValue(cameraConfig, "zoom", 1);
camera.rotation = GetFastValue(cameraConfig, "rotation", 0);
camera.scrollX = GetFastValue(cameraConfig, "scrollX", 0);
camera.scrollY = GetFastValue(cameraConfig, "scrollY", 0);
camera.roundPixels = GetFastValue(cameraConfig, "roundPixels", false);
camera.visible = GetFastValue(cameraConfig, "visible", true);
var backgroundColor = GetFastValue(cameraConfig, "backgroundColor", false);
if (backgroundColor) {
camera.setBackgroundColor(backgroundColor);
}
var boundsConfig = GetFastValue(cameraConfig, "bounds", null);
if (boundsConfig) {
var bx = GetFastValue(boundsConfig, "x", 0);
var by = GetFastValue(boundsConfig, "y", 0);
var bwidth = GetFastValue(boundsConfig, "width", gameWidth);
var bheight = GetFastValue(boundsConfig, "height", gameHeight);
camera.setBounds(bx, by, bwidth, bheight);
}
}
return this;
},
/**
* Gets a Camera based on its name.
*
* Camera names are optional and don't have to be set, so this method is only of any use if you
* have given your Cameras unique names.
*
* @method Phaser.Cameras.Scene2D.CameraManager#getCamera
* @since 3.0.0
*
* @param {string} name - The name of the Camera.
*
* @return {?Phaser.Cameras.Scene2D.Camera} The first Camera with a name matching the given string, otherwise `null`.
*/
getCamera: function(name) {
var cameras = this.cameras;
for (var i = 0; i < cameras.length; i++) {
if (cameras[i].name === name) {
return cameras[i];
}
}
return null;
},
/**
* Returns an array of all cameras below the given Pointer.
*
* The first camera in the array is the top-most camera in the camera list.
*
* @method Phaser.Cameras.Scene2D.CameraManager#getCamerasBelowPointer
* @since 3.10.0
*
* @param {Phaser.Input.Pointer} pointer - The Pointer to check against.
*
* @return {Phaser.Cameras.Scene2D.Camera[]} An array of cameras below the Pointer.
*/
getCamerasBelowPointer: function(pointer) {
var cameras = this.cameras;
var x = pointer.x;
var y = pointer.y;
var output = [];
for (var i = 0; i < cameras.length; i++) {
var camera = cameras[i];
if (camera.visible && camera.inputEnabled && RectangleContains(camera, x, y)) {
output.unshift(camera);
}
}
return output;
},
/**
* Removes the given Camera, or an array of Cameras, from this Camera Manager.
*
* If found in the Camera Manager it will be immediately removed from the local cameras array.
* If also currently the 'main' camera, 'main' will be reset to be camera 0.
*
* The removed Cameras are automatically destroyed if the `runDestroy` argument is `true`, which is the default.
* If you wish to re-use the cameras then set this to `false`, but know that they will retain their references
* and internal data until destroyed or re-added to a Camera Manager.
*
* @method Phaser.Cameras.Scene2D.CameraManager#remove
* @since 3.0.0
*
* @param {(Phaser.Cameras.Scene2D.Camera|Phaser.Cameras.Scene2D.Camera[])} camera - The Camera, or an array of Cameras, to be removed from this Camera Manager.
* @param {boolean} [runDestroy=true] - Automatically call `Camera.destroy` on each Camera removed from this Camera Manager.
*
* @return {number} The total number of Cameras removed.
*/
remove: function(camera, runDestroy) {
if (runDestroy === void 0) {
runDestroy = true;
}
if (!Array.isArray(camera)) {
camera = [camera];
}
var total = 0;
var cameras = this.cameras;
for (var i = 0; i < camera.length; i++) {
var index = cameras.indexOf(camera[i]);
if (index !== -1) {
if (runDestroy) {
cameras[index].destroy();
} else {
cameras[index].renderList = [];
}
cameras.splice(index, 1);
total++;
}
}
if (!this.main && cameras[0]) {
this.main = cameras[0];
}
return total;
},
/**
* The internal render method. This is called automatically by the Scene and should not be invoked directly.
*
* It will iterate through all local cameras and render them in turn, as long as they're visible and have
* an alpha level > 0.
*
* @method Phaser.Cameras.Scene2D.CameraManager#render
* @protected
* @since 3.0.0
*
* @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The Renderer that will render the children to this camera.
* @param {Phaser.GameObjects.DisplayList} displayList - The Display List for the Scene.
*/
render: function(renderer, displayList) {
var scene = this.scene;
var cameras = this.cameras;
for (var i = 0; i < cameras.length; i++) {
var camera = cameras[i];
if (camera.visible && camera.alpha > 0) {
camera.preRender();
var visibleChildren = this.getVisibleChildren(displayList.getChildren(), camera);
renderer.render(scene, visibleChildren, camera);
}
}
},
/**
* Takes an array of Game Objects and a Camera and returns a new array
* containing only those Game Objects that pass the `willRender` test
* against the given Camera.
*
* @method Phaser.Cameras.Scene2D.CameraManager#getVisibleChildren
* @since 3.50.0
*
* @param {Phaser.GameObjects.GameObject[]} children - An array of Game Objects to be checked against the camera.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The camera to filter the Game Objects against.
*
* @return {Phaser.GameObjects.GameObject[]} A filtered list of only Game Objects within the Scene that will render against the given Camera.
*/
getVisibleChildren: function(children, camera) {
return children.filter(function(child) {
return child.willRender(camera);
});
},
/**
* Resets this Camera Manager.
*
* This will iterate through all current Cameras, destroying them all, then it will reset the
* cameras array, reset the ID counter and create 1 new single camera using the default values.
*
* @method Phaser.Cameras.Scene2D.CameraManager#resetAll
* @since 3.0.0
*
* @return {Phaser.Cameras.Scene2D.Camera} The freshly created main Camera.
*/
resetAll: function() {
for (var i = 0; i < this.cameras.length; i++) {
this.cameras[i].destroy();
}
this.cameras = [];
this.main = this.add();
return this.main;
},
/**
* The main update loop. Called automatically when the Scene steps.
*
* @method Phaser.Cameras.Scene2D.CameraManager#update
* @protected
* @since 3.0.0
*
* @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout.
* @param {number} delta - The delta time, in ms, elapsed since the last frame.
*/
update: function(time, delta) {
for (var i = 0; i < this.cameras.length; i++) {
this.cameras[i].update(time, delta);
}
},
/**
* The event handler that manages the `resize` event dispatched by the Scale Manager.
*
* @method Phaser.Cameras.Scene2D.CameraManager#onResize
* @since 3.18.0
*
* @param {Phaser.Structs.Size} gameSize - The default Game Size object. This is the un-modified game dimensions.
* @param {Phaser.Structs.Size} baseSize - The base Size object. The game dimensions. The canvas width / height values match this.
*/
onResize: function(gameSize, baseSize, displaySize, previousWidth, previousHeight) {
for (var i = 0; i < this.cameras.length; i++) {
var cam = this.cameras[i];
if (cam._x === 0 && cam._y === 0 && cam._width === previousWidth && cam._height === previousHeight) {
cam.setSize(baseSize.width, baseSize.height);
}
}
},
/**
* Resizes all cameras to the given dimensions.
*
* @method Phaser.Cameras.Scene2D.CameraManager#resize
* @since 3.2.0
*
* @param {number} width - The new width of the camera.
* @param {number} height - The new height of the camera.
*/
resize: function(width, height) {
for (var i = 0; i < this.cameras.length; i++) {
this.cameras[i].setSize(width, height);
}
},
/**
* The Scene that owns this plugin is shutting down.
* We need to kill and reset all internal properties as well as stop listening to Scene events.
*
* @method Phaser.Cameras.Scene2D.CameraManager#shutdown
* @private
* @since 3.0.0
*/
shutdown: function() {
this.main = void 0;
for (var i = 0; i < this.cameras.length; i++) {
this.cameras[i].destroy();
}
this.cameras = [];
var eventEmitter = this.systems.events;
eventEmitter.off(SceneEvents.UPDATE, this.update, this);
eventEmitter.off(SceneEvents.SHUTDOWN, this.shutdown, this);
},
/**
* The Scene that owns this plugin is being destroyed.
* We need to shutdown and then kill off all external references.
*
* @method Phaser.Cameras.Scene2D.CameraManager#destroy
* @private
* @since 3.0.0
*/
destroy: function() {
this.shutdown();
this.default.destroy();
this.systems.events.off(SceneEvents.START, this.start, this);
this.systems.events.off(SceneEvents.DESTROY, this.destroy, this);
this.systems.game.scale.off(ScaleEvents.RESIZE, this.onResize, this);
this.scene = null;
this.systems = null;
}
});
PluginCache.register("CameraManager", CameraManager, "cameras");
module2.exports = CameraManager;
}
),
/***/
5020: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Clamp = __webpack_require__2(45319);
var Class = __webpack_require__2(83419);
var Events = __webpack_require__2(19715);
var Fade = new Class({
initialize: function Fade2(camera) {
this.camera = camera;
this.isRunning = false;
this.isComplete = false;
this.direction = true;
this.duration = 0;
this.red = 0;
this.green = 0;
this.blue = 0;
this.alpha = 0;
this.progress = 0;
this._elapsed = 0;
this._onUpdate;
this._onUpdateScope;
},
/**
* Fades the Camera to or from the given color over the duration specified.
*
* @method Phaser.Cameras.Scene2D.Effects.Fade#start
* @fires Phaser.Cameras.Scene2D.Events#FADE_IN_START
* @fires Phaser.Cameras.Scene2D.Events#FADE_OUT_START
* @since 3.5.0
*
* @param {boolean} [direction=true] - The direction of the fade. `true` = fade out (transparent to color), `false` = fade in (color to transparent)
* @param {number} [duration=1000] - The duration of the effect in milliseconds.
* @param {number} [red=0] - The amount to fade the red channel towards. A value between 0 and 255.
* @param {number} [green=0] - The amount to fade the green channel towards. A value between 0 and 255.
* @param {number} [blue=0] - The amount to fade the blue channel towards. A value between 0 and 255.
* @param {boolean} [force=false] - Force the effect to start immediately, even if already running.
* @param {Phaser.Types.Cameras.Scene2D.CameraFadeCallback} [callback] - This callback will be invoked every frame for the duration of the effect.
* It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is.
* @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
*
* @return {Phaser.Cameras.Scene2D.Camera} The Camera on which the effect was started.
*/
start: function(direction, duration, red, green, blue, force, callback, context) {
if (direction === void 0) {
direction = true;
}
if (duration === void 0) {
duration = 1e3;
}
if (red === void 0) {
red = 0;
}
if (green === void 0) {
green = 0;
}
if (blue === void 0) {
blue = 0;
}
if (force === void 0) {
force = false;
}
if (callback === void 0) {
callback = null;
}
if (context === void 0) {
context = this.camera.scene;
}
if (!force && this.isRunning) {
return this.camera;
}
this.isRunning = true;
this.isComplete = false;
this.duration = duration;
this.direction = direction;
this.progress = 0;
this.red = red;
this.green = green;
this.blue = blue;
this.alpha = direction ? Number.MIN_VALUE : 1;
this._elapsed = 0;
this._onUpdate = callback;
this._onUpdateScope = context;
var eventName = direction ? Events.FADE_OUT_START : Events.FADE_IN_START;
this.camera.emit(eventName, this.camera, this, duration, red, green, blue);
return this.camera;
},
/**
* The main update loop for this effect. Called automatically by the Camera.
*
* @method Phaser.Cameras.Scene2D.Effects.Fade#update
* @since 3.5.0
*
* @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout.
* @param {number} delta - The delta time, in ms, elapsed since the last frame.
*/
update: function(time, delta) {
if (!this.isRunning) {
return;
}
this._elapsed += delta;
this.progress = Clamp(this._elapsed / this.duration, 0, 1);
if (this._onUpdate) {
this._onUpdate.call(this._onUpdateScope, this.camera, this.progress);
}
if (this._elapsed < this.duration) {
this.alpha = this.direction ? this.progress : 1 - this.progress;
} else {
this.alpha = this.direction ? 1 : 0;
this.effectComplete();
}
},
/**
* Called internally by the Canvas Renderer.
*
* @method Phaser.Cameras.Scene2D.Effects.Fade#postRenderCanvas
* @since 3.5.0
*
* @param {CanvasRenderingContext2D} ctx - The Canvas context to render to.
*
* @return {boolean} `true` if the effect drew to the renderer, otherwise `false`.
*/
postRenderCanvas: function(ctx) {
if (!this.isRunning && !this.isComplete) {
return false;
}
var camera = this.camera;
ctx.fillStyle = "rgba(" + this.red + "," + this.green + "," + this.blue + "," + this.alpha + ")";
ctx.fillRect(camera.x, camera.y, camera.width, camera.height);
return true;
},
/**
* Called internally by the WebGL Renderer.
*
* @method Phaser.Cameras.Scene2D.Effects.Fade#postRenderWebGL
* @since 3.5.0
*
* @param {Phaser.Renderer.WebGL.Pipelines.MultiPipeline} pipeline - The WebGL Pipeline to render to. Must provide the `drawFillRect` method.
* @param {function} getTintFunction - A function that will return the gl safe tint colors.
*
* @return {boolean} `true` if the effect drew to the renderer, otherwise `false`.
*/
postRenderWebGL: function(pipeline, getTintFunction) {
if (!this.isRunning && !this.isComplete) {
return false;
}
var camera = this.camera;
var red = this.red / 255;
var green = this.green / 255;
var blue = this.blue / 255;
pipeline.drawFillRect(
camera.x,
camera.y,
camera.width,
camera.height,
getTintFunction(blue, green, red, 1),
this.alpha
);
return true;
},
/**
* Called internally when the effect completes.
*
* @method Phaser.Cameras.Scene2D.Effects.Fade#effectComplete
* @fires Phaser.Cameras.Scene2D.Events#FADE_IN_COMPLETE
* @fires Phaser.Cameras.Scene2D.Events#FADE_OUT_COMPLETE
* @since 3.5.0
*/
effectComplete: function() {
this._onUpdate = null;
this._onUpdateScope = null;
this.isRunning = false;
this.isComplete = true;
var eventName = this.direction ? Events.FADE_OUT_COMPLETE : Events.FADE_IN_COMPLETE;
this.camera.emit(eventName, this.camera, this);
},
/**
* Resets this camera effect.
* If it was previously running, it stops instantly without calling its onComplete callback or emitting an event.
*
* @method Phaser.Cameras.Scene2D.Effects.Fade#reset
* @since 3.5.0
*/
reset: function() {
this.isRunning = false;
this.isComplete = false;
this._onUpdate = null;
this._onUpdateScope = null;
},
/**
* Destroys this effect, releasing it from the Camera.
*
* @method Phaser.Cameras.Scene2D.Effects.Fade#destroy
* @since 3.5.0
*/
destroy: function() {
this.reset();
this.camera = null;
}
});
module2.exports = Fade;
}
),
/***/
10662: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Clamp = __webpack_require__2(45319);
var Class = __webpack_require__2(83419);
var Events = __webpack_require__2(19715);
var Flash = new Class({
initialize: function Flash2(camera) {
this.camera = camera;
this.isRunning = false;
this.duration = 0;
this.red = 0;
this.green = 0;
this.blue = 0;
this.alpha = 1;
this.progress = 0;
this._elapsed = 0;
this._alpha;
this._onUpdate;
this._onUpdateScope;
},
/**
* Flashes the Camera to or from the given color over the duration specified.
*
* @method Phaser.Cameras.Scene2D.Effects.Flash#start
* @fires Phaser.Cameras.Scene2D.Events#FLASH_START
* @fires Phaser.Cameras.Scene2D.Events#FLASH_COMPLETE
* @since 3.5.0
*
* @param {number} [duration=250] - The duration of the effect in milliseconds.
* @param {number} [red=255] - The amount to flash the red channel towards. A value between 0 and 255.
* @param {number} [green=255] - The amount to flash the green channel towards. A value between 0 and 255.
* @param {number} [blue=255] - The amount to flash the blue channel towards. A value between 0 and 255.
* @param {boolean} [force=false] - Force the effect to start immediately, even if already running.
* @param {Phaser.Types.Cameras.Scene2D.CameraFlashCallback} [callback] - This callback will be invoked every frame for the duration of the effect.
* It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is.
* @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
*
* @return {Phaser.Cameras.Scene2D.Camera} The Camera on which the effect was started.
*/
start: function(duration, red, green, blue, force, callback, context) {
if (duration === void 0) {
duration = 250;
}
if (red === void 0) {
red = 255;
}
if (green === void 0) {
green = 255;
}
if (blue === void 0) {
blue = 255;
}
if (force === void 0) {
force = false;
}
if (callback === void 0) {
callback = null;
}
if (context === void 0) {
context = this.camera.scene;
}
if (!force && this.isRunning) {
return this.camera;
}
this.isRunning = true;
this.duration = duration;
this.progress = 0;
this.red = red;
this.green = green;
this.blue = blue;
this._alpha = this.alpha;
this._elapsed = 0;
this._onUpdate = callback;
this._onUpdateScope = context;
this.camera.emit(Events.FLASH_START, this.camera, this, duration, red, green, blue);
return this.camera;
},
/**
* The main update loop for this effect. Called automatically by the Camera.
*
* @method Phaser.Cameras.Scene2D.Effects.Flash#update
* @since 3.5.0
*
* @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout.
* @param {number} delta - The delta time, in ms, elapsed since the last frame.
*/
update: function(time, delta) {
if (!this.isRunning) {
return;
}
this._elapsed += delta;
this.progress = Clamp(this._elapsed / this.duration, 0, 1);
if (this._onUpdate) {
this._onUpdate.call(this._onUpdateScope, this.camera, this.progress);
}
if (this._elapsed < this.duration) {
this.alpha = this._alpha * (1 - this.progress);
} else {
this.effectComplete();
}
},
/**
* Called internally by the Canvas Renderer.
*
* @method Phaser.Cameras.Scene2D.Effects.Flash#postRenderCanvas
* @since 3.5.0
*
* @param {CanvasRenderingContext2D} ctx - The Canvas context to render to.
*
* @return {boolean} `true` if the effect drew to the renderer, otherwise `false`.
*/
postRenderCanvas: function(ctx) {
if (!this.isRunning) {
return false;
}
var camera = this.camera;
ctx.fillStyle = "rgba(" + this.red + "," + this.green + "," + this.blue + "," + this.alpha + ")";
ctx.fillRect(camera.x, camera.y, camera.width, camera.height);
return true;
},
/**
* Called internally by the WebGL Renderer.
*
* @method Phaser.Cameras.Scene2D.Effects.Flash#postRenderWebGL
* @since 3.5.0
*
* @param {Phaser.Renderer.WebGL.Pipelines.MultiPipeline} pipeline - The WebGL Pipeline to render to. Must provide the `drawFillRect` method.
* @param {function} getTintFunction - A function that will return the gl safe tint colors.
*
* @return {boolean} `true` if the effect drew to the renderer, otherwise `false`.
*/
postRenderWebGL: function(pipeline, getTintFunction) {
if (!this.isRunning) {
return false;
}
var camera = this.camera;
var red = this.red / 255;
var green = this.green / 255;
var blue = this.blue / 255;
pipeline.drawFillRect(
camera.x,
camera.y,
camera.width,
camera.height,
getTintFunction(blue, green, red, 1),
this.alpha
);
return true;
},
/**
* Called internally when the effect completes.
*
* @method Phaser.Cameras.Scene2D.Effects.Flash#effectComplete
* @fires Phaser.Cameras.Scene2D.Events#FLASH_COMPLETE
* @since 3.5.0
*/
effectComplete: function() {
this.alpha = this._alpha;
this._onUpdate = null;
this._onUpdateScope = null;
this.isRunning = false;
this.camera.emit(Events.FLASH_COMPLETE, this.camera, this);
},
/**
* Resets this camera effect.
* If it was previously running, it stops instantly without calling its onComplete callback or emitting an event.
*
* @method Phaser.Cameras.Scene2D.Effects.Flash#reset
* @since 3.5.0
*/
reset: function() {
this.isRunning = false;
this._onUpdate = null;
this._onUpdateScope = null;
},
/**
* Destroys this effect, releasing it from the Camera.
*
* @method Phaser.Cameras.Scene2D.Effects.Flash#destroy
* @since 3.5.0
*/
destroy: function() {
this.reset();
this.camera = null;
}
});
module2.exports = Flash;
}
),
/***/
20359: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Clamp = __webpack_require__2(45319);
var Class = __webpack_require__2(83419);
var EaseMap = __webpack_require__2(62640);
var Events = __webpack_require__2(19715);
var Vector2 = __webpack_require__2(26099);
var Pan = new Class({
initialize: function Pan2(camera) {
this.camera = camera;
this.isRunning = false;
this.duration = 0;
this.source = new Vector2();
this.current = new Vector2();
this.destination = new Vector2();
this.ease;
this.progress = 0;
this._elapsed = 0;
this._onUpdate;
this._onUpdateScope;
},
/**
* This effect will scroll the Camera so that the center of its viewport finishes at the given destination,
* over the duration and with the ease specified.
*
* @method Phaser.Cameras.Scene2D.Effects.Pan#start
* @fires Phaser.Cameras.Scene2D.Events#PAN_START
* @fires Phaser.Cameras.Scene2D.Events#PAN_COMPLETE
* @since 3.11.0
*
* @param {number} x - The destination x coordinate to scroll the center of the Camera viewport to.
* @param {number} y - The destination y coordinate to scroll the center of the Camera viewport to.
* @param {number} [duration=1000] - The duration of the effect in milliseconds.
* @param {(string|function)} [ease='Linear'] - The ease to use for the pan. Can be any of the Phaser Easing constants or a custom function.
* @param {boolean} [force=false] - Force the pan effect to start immediately, even if already running.
* @param {Phaser.Types.Cameras.Scene2D.CameraPanCallback} [callback] - This callback will be invoked every frame for the duration of the effect.
* It is sent four arguments: A reference to the camera, a progress amount between 0 and 1 indicating how complete the effect is,
* the current camera scroll x coordinate and the current camera scroll y coordinate.
* @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
*
* @return {Phaser.Cameras.Scene2D.Camera} The Camera on which the effect was started.
*/
start: function(x, y, duration, ease, force, callback, context) {
if (duration === void 0) {
duration = 1e3;
}
if (ease === void 0) {
ease = EaseMap.Linear;
}
if (force === void 0) {
force = false;
}
if (callback === void 0) {
callback = null;
}
if (context === void 0) {
context = this.camera.scene;
}
var cam = this.camera;
if (!force && this.isRunning) {
return cam;
}
this.isRunning = true;
this.duration = duration;
this.progress = 0;
this.source.set(cam.scrollX, cam.scrollY);
this.destination.set(x, y);
cam.getScroll(x, y, this.current);
if (typeof ease === "string" && EaseMap.hasOwnProperty(ease)) {
this.ease = EaseMap[ease];
} else if (typeof ease === "function") {
this.ease = ease;
}
this._elapsed = 0;
this._onUpdate = callback;
this._onUpdateScope = context;
this.camera.emit(Events.PAN_START, this.camera, this, duration, x, y);
return cam;
},
/**
* The main update loop for this effect. Called automatically by the Camera.
*
* @method Phaser.Cameras.Scene2D.Effects.Pan#update
* @since 3.11.0
*
* @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout.
* @param {number} delta - The delta time, in ms, elapsed since the last frame.
*/
update: function(time, delta) {
if (!this.isRunning) {
return;
}
this._elapsed += delta;
var progress = Clamp(this._elapsed / this.duration, 0, 1);
this.progress = progress;
var cam = this.camera;
if (this._elapsed < this.duration) {
var v = this.ease(progress);
cam.getScroll(this.destination.x, this.destination.y, this.current);
var x = this.source.x + (this.current.x - this.source.x) * v;
var y = this.source.y + (this.current.y - this.source.y) * v;
cam.setScroll(x, y);
if (this._onUpdate) {
this._onUpdate.call(this._onUpdateScope, cam, progress, x, y);
}
} else {
cam.centerOn(this.destination.x, this.destination.y);
if (this._onUpdate) {
this._onUpdate.call(this._onUpdateScope, cam, progress, cam.scrollX, cam.scrollY);
}
this.effectComplete();
}
},
/**
* Called internally when the effect completes.
*
* @method Phaser.Cameras.Scene2D.Effects.Pan#effectComplete
* @fires Phaser.Cameras.Scene2D.Events#PAN_COMPLETE
* @since 3.11.0
*/
effectComplete: function() {
this._onUpdate = null;
this._onUpdateScope = null;
this.isRunning = false;
this.camera.emit(Events.PAN_COMPLETE, this.camera, this);
},
/**
* Resets this camera effect.
* If it was previously running, it stops instantly without calling its onComplete callback or emitting an event.
*
* @method Phaser.Cameras.Scene2D.Effects.Pan#reset
* @since 3.11.0
*/
reset: function() {
this.isRunning = false;
this._onUpdate = null;
this._onUpdateScope = null;
},
/**
* Destroys this effect, releasing it from the Camera.
*
* @method Phaser.Cameras.Scene2D.Effects.Pan#destroy
* @since 3.11.0
*/
destroy: function() {
this.reset();
this.camera = null;
this.source = null;
this.destination = null;
}
});
module2.exports = Pan;
}
),
/***/
34208: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Clamp = __webpack_require__2(45319);
var Class = __webpack_require__2(83419);
var Events = __webpack_require__2(19715);
var EaseMap = __webpack_require__2(62640);
var RotateTo = new Class({
initialize: function RotateTo2(camera) {
this.camera = camera;
this.isRunning = false;
this.duration = 0;
this.source = 0;
this.current = 0;
this.destination = 0;
this.ease;
this.progress = 0;
this._elapsed = 0;
this._onUpdate;
this._onUpdateScope;
this.clockwise = true;
this.shortestPath = false;
},
/**
* This effect will scroll the Camera so that the center of its viewport finishes at the given angle,
* over the duration and with the ease specified.
*
* @method Phaser.Cameras.Scene2D.Effects.RotateTo#start
* @fires Phaser.Cameras.Scene2D.Events#ROTATE_START
* @fires Phaser.Cameras.Scene2D.Events#ROTATE_COMPLETE
* @since 3.23.0
*
* @param {number} radians - The destination angle in radians to rotate the Camera viewport to. If the angle is positive then the rotation is clockwise else anticlockwise
* @param {boolean} [shortestPath=false] - If shortest path is set to true the camera will rotate in the quickest direction clockwise or anti-clockwise.
* @param {number} [duration=1000] - The duration of the effect in milliseconds.
* @param {(string|function)} [ease='Linear'] - The ease to use for the Rotate. Can be any of the Phaser Easing constants or a custom function.
* @param {boolean} [force=false] - Force the rotation effect to start immediately, even if already running.
* @param {CameraRotateCallback} [callback] - This callback will be invoked every frame for the duration of the effect.
* It is sent four arguments: A reference to the camera, a progress amount between 0 and 1 indicating how complete the effect is,
* the current camera scroll x coordinate and the current camera scroll y coordinate.
* @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
*
* @return {Phaser.Cameras.Scene2D.Camera} The Camera on which the effect was started.
*/
start: function(radians, shortestPath, duration, ease, force, callback, context) {
if (duration === void 0) {
duration = 1e3;
}
if (ease === void 0) {
ease = EaseMap.Linear;
}
if (force === void 0) {
force = false;
}
if (callback === void 0) {
callback = null;
}
if (context === void 0) {
context = this.camera.scene;
}
if (shortestPath === void 0) {
shortestPath = false;
}
this.shortestPath = shortestPath;
var tmpDestination = radians;
if (radians < 0) {
tmpDestination = -1 * radians;
this.clockwise = false;
} else {
this.clockwise = true;
}
var maxRad = 360 * Math.PI / 180;
tmpDestination = tmpDestination - Math.floor(tmpDestination / maxRad) * maxRad;
var cam = this.camera;
if (!force && this.isRunning) {
return cam;
}
this.isRunning = true;
this.duration = duration;
this.progress = 0;
this.source = cam.rotation;
this.destination = tmpDestination;
if (typeof ease === "string" && EaseMap.hasOwnProperty(ease)) {
this.ease = EaseMap[ease];
} else if (typeof ease === "function") {
this.ease = ease;
}
this._elapsed = 0;
this._onUpdate = callback;
this._onUpdateScope = context;
if (this.shortestPath) {
var cwDist = 0;
var acwDist = 0;
if (this.destination > this.source) {
cwDist = Math.abs(this.destination - this.source);
} else {
cwDist = Math.abs(this.destination + maxRad) - this.source;
}
if (this.source > this.destination) {
acwDist = Math.abs(this.source - this.destination);
} else {
acwDist = Math.abs(this.source + maxRad) - this.destination;
}
if (cwDist < acwDist) {
this.clockwise = true;
} else if (cwDist > acwDist) {
this.clockwise = false;
}
}
this.camera.emit(Events.ROTATE_START, this.camera, this, duration, tmpDestination);
return cam;
},
/**
* The main update loop for this effect. Called automatically by the Camera.
*
* @method Phaser.Cameras.Scene2D.Effects.RotateTo#update
* @since 3.23.0
*
* @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout.
* @param {number} delta - The delta time, in ms, elapsed since the last frame.
*/
update: function(time, delta) {
if (!this.isRunning) {
return;
}
this._elapsed += delta;
var progress = Clamp(this._elapsed / this.duration, 0, 1);
this.progress = progress;
var cam = this.camera;
if (this._elapsed < this.duration) {
var v = this.ease(progress);
this.current = cam.rotation;
var distance = 0;
var maxRad = 360 * Math.PI / 180;
var target = this.destination;
var current = this.current;
if (this.clockwise === false) {
target = this.current;
current = this.destination;
}
if (target >= current) {
distance = Math.abs(target - current);
} else {
distance = Math.abs(target + maxRad) - current;
}
var r = 0;
if (this.clockwise) {
r = cam.rotation + distance * v;
} else {
r = cam.rotation - distance * v;
}
cam.rotation = r;
if (this._onUpdate) {
this._onUpdate.call(this._onUpdateScope, cam, progress, r);
}
} else {
cam.rotation = this.destination;
if (this._onUpdate) {
this._onUpdate.call(this._onUpdateScope, cam, progress, this.destination);
}
this.effectComplete();
}
},
/**
* Called internally when the effect completes.
*
* @method Phaser.Cameras.Scene2D.Effects.RotateTo#effectComplete
* @since 3.23.0
*/
effectComplete: function() {
this._onUpdate = null;
this._onUpdateScope = null;
this.isRunning = false;
this.camera.emit(Events.ROTATE_COMPLETE, this.camera, this);
},
/**
* Resets this camera effect.
* If it was previously running, it stops instantly without calling its onComplete callback or emitting an event.
*
* @method Phaser.Cameras.Scene2D.Effects.RotateTo#reset
* @since 3.23.0
*/
reset: function() {
this.isRunning = false;
this._onUpdate = null;
this._onUpdateScope = null;
},
/**
* Destroys this effect, releasing it from the Camera.
*
* @method Phaser.Cameras.Scene2D.Effects.RotateTo#destroy
* @since 3.23.0
*/
destroy: function() {
this.reset();
this.camera = null;
this.source = null;
this.destination = null;
}
});
module2.exports = RotateTo;
}
),
/***/
30330: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Clamp = __webpack_require__2(45319);
var Class = __webpack_require__2(83419);
var Events = __webpack_require__2(19715);
var Vector2 = __webpack_require__2(26099);
var Shake = new Class({
initialize: function Shake2(camera) {
this.camera = camera;
this.isRunning = false;
this.duration = 0;
this.intensity = new Vector2();
this.progress = 0;
this._elapsed = 0;
this._offsetX = 0;
this._offsetY = 0;
this._onUpdate;
this._onUpdateScope;
},
/**
* Shakes the Camera by the given intensity over the duration specified.
*
* @method Phaser.Cameras.Scene2D.Effects.Shake#start
* @fires Phaser.Cameras.Scene2D.Events#SHAKE_START
* @fires Phaser.Cameras.Scene2D.Events#SHAKE_COMPLETE
* @since 3.5.0
*
* @param {number} [duration=100] - The duration of the effect in milliseconds.
* @param {(number|Phaser.Math.Vector2)} [intensity=0.05] - The intensity of the shake.
* @param {boolean} [force=false] - Force the shake effect to start immediately, even if already running.
* @param {Phaser.Types.Cameras.Scene2D.CameraShakeCallback} [callback] - This callback will be invoked every frame for the duration of the effect.
* It is sent two arguments: A reference to the camera and a progress amount between 0 and 1 indicating how complete the effect is.
* @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
*
* @return {Phaser.Cameras.Scene2D.Camera} The Camera on which the effect was started.
*/
start: function(duration, intensity, force, callback, context) {
if (duration === void 0) {
duration = 100;
}
if (intensity === void 0) {
intensity = 0.05;
}
if (force === void 0) {
force = false;
}
if (callback === void 0) {
callback = null;
}
if (context === void 0) {
context = this.camera.scene;
}
if (!force && this.isRunning) {
return this.camera;
}
this.isRunning = true;
this.duration = duration;
this.progress = 0;
if (typeof intensity === "number") {
this.intensity.set(intensity);
} else {
this.intensity.set(intensity.x, intensity.y);
}
this._elapsed = 0;
this._offsetX = 0;
this._offsetY = 0;
this._onUpdate = callback;
this._onUpdateScope = context;
this.camera.emit(Events.SHAKE_START, this.camera, this, duration, intensity);
return this.camera;
},
/**
* The pre-render step for this effect. Called automatically by the Camera.
*
* @method Phaser.Cameras.Scene2D.Effects.Shake#preRender
* @since 3.5.0
*/
preRender: function() {
if (this.isRunning) {
this.camera.matrix.translate(this._offsetX, this._offsetY);
}
},
/**
* The main update loop for this effect. Called automatically by the Camera.
*
* @method Phaser.Cameras.Scene2D.Effects.Shake#update
* @since 3.5.0
*
* @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout.
* @param {number} delta - The delta time, in ms, elapsed since the last frame.
*/
update: function(time, delta) {
if (!this.isRunning) {
return;
}
this._elapsed += delta;
this.progress = Clamp(this._elapsed / this.duration, 0, 1);
if (this._onUpdate) {
this._onUpdate.call(this._onUpdateScope, this.camera, this.progress);
}
if (this._elapsed < this.duration) {
var intensity = this.intensity;
var width = this.camera.width;
var height = this.camera.height;
var zoom = this.camera.zoom;
this._offsetX = (Math.random() * intensity.x * width * 2 - intensity.x * width) * zoom;
this._offsetY = (Math.random() * intensity.y * height * 2 - intensity.y * height) * zoom;
if (this.camera.roundPixels) {
this._offsetX = Math.round(this._offsetX);
this._offsetY = Math.round(this._offsetY);
}
} else {
this.effectComplete();
}
},
/**
* Called internally when the effect completes.
*
* @method Phaser.Cameras.Scene2D.Effects.Shake#effectComplete
* @fires Phaser.Cameras.Scene2D.Events#SHAKE_COMPLETE
* @since 3.5.0
*/
effectComplete: function() {
this._offsetX = 0;
this._offsetY = 0;
this._onUpdate = null;
this._onUpdateScope = null;
this.isRunning = false;
this.camera.emit(Events.SHAKE_COMPLETE, this.camera, this);
},
/**
* Resets this camera effect.
* If it was previously running, it stops instantly without calling its onComplete callback or emitting an event.
*
* @method Phaser.Cameras.Scene2D.Effects.Shake#reset
* @since 3.5.0
*/
reset: function() {
this.isRunning = false;
this._offsetX = 0;
this._offsetY = 0;
this._onUpdate = null;
this._onUpdateScope = null;
},
/**
* Destroys this effect, releasing it from the Camera.
*
* @method Phaser.Cameras.Scene2D.Effects.Shake#destroy
* @since 3.5.0
*/
destroy: function() {
this.reset();
this.camera = null;
this.intensity = null;
}
});
module2.exports = Shake;
}
),
/***/
45641: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Clamp = __webpack_require__2(45319);
var Class = __webpack_require__2(83419);
var EaseMap = __webpack_require__2(62640);
var Events = __webpack_require__2(19715);
var Zoom = new Class({
initialize: function Zoom2(camera) {
this.camera = camera;
this.isRunning = false;
this.duration = 0;
this.source = 1;
this.destination = 1;
this.ease;
this.progress = 0;
this._elapsed = 0;
this._onUpdate;
this._onUpdateScope;
},
/**
* This effect will zoom the Camera to the given scale, over the duration and with the ease specified.
*
* @method Phaser.Cameras.Scene2D.Effects.Zoom#start
* @fires Phaser.Cameras.Scene2D.Events#ZOOM_START
* @fires Phaser.Cameras.Scene2D.Events#ZOOM_COMPLETE
* @since 3.11.0
*
* @param {number} zoom - The target Camera zoom value.
* @param {number} [duration=1000] - The duration of the effect in milliseconds.
* @param {(string|function)} [ease='Linear'] - The ease to use for the Zoom. Can be any of the Phaser Easing constants or a custom function.
* @param {boolean} [force=false] - Force the zoom effect to start immediately, even if already running.
* @param {Phaser.Types.Cameras.Scene2D.CameraZoomCallback} [callback] - This callback will be invoked every frame for the duration of the effect.
* It is sent three arguments: A reference to the camera, a progress amount between 0 and 1 indicating how complete the effect is,
* and the current camera zoom value.
* @param {any} [context] - The context in which the callback is invoked. Defaults to the Scene to which the Camera belongs.
*
* @return {Phaser.Cameras.Scene2D.Camera} The Camera on which the effect was started.
*/
start: function(zoom, duration, ease, force, callback, context) {
if (duration === void 0) {
duration = 1e3;
}
if (ease === void 0) {
ease = EaseMap.Linear;
}
if (force === void 0) {
force = false;
}
if (callback === void 0) {
callback = null;
}
if (context === void 0) {
context = this.camera.scene;
}
var cam = this.camera;
if (!force && this.isRunning) {
return cam;
}
this.isRunning = true;
this.duration = duration;
this.progress = 0;
this.source = cam.zoom;
this.destination = zoom;
if (typeof ease === "string" && EaseMap.hasOwnProperty(ease)) {
this.ease = EaseMap[ease];
} else if (typeof ease === "function") {
this.ease = ease;
}
this._elapsed = 0;
this._onUpdate = callback;
this._onUpdateScope = context;
this.camera.emit(Events.ZOOM_START, this.camera, this, duration, zoom);
return cam;
},
/**
* The main update loop for this effect. Called automatically by the Camera.
*
* @method Phaser.Cameras.Scene2D.Effects.Zoom#update
* @since 3.11.0
*
* @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout.
* @param {number} delta - The delta time, in ms, elapsed since the last frame.
*/
update: function(time, delta) {
if (!this.isRunning) {
return;
}
this._elapsed += delta;
this.progress = Clamp(this._elapsed / this.duration, 0, 1);
if (this._elapsed < this.duration) {
this.camera.zoom = this.source + (this.destination - this.source) * this.ease(this.progress);
if (this._onUpdate) {
this._onUpdate.call(this._onUpdateScope, this.camera, this.progress, this.camera.zoom);
}
} else {
this.camera.zoom = this.destination;
if (this._onUpdate) {
this._onUpdate.call(this._onUpdateScope, this.camera, this.progress, this.destination);
}
this.effectComplete();
}
},
/**
* Called internally when the effect completes.
*
* @method Phaser.Cameras.Scene2D.Effects.Zoom#effectComplete
* @fires Phaser.Cameras.Scene2D.Events#ZOOM_COMPLETE
* @since 3.11.0
*/
effectComplete: function() {
this._onUpdate = null;
this._onUpdateScope = null;
this.isRunning = false;
this.camera.emit(Events.ZOOM_COMPLETE, this.camera, this);
},
/**
* Resets this camera effect.
* If it was previously running, it stops instantly without calling its onComplete callback or emitting an event.
*
* @method Phaser.Cameras.Scene2D.Effects.Zoom#reset
* @since 3.11.0
*/
reset: function() {
this.isRunning = false;
this._onUpdate = null;
this._onUpdateScope = null;
},
/**
* Destroys this effect, releasing it from the Camera.
*
* @method Phaser.Cameras.Scene2D.Effects.Zoom#destroy
* @since 3.11.0
*/
destroy: function() {
this.reset();
this.camera = null;
}
});
module2.exports = Zoom;
}
),
/***/
20052: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Fade: __webpack_require__2(5020),
Flash: __webpack_require__2(10662),
Pan: __webpack_require__2(20359),
Shake: __webpack_require__2(30330),
RotateTo: __webpack_require__2(34208),
Zoom: __webpack_require__2(45641)
};
}
),
/***/
16438: (
/***/
(module2) => {
module2.exports = "cameradestroy";
}
),
/***/
32726: (
/***/
(module2) => {
module2.exports = "camerafadeincomplete";
}
),
/***/
87807: (
/***/
(module2) => {
module2.exports = "camerafadeinstart";
}
),
/***/
45917: (
/***/
(module2) => {
module2.exports = "camerafadeoutcomplete";
}
),
/***/
95666: (
/***/
(module2) => {
module2.exports = "camerafadeoutstart";
}
),
/***/
47056: (
/***/
(module2) => {
module2.exports = "cameraflashcomplete";
}
),
/***/
91261: (
/***/
(module2) => {
module2.exports = "cameraflashstart";
}
),
/***/
45047: (
/***/
(module2) => {
module2.exports = "followupdate";
}
),
/***/
81927: (
/***/
(module2) => {
module2.exports = "camerapancomplete";
}
),
/***/
74264: (
/***/
(module2) => {
module2.exports = "camerapanstart";
}
),
/***/
54419: (
/***/
(module2) => {
module2.exports = "postrender";
}
),
/***/
79330: (
/***/
(module2) => {
module2.exports = "prerender";
}
),
/***/
93183: (
/***/
(module2) => {
module2.exports = "camerarotatecomplete";
}
),
/***/
80112: (
/***/
(module2) => {
module2.exports = "camerarotatestart";
}
),
/***/
62252: (
/***/
(module2) => {
module2.exports = "camerashakecomplete";
}
),
/***/
86017: (
/***/
(module2) => {
module2.exports = "camerashakestart";
}
),
/***/
539: (
/***/
(module2) => {
module2.exports = "camerazoomcomplete";
}
),
/***/
51892: (
/***/
(module2) => {
module2.exports = "camerazoomstart";
}
),
/***/
19715: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
DESTROY: __webpack_require__2(16438),
FADE_IN_COMPLETE: __webpack_require__2(32726),
FADE_IN_START: __webpack_require__2(87807),
FADE_OUT_COMPLETE: __webpack_require__2(45917),
FADE_OUT_START: __webpack_require__2(95666),
FLASH_COMPLETE: __webpack_require__2(47056),
FLASH_START: __webpack_require__2(91261),
FOLLOW_UPDATE: __webpack_require__2(45047),
PAN_COMPLETE: __webpack_require__2(81927),
PAN_START: __webpack_require__2(74264),
POST_RENDER: __webpack_require__2(54419),
PRE_RENDER: __webpack_require__2(79330),
ROTATE_COMPLETE: __webpack_require__2(93183),
ROTATE_START: __webpack_require__2(80112),
SHAKE_COMPLETE: __webpack_require__2(62252),
SHAKE_START: __webpack_require__2(86017),
ZOOM_COMPLETE: __webpack_require__2(539),
ZOOM_START: __webpack_require__2(51892)
};
}
),
/***/
87969: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Camera: __webpack_require__2(38058),
BaseCamera: __webpack_require__2(71911),
CameraManager: __webpack_require__2(32743),
Effects: __webpack_require__2(20052),
Events: __webpack_require__2(19715)
};
}
),
/***/
63091: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var GetValue = __webpack_require__2(35154);
var FixedKeyControl = new Class({
initialize: function FixedKeyControl2(config) {
this.camera = GetValue(config, "camera", null);
this.left = GetValue(config, "left", null);
this.right = GetValue(config, "right", null);
this.up = GetValue(config, "up", null);
this.down = GetValue(config, "down", null);
this.zoomIn = GetValue(config, "zoomIn", null);
this.zoomOut = GetValue(config, "zoomOut", null);
this.zoomSpeed = GetValue(config, "zoomSpeed", 0.01);
this.minZoom = GetValue(config, "minZoom", 1e-3);
this.maxZoom = GetValue(config, "maxZoom", 1e3);
this.speedX = 0;
this.speedY = 0;
var speed = GetValue(config, "speed", null);
if (typeof speed === "number") {
this.speedX = speed;
this.speedY = speed;
} else {
this.speedX = GetValue(config, "speed.x", 0);
this.speedY = GetValue(config, "speed.y", 0);
}
this._zoom = 0;
this.active = this.camera !== null;
},
/**
* Starts the Key Control running, providing it has been linked to a camera.
*
* @method Phaser.Cameras.Controls.FixedKeyControl#start
* @since 3.0.0
*
* @return {this} This Key Control instance.
*/
start: function() {
this.active = this.camera !== null;
return this;
},
/**
* Stops this Key Control from running. Call `start` to start it again.
*
* @method Phaser.Cameras.Controls.FixedKeyControl#stop
* @since 3.0.0
*
* @return {this} This Key Control instance.
*/
stop: function() {
this.active = false;
return this;
},
/**
* Binds this Key Control to a camera.
*
* @method Phaser.Cameras.Controls.FixedKeyControl#setCamera
* @since 3.0.0
*
* @param {Phaser.Cameras.Scene2D.Camera} camera - The camera to bind this Key Control to.
*
* @return {this} This Key Control instance.
*/
setCamera: function(camera) {
this.camera = camera;
return this;
},
/**
* Applies the results of pressing the control keys to the Camera.
*
* You must call this every step, it is not called automatically.
*
* @method Phaser.Cameras.Controls.FixedKeyControl#update
* @since 3.0.0
*
* @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
*/
update: function(delta) {
if (!this.active) {
return;
}
if (delta === void 0) {
delta = 1;
}
var cam = this.camera;
if (this.up && this.up.isDown) {
cam.scrollY -= this.speedY * delta | 0;
} else if (this.down && this.down.isDown) {
cam.scrollY += this.speedY * delta | 0;
}
if (this.left && this.left.isDown) {
cam.scrollX -= this.speedX * delta | 0;
} else if (this.right && this.right.isDown) {
cam.scrollX += this.speedX * delta | 0;
}
if (this.zoomIn && this.zoomIn.isDown) {
cam.zoom -= this.zoomSpeed;
if (cam.zoom < this.minZoom) {
cam.zoom = this.minZoom;
}
} else if (this.zoomOut && this.zoomOut.isDown) {
cam.zoom += this.zoomSpeed;
if (cam.zoom > this.maxZoom) {
cam.zoom = this.maxZoom;
}
}
},
/**
* Destroys this Key Control.
*
* @method Phaser.Cameras.Controls.FixedKeyControl#destroy
* @since 3.0.0
*/
destroy: function() {
this.camera = null;
this.left = null;
this.right = null;
this.up = null;
this.down = null;
this.zoomIn = null;
this.zoomOut = null;
}
});
module2.exports = FixedKeyControl;
}
),
/***/
58818: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var GetValue = __webpack_require__2(35154);
var SmoothedKeyControl = new Class({
initialize: function SmoothedKeyControl2(config) {
this.camera = GetValue(config, "camera", null);
this.left = GetValue(config, "left", null);
this.right = GetValue(config, "right", null);
this.up = GetValue(config, "up", null);
this.down = GetValue(config, "down", null);
this.zoomIn = GetValue(config, "zoomIn", null);
this.zoomOut = GetValue(config, "zoomOut", null);
this.zoomSpeed = GetValue(config, "zoomSpeed", 0.01);
this.minZoom = GetValue(config, "minZoom", 1e-3);
this.maxZoom = GetValue(config, "maxZoom", 1e3);
this.accelX = 0;
this.accelY = 0;
var accel = GetValue(config, "acceleration", null);
if (typeof accel === "number") {
this.accelX = accel;
this.accelY = accel;
} else {
this.accelX = GetValue(config, "acceleration.x", 0);
this.accelY = GetValue(config, "acceleration.y", 0);
}
this.dragX = 0;
this.dragY = 0;
var drag = GetValue(config, "drag", null);
if (typeof drag === "number") {
this.dragX = drag;
this.dragY = drag;
} else {
this.dragX = GetValue(config, "drag.x", 0);
this.dragY = GetValue(config, "drag.y", 0);
}
this.maxSpeedX = 0;
this.maxSpeedY = 0;
var maxSpeed = GetValue(config, "maxSpeed", null);
if (typeof maxSpeed === "number") {
this.maxSpeedX = maxSpeed;
this.maxSpeedY = maxSpeed;
} else {
this.maxSpeedX = GetValue(config, "maxSpeed.x", 0);
this.maxSpeedY = GetValue(config, "maxSpeed.y", 0);
}
this._speedX = 0;
this._speedY = 0;
this._zoom = 0;
this.active = this.camera !== null;
},
/**
* Starts the Key Control running, providing it has been linked to a camera.
*
* @method Phaser.Cameras.Controls.SmoothedKeyControl#start
* @since 3.0.0
*
* @return {this} This Key Control instance.
*/
start: function() {
this.active = this.camera !== null;
return this;
},
/**
* Stops this Key Control from running. Call `start` to start it again.
*
* @method Phaser.Cameras.Controls.SmoothedKeyControl#stop
* @since 3.0.0
*
* @return {this} This Key Control instance.
*/
stop: function() {
this.active = false;
return this;
},
/**
* Binds this Key Control to a camera.
*
* @method Phaser.Cameras.Controls.SmoothedKeyControl#setCamera
* @since 3.0.0
*
* @param {Phaser.Cameras.Scene2D.Camera} camera - The camera to bind this Key Control to.
*
* @return {this} This Key Control instance.
*/
setCamera: function(camera) {
this.camera = camera;
return this;
},
/**
* Applies the results of pressing the control keys to the Camera.
*
* You must call this every step, it is not called automatically.
*
* @method Phaser.Cameras.Controls.SmoothedKeyControl#update
* @since 3.0.0
*
* @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
*/
update: function(delta) {
if (!this.active) {
return;
}
if (delta === void 0) {
delta = 1;
}
var cam = this.camera;
if (this._speedX > 0) {
this._speedX -= this.dragX * delta;
if (this._speedX < 0) {
this._speedX = 0;
}
} else if (this._speedX < 0) {
this._speedX += this.dragX * delta;
if (this._speedX > 0) {
this._speedX = 0;
}
}
if (this._speedY > 0) {
this._speedY -= this.dragY * delta;
if (this._speedY < 0) {
this._speedY = 0;
}
} else if (this._speedY < 0) {
this._speedY += this.dragY * delta;
if (this._speedY > 0) {
this._speedY = 0;
}
}
if (this.up && this.up.isDown) {
this._speedY += this.accelY;
if (this._speedY > this.maxSpeedY) {
this._speedY = this.maxSpeedY;
}
} else if (this.down && this.down.isDown) {
this._speedY -= this.accelY;
if (this._speedY < -this.maxSpeedY) {
this._speedY = -this.maxSpeedY;
}
}
if (this.left && this.left.isDown) {
this._speedX += this.accelX;
if (this._speedX > this.maxSpeedX) {
this._speedX = this.maxSpeedX;
}
} else if (this.right && this.right.isDown) {
this._speedX -= this.accelX;
if (this._speedX < -this.maxSpeedX) {
this._speedX = -this.maxSpeedX;
}
}
if (this.zoomIn && this.zoomIn.isDown) {
this._zoom = -this.zoomSpeed;
} else if (this.zoomOut && this.zoomOut.isDown) {
this._zoom = this.zoomSpeed;
} else {
this._zoom = 0;
}
if (this._speedX !== 0) {
cam.scrollX -= this._speedX * delta | 0;
}
if (this._speedY !== 0) {
cam.scrollY -= this._speedY * delta | 0;
}
if (this._zoom !== 0) {
cam.zoom += this._zoom;
if (cam.zoom < this.minZoom) {
cam.zoom = this.minZoom;
} else if (cam.zoom > this.maxZoom) {
cam.zoom = this.maxZoom;
}
}
},
/**
* Destroys this Key Control.
*
* @method Phaser.Cameras.Controls.SmoothedKeyControl#destroy
* @since 3.0.0
*/
destroy: function() {
this.camera = null;
this.left = null;
this.right = null;
this.up = null;
this.down = null;
this.zoomIn = null;
this.zoomOut = null;
}
});
module2.exports = SmoothedKeyControl;
}
),
/***/
38865: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
FixedKeyControl: __webpack_require__2(63091),
SmoothedKeyControl: __webpack_require__2(58818)
};
}
),
/***/
26638: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Controls: __webpack_require__2(38865),
Scene2D: __webpack_require__2(87969)
};
}
),
/***/
8054: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = {
/**
* Phaser Release Version
*
* @name Phaser.VERSION
* @const
* @type {string}
* @since 3.0.0
*/
VERSION: "3.86.0",
BlendModes: __webpack_require__2(10312),
ScaleModes: __webpack_require__2(29795),
/**
* This setting will auto-detect if the browser is capable of suppporting WebGL.
* If it is, it will use the WebGL Renderer. If not, it will fall back to the Canvas Renderer.
*
* @name Phaser.AUTO
* @const
* @type {number}
* @since 3.0.0
*/
AUTO: 0,
/**
* Forces Phaser to only use the Canvas Renderer, regardless if the browser supports
* WebGL or not.
*
* @name Phaser.CANVAS
* @const
* @type {number}
* @since 3.0.0
*/
CANVAS: 1,
/**
* Forces Phaser to use the WebGL Renderer. If the browser does not support it, there is
* no fallback to Canvas with this setting, so you should trap it and display a suitable
* message to the user.
*
* @name Phaser.WEBGL
* @const
* @type {number}
* @since 3.0.0
*/
WEBGL: 2,
/**
* A Headless Renderer doesn't create either a Canvas or WebGL Renderer. However, it still
* absolutely relies on the DOM being present and available. This mode is meant for unit testing,
* not for running Phaser on the server, which is something you really shouldn't do.
*
* @name Phaser.HEADLESS
* @const
* @type {number}
* @since 3.0.0
*/
HEADLESS: 3,
/**
* In Phaser the value -1 means 'forever' in lots of cases, this const allows you to use it instead
* to help you remember what the value is doing in your code.
*
* @name Phaser.FOREVER
* @const
* @type {number}
* @since 3.0.0
*/
FOREVER: -1,
/**
* Direction constant.
*
* @name Phaser.NONE
* @const
* @type {number}
* @since 3.0.0
*/
NONE: 4,
/**
* Direction constant.
*
* @name Phaser.UP
* @const
* @type {number}
* @since 3.0.0
*/
UP: 5,
/**
* Direction constant.
*
* @name Phaser.DOWN
* @const
* @type {number}
* @since 3.0.0
*/
DOWN: 6,
/**
* Direction constant.
*
* @name Phaser.LEFT
* @const
* @type {number}
* @since 3.0.0
*/
LEFT: 7,
/**
* Direction constant.
*
* @name Phaser.RIGHT
* @const
* @type {number}
* @since 3.0.0
*/
RIGHT: 8
};
module2.exports = CONST;
}
),
/***/
69547: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(8054);
var DefaultPlugins = __webpack_require__2(42363);
var Device = __webpack_require__2(82264);
var GetFastValue = __webpack_require__2(95540);
var GetValue = __webpack_require__2(35154);
var IsPlainObject = __webpack_require__2(41212);
var NOOP = __webpack_require__2(29747);
var PhaserMath = __webpack_require__2(75508);
var PIPELINE_CONST = __webpack_require__2(36060);
var ValueToColor = __webpack_require__2(80333);
var Config = new Class({
initialize: function Config2(config) {
if (config === void 0) {
config = {};
}
var defaultBannerColor = [
"#ff0000",
"#ffff00",
"#00ff00",
"#00ffff",
"#000000"
];
var defaultBannerTextColor = "#ffffff";
var scaleConfig = GetValue(config, "scale", null);
this.width = GetValue(scaleConfig, "width", 1024, config);
this.height = GetValue(scaleConfig, "height", 768, config);
this.zoom = GetValue(scaleConfig, "zoom", 1, config);
this.parent = GetValue(scaleConfig, "parent", void 0, config);
this.scaleMode = GetValue(scaleConfig, scaleConfig ? "mode" : "scaleMode", 0, config);
this.expandParent = GetValue(scaleConfig, "expandParent", true, config);
this.autoRound = GetValue(scaleConfig, "autoRound", false, config);
this.autoCenter = GetValue(scaleConfig, "autoCenter", 0, config);
this.resizeInterval = GetValue(scaleConfig, "resizeInterval", 500, config);
this.fullscreenTarget = GetValue(scaleConfig, "fullscreenTarget", null, config);
this.minWidth = GetValue(scaleConfig, "min.width", 0, config);
this.maxWidth = GetValue(scaleConfig, "max.width", 0, config);
this.minHeight = GetValue(scaleConfig, "min.height", 0, config);
this.maxHeight = GetValue(scaleConfig, "max.height", 0, config);
this.snapWidth = GetValue(scaleConfig, "snap.width", 0, config);
this.snapHeight = GetValue(scaleConfig, "snap.height", 0, config);
this.renderType = GetValue(config, "type", CONST.AUTO);
this.canvas = GetValue(config, "canvas", null);
this.context = GetValue(config, "context", null);
this.canvasStyle = GetValue(config, "canvasStyle", null);
this.customEnvironment = GetValue(config, "customEnvironment", false);
this.sceneConfig = GetValue(config, "scene", null);
this.seed = GetValue(config, "seed", [(Date.now() * Math.random()).toString()]);
PhaserMath.RND = new PhaserMath.RandomDataGenerator(this.seed);
this.gameTitle = GetValue(config, "title", "");
this.gameURL = GetValue(config, "url", "https://phaser.io/v385/");
this.gameVersion = GetValue(config, "version", "");
this.autoFocus = GetValue(config, "autoFocus", true);
this.stableSort = GetValue(config, "stableSort", -1);
if (this.stableSort === -1) {
this.stableSort = Device.browser.es2019 ? 1 : 0;
}
Device.features.stableSort = this.stableSort;
this.domCreateContainer = GetValue(config, "dom.createContainer", false);
this.domPointerEvents = GetValue(config, "dom.pointerEvents", "none");
this.inputKeyboard = GetValue(config, "input.keyboard", true);
this.inputKeyboardEventTarget = GetValue(config, "input.keyboard.target", window);
this.inputKeyboardCapture = GetValue(config, "input.keyboard.capture", []);
this.inputMouse = GetValue(config, "input.mouse", true);
this.inputMouseEventTarget = GetValue(config, "input.mouse.target", null);
this.inputMousePreventDefaultDown = GetValue(config, "input.mouse.preventDefaultDown", true);
this.inputMousePreventDefaultUp = GetValue(config, "input.mouse.preventDefaultUp", true);
this.inputMousePreventDefaultMove = GetValue(config, "input.mouse.preventDefaultMove", true);
this.inputMousePreventDefaultWheel = GetValue(config, "input.mouse.preventDefaultWheel", true);
this.inputTouch = GetValue(config, "input.touch", Device.input.touch);
this.inputTouchEventTarget = GetValue(config, "input.touch.target", null);
this.inputTouchCapture = GetValue(config, "input.touch.capture", true);
this.inputActivePointers = GetValue(config, "input.activePointers", 1);
this.inputSmoothFactor = GetValue(config, "input.smoothFactor", 0);
this.inputWindowEvents = GetValue(config, "input.windowEvents", true);
this.inputGamepad = GetValue(config, "input.gamepad", false);
this.inputGamepadEventTarget = GetValue(config, "input.gamepad.target", window);
this.disableContextMenu = GetValue(config, "disableContextMenu", false);
this.audio = GetValue(config, "audio", {});
this.hideBanner = GetValue(config, "banner", null) === false;
this.hidePhaser = GetValue(config, "banner.hidePhaser", false);
this.bannerTextColor = GetValue(config, "banner.text", defaultBannerTextColor);
this.bannerBackgroundColor = GetValue(config, "banner.background", defaultBannerColor);
if (this.gameTitle === "" && this.hidePhaser) {
this.hideBanner = true;
}
this.fps = GetValue(config, "fps", null);
this.disablePreFX = GetValue(config, "disablePreFX", false);
this.disablePostFX = GetValue(config, "disablePostFX", false);
var renderConfig = GetValue(config, "render", null);
this.pipeline = GetValue(renderConfig, "pipeline", null, config);
this.autoMobilePipeline = GetValue(renderConfig, "autoMobilePipeline", true, config);
this.defaultPipeline = GetValue(renderConfig, "defaultPipeline", PIPELINE_CONST.MULTI_PIPELINE, config);
this.antialias = GetValue(renderConfig, "antialias", true, config);
this.antialiasGL = GetValue(renderConfig, "antialiasGL", true, config);
this.mipmapFilter = GetValue(renderConfig, "mipmapFilter", "", config);
this.desynchronized = GetValue(renderConfig, "desynchronized", false, config);
this.roundPixels = GetValue(renderConfig, "roundPixels", false, config);
this.pixelArt = GetValue(renderConfig, "pixelArt", this.zoom !== 1, config);
if (this.pixelArt) {
this.antialias = false;
this.antialiasGL = false;
this.roundPixels = true;
}
this.transparent = GetValue(renderConfig, "transparent", false, config);
this.clearBeforeRender = GetValue(renderConfig, "clearBeforeRender", true, config);
this.preserveDrawingBuffer = GetValue(renderConfig, "preserveDrawingBuffer", false, config);
this.premultipliedAlpha = GetValue(renderConfig, "premultipliedAlpha", true, config);
this.failIfMajorPerformanceCaveat = GetValue(renderConfig, "failIfMajorPerformanceCaveat", false, config);
this.powerPreference = GetValue(renderConfig, "powerPreference", "default", config);
this.batchSize = GetValue(renderConfig, "batchSize", 4096, config);
this.maxTextures = GetValue(renderConfig, "maxTextures", -1, config);
this.maxLights = GetValue(renderConfig, "maxLights", 10, config);
var bgc = GetValue(config, "backgroundColor", 0);
this.backgroundColor = ValueToColor(bgc);
if (this.transparent) {
this.backgroundColor = ValueToColor(0);
this.backgroundColor.alpha = 0;
}
this.preBoot = GetValue(config, "callbacks.preBoot", NOOP);
this.postBoot = GetValue(config, "callbacks.postBoot", NOOP);
this.physics = GetValue(config, "physics", {});
this.defaultPhysicsSystem = GetValue(this.physics, "default", false);
this.loaderBaseURL = GetValue(config, "loader.baseURL", "");
this.loaderPath = GetValue(config, "loader.path", "");
this.loaderMaxParallelDownloads = GetValue(config, "loader.maxParallelDownloads", Device.os.android ? 6 : 32);
this.loaderCrossOrigin = GetValue(config, "loader.crossOrigin", void 0);
this.loaderResponseType = GetValue(config, "loader.responseType", "");
this.loaderAsync = GetValue(config, "loader.async", true);
this.loaderUser = GetValue(config, "loader.user", "");
this.loaderPassword = GetValue(config, "loader.password", "");
this.loaderTimeout = GetValue(config, "loader.timeout", 0);
this.loaderMaxRetries = GetValue(config, "loader.maxRetries", 2);
this.loaderWithCredentials = GetValue(config, "loader.withCredentials", false);
this.loaderImageLoadType = GetValue(config, "loader.imageLoadType", "XHR");
this.loaderLocalScheme = GetValue(config, "loader.localScheme", ["file://", "capacitor://"]);
this.glowFXQuality = GetValue(config, "fx.glow.quality", 0.1);
this.glowFXDistance = GetValue(config, "fx.glow.distance", 10);
this.installGlobalPlugins = [];
this.installScenePlugins = [];
var plugins = GetValue(config, "plugins", null);
var defaultPlugins = DefaultPlugins.DefaultScene;
if (plugins) {
if (Array.isArray(plugins)) {
this.defaultPlugins = plugins;
} else if (IsPlainObject(plugins)) {
this.installGlobalPlugins = GetFastValue(plugins, "global", []);
this.installScenePlugins = GetFastValue(plugins, "scene", []);
if (Array.isArray(plugins.default)) {
defaultPlugins = plugins.default;
} else if (Array.isArray(plugins.defaultMerge)) {
defaultPlugins = defaultPlugins.concat(plugins.defaultMerge);
}
}
}
this.defaultPlugins = defaultPlugins;
var pngPrefix = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAg";
this.defaultImage = GetValue(config, "images.default", pngPrefix + "AQMAAABJtOi3AAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAABVJREFUeF7NwIEAAAAAgKD9qdeocAMAoAABm3DkcAAAAABJRU5ErkJggg==");
this.missingImage = GetValue(config, "images.missing", pngPrefix + "CAIAAAD8GO2jAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJ9JREFUeNq01ssOwyAMRFG46v//Mt1ESmgh+DFmE2GPOBARKb2NVjo+17PXLD8a1+pl5+A+wSgFygymWYHBb0FtsKhJDdZlncG2IzJ4ayoMDv20wTmSMzClEgbWYNTAkQ0Z+OJ+A/eWnAaR9+oxCF4Os0H8htsMUp+pwcgBBiMNnAwF8GqIgL2hAzaGFFgZauDPKABmowZ4GL369/0rwACp2yA/ttmvsQAAAABJRU5ErkJggg==");
this.whiteImage = GetValue(config, "images.white", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABdJREFUeNpi/P//PwMMMDEgAdwcgAADAJZuAwXJYZOzAAAAAElFTkSuQmCC");
if (window) {
if (window.FORCE_WEBGL) {
this.renderType = CONST.WEBGL;
} else if (window.FORCE_CANVAS) {
this.renderType = CONST.CANVAS;
}
}
}
});
module2.exports = Config;
}
),
/***/
86054: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CanvasInterpolation = __webpack_require__2(20623);
var CanvasPool = __webpack_require__2(27919);
var CONST = __webpack_require__2(8054);
var Features = __webpack_require__2(89357);
var CreateRenderer = function(game) {
var config = game.config;
if ((config.customEnvironment || config.canvas) && config.renderType === CONST.AUTO) {
throw new Error("Must set explicit renderType in custom environment");
}
if (!config.customEnvironment && !config.canvas && config.renderType !== CONST.HEADLESS) {
if (config.renderType === CONST.AUTO) {
config.renderType = Features.webGL ? CONST.WEBGL : CONST.CANVAS;
}
if (config.renderType === CONST.WEBGL) {
if (!Features.webGL) {
throw new Error("Cannot create WebGL context, aborting.");
}
} else if (config.renderType === CONST.CANVAS) {
if (!Features.canvas) {
throw new Error("Cannot create Canvas context, aborting.");
}
} else {
throw new Error("Unknown value for renderer type: " + config.renderType);
}
}
if (!config.antialias) {
CanvasPool.disableSmoothing();
}
var baseSize = game.scale.baseSize;
var width = baseSize.width;
var height = baseSize.height;
if (config.canvas) {
game.canvas = config.canvas;
game.canvas.width = width;
game.canvas.height = height;
} else {
game.canvas = CanvasPool.create(game, width, height, config.renderType);
}
if (config.canvasStyle) {
game.canvas.style = config.canvasStyle;
}
if (!config.antialias) {
CanvasInterpolation.setCrisp(game.canvas);
}
if (config.renderType === CONST.HEADLESS) {
return;
}
var CanvasRenderer;
var WebGLRenderer;
if (true) {
CanvasRenderer = __webpack_require__2(68627);
WebGLRenderer = __webpack_require__2(74797);
if (config.renderType === CONST.WEBGL) {
game.renderer = new WebGLRenderer(game);
} else {
game.renderer = new CanvasRenderer(game);
game.context = game.renderer.gameContext;
}
}
if (false) {
}
if (false) {
}
};
module2.exports = CreateRenderer;
}
),
/***/
96391: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(8054);
var DebugHeader = function(game) {
var config = game.config;
if (config.hideBanner) {
return;
}
var renderType = "WebGL";
if (config.renderType === CONST.CANVAS) {
renderType = "Canvas";
} else if (config.renderType === CONST.HEADLESS) {
renderType = "Headless";
}
var audioConfig = config.audio;
var deviceAudio = game.device.audio;
var audioType;
if (deviceAudio.webAudio && !audioConfig.disableWebAudio) {
audioType = "Web Audio";
} else if (audioConfig.noAudio || !deviceAudio.webAudio && !deviceAudio.audioData) {
audioType = "No Audio";
} else {
audioType = "HTML5 Audio";
}
if (!game.device.browser.ie) {
var c = "";
var args = [c];
if (Array.isArray(config.bannerBackgroundColor)) {
var lastColor;
config.bannerBackgroundColor.forEach(function(color) {
c = c.concat("%c ");
args.push("background: " + color);
lastColor = color;
});
args[args.length - 1] = "color: " + config.bannerTextColor + "; background: " + lastColor;
} else {
c = c.concat("%c ");
args.push("color: " + config.bannerTextColor + "; background: " + config.bannerBackgroundColor);
}
args.push("background: transparent");
if (config.gameTitle) {
c = c.concat(config.gameTitle);
if (config.gameVersion) {
c = c.concat(" v" + config.gameVersion);
}
if (!config.hidePhaser) {
c = c.concat(" / ");
}
}
var fb = false ? 0 : "";
if (!config.hidePhaser) {
c = c.concat("Phaser v" + CONST.VERSION + fb + " (" + renderType + " | " + audioType + ")");
}
c = c.concat(" %c " + config.gameURL);
args[0] = c;
console.log.apply(console, args);
} else if (window["console"]) {
console.log("Phaser v" + CONST.VERSION + " / https://phaser.io");
}
};
module2.exports = DebugHeader;
}
),
/***/
50127: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var AddToDOM = __webpack_require__2(40366);
var AnimationManager = __webpack_require__2(60848);
var CacheManager = __webpack_require__2(24047);
var CanvasPool = __webpack_require__2(27919);
var Class = __webpack_require__2(83419);
var Config = __webpack_require__2(69547);
var CreateDOMContainer = __webpack_require__2(83719);
var CreateRenderer = __webpack_require__2(86054);
var DataManager = __webpack_require__2(45893);
var DebugHeader = __webpack_require__2(96391);
var Device = __webpack_require__2(82264);
var DOMContentLoaded = __webpack_require__2(57264);
var EventEmitter = __webpack_require__2(50792);
var Events = __webpack_require__2(8443);
var InputManager = __webpack_require__2(7003);
var PluginCache = __webpack_require__2(37277);
var PluginManager = __webpack_require__2(77332);
var ScaleManager = __webpack_require__2(76531);
var SceneManager = __webpack_require__2(60903);
var TextureEvents = __webpack_require__2(69442);
var TextureManager = __webpack_require__2(17130);
var TimeStep = __webpack_require__2(65898);
var VisibilityHandler = __webpack_require__2(51085);
if (true) {
var SoundManagerCreator = __webpack_require__2(14747);
}
if (false) {
var FacebookInstantGamesPlugin;
}
var Game = new Class({
initialize: function Game2(config) {
this.config = new Config(config);
this.renderer = null;
this.domContainer = null;
this.canvas = null;
this.context = null;
this.isBooted = false;
this.isRunning = false;
this.events = new EventEmitter();
this.anims = new AnimationManager(this);
this.textures = new TextureManager(this);
this.cache = new CacheManager(this);
this.registry = new DataManager(this, new EventEmitter());
this.input = new InputManager(this, this.config);
this.scene = new SceneManager(this, this.config.sceneConfig);
this.device = Device;
this.scale = new ScaleManager(this, this.config);
this.sound = null;
if (true) {
this.sound = SoundManagerCreator.create(this);
}
this.loop = new TimeStep(this, this.config.fps);
this.plugins = new PluginManager(this, this.config);
if (false) {
}
this.pendingDestroy = false;
this.removeCanvas = false;
this.noReturn = false;
this.hasFocus = false;
this.isPaused = false;
DOMContentLoaded(this.boot.bind(this));
},
/**
* This method is called automatically when the DOM is ready. It is responsible for creating the renderer,
* displaying the Debug Header, adding the game canvas to the DOM and emitting the 'boot' event.
* It listens for a 'ready' event from the base systems and once received it will call `Game.start`.
*
* @method Phaser.Game#boot
* @protected
* @fires Phaser.Core.Events#BOOT
* @listens Phaser.Textures.Events#READY
* @since 3.0.0
*/
boot: function() {
if (!PluginCache.hasCore("EventEmitter")) {
console.warn("Aborting. Core Plugins missing.");
return;
}
this.isBooted = true;
this.config.preBoot(this);
this.scale.preBoot();
CreateRenderer(this);
CreateDOMContainer(this);
DebugHeader(this);
AddToDOM(this.canvas, this.config.parent);
this.textures.once(TextureEvents.READY, this.texturesReady, this);
this.events.emit(Events.BOOT);
if (false) {
}
},
/**
* Called automatically when the Texture Manager has finished setting up and preparing the
* default textures.
*
* @method Phaser.Game#texturesReady
* @private
* @fires Phaser.Game#READY
* @since 3.12.0
*/
texturesReady: function() {
this.events.emit(Events.READY);
this.start();
},
/**
* Called automatically by Game.boot once all of the global systems have finished setting themselves up.
* By this point the Game is now ready to start the main loop running.
* It will also enable the Visibility Handler.
*
* @method Phaser.Game#start
* @protected
* @since 3.0.0
*/
start: function() {
this.isRunning = true;
this.config.postBoot(this);
if (this.renderer) {
this.loop.start(this.step.bind(this));
} else {
this.loop.start(this.headlessStep.bind(this));
}
VisibilityHandler(this);
var eventEmitter = this.events;
eventEmitter.on(Events.HIDDEN, this.onHidden, this);
eventEmitter.on(Events.VISIBLE, this.onVisible, this);
eventEmitter.on(Events.BLUR, this.onBlur, this);
eventEmitter.on(Events.FOCUS, this.onFocus, this);
},
/**
* The main Game Step. Called automatically by the Time Step, once per browser frame (typically as a result of
* Request Animation Frame, or Set Timeout on very old browsers.)
*
* The step will update the global managers first, then proceed to update each Scene in turn, via the Scene Manager.
*
* It will then render each Scene in turn, via the Renderer. This process emits `prerender` and `postrender` events.
*
* @method Phaser.Game#step
* @fires Phaser.Core.Events#PRE_STEP
* @fires Phaser.Core.Events#STEP
* @fires Phaser.Core.Events#POST_STEP
* @fires Phaser.Core.Events#PRE_RENDER
* @fires Phaser.Core.Events#POST_RENDER
* @since 3.0.0
*
* @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout.
* @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
*/
step: function(time, delta) {
if (this.pendingDestroy) {
return this.runDestroy();
}
if (this.isPaused) {
return;
}
var eventEmitter = this.events;
eventEmitter.emit(Events.PRE_STEP, time, delta);
eventEmitter.emit(Events.STEP, time, delta);
this.scene.update(time, delta);
eventEmitter.emit(Events.POST_STEP, time, delta);
var renderer = this.renderer;
renderer.preRender();
eventEmitter.emit(Events.PRE_RENDER, renderer, time, delta);
this.scene.render(renderer);
renderer.postRender();
eventEmitter.emit(Events.POST_RENDER, renderer, time, delta);
},
/**
* A special version of the Game Step for the HEADLESS renderer only.
*
* The main Game Step. Called automatically by the Time Step, once per browser frame (typically as a result of
* Request Animation Frame, or Set Timeout on very old browsers.)
*
* The step will update the global managers first, then proceed to update each Scene in turn, via the Scene Manager.
*
* This process emits `prerender` and `postrender` events, even though nothing actually displays.
*
* @method Phaser.Game#headlessStep
* @fires Phaser.Game#PRE_RENDER
* @fires Phaser.Game#POST_RENDER
* @since 3.2.0
*
* @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout.
* @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
*/
headlessStep: function(time, delta) {
if (this.pendingDestroy) {
return this.runDestroy();
}
if (this.isPaused) {
return;
}
var eventEmitter = this.events;
eventEmitter.emit(Events.PRE_STEP, time, delta);
eventEmitter.emit(Events.STEP, time, delta);
this.scene.update(time, delta);
eventEmitter.emit(Events.POST_STEP, time, delta);
this.scene.isProcessing = false;
eventEmitter.emit(Events.PRE_RENDER, null, time, delta);
eventEmitter.emit(Events.POST_RENDER, null, time, delta);
},
/**
* Called automatically by the Visibility Handler.
* This will pause the main loop and then emit a pause event.
*
* @method Phaser.Game#onHidden
* @protected
* @fires Phaser.Core.Events#PAUSE
* @since 3.0.0
*/
onHidden: function() {
this.loop.pause();
this.events.emit(Events.PAUSE);
},
/**
* This will pause the entire game and emit a `PAUSE` event.
*
* All of Phaser's internal systems will be paused and the game will not re-render.
*
* Note that it does not pause any Loader requests that are currently in-flight.
*
* @method Phaser.Game#pause
* @fires Phaser.Core.Events#PAUSE
* @since 3.60.0
*/
pause: function() {
var wasPaused = this.isPaused;
this.isPaused = true;
if (!wasPaused) {
this.events.emit(Events.PAUSE);
}
},
/**
* Called automatically by the Visibility Handler.
* This will resume the main loop and then emit a resume event.
*
* @method Phaser.Game#onVisible
* @protected
* @fires Phaser.Core.Events#RESUME
* @since 3.0.0
*/
onVisible: function() {
this.loop.resume();
this.events.emit(Events.RESUME, this.loop.pauseDuration);
},
/**
* This will resume the entire game and emit a `RESUME` event.
*
* All of Phaser's internal systems will be resumed and the game will start rendering again.
*
* @method Phaser.Game#resume
* @fires Phaser.Core.Events#RESUME
* @since 3.60.0
*/
resume: function() {
var wasPaused = this.isPaused;
this.isPaused = false;
if (wasPaused) {
this.events.emit(Events.RESUME, 0);
}
},
/**
* Called automatically by the Visibility Handler.
* This will set the main loop into a 'blurred' state, which pauses it.
*
* @method Phaser.Game#onBlur
* @protected
* @since 3.0.0
*/
onBlur: function() {
this.hasFocus = false;
this.loop.blur();
},
/**
* Called automatically by the Visibility Handler.
* This will set the main loop into a 'focused' state, which resumes it.
*
* @method Phaser.Game#onFocus
* @protected
* @since 3.0.0
*/
onFocus: function() {
this.hasFocus = true;
this.loop.focus();
},
/**
* Returns the current game frame.
*
* When the game starts running, the frame is incremented every time Request Animation Frame, or Set Timeout, fires.
*
* @method Phaser.Game#getFrame
* @since 3.16.0
*
* @return {number} The current game frame.
*/
getFrame: function() {
return this.loop.frame;
},
/**
* Returns the time that the current game step started at, as based on `performance.now`.
*
* @method Phaser.Game#getTime
* @since 3.16.0
*
* @return {number} The current game timestamp.
*/
getTime: function() {
return this.loop.now;
},
/**
* Flags this Game instance as needing to be destroyed on the _next frame_, making this an asynchronous operation.
*
* It will wait until the current frame has completed and then call `runDestroy` internally.
*
* If you need to react to the games eventual destruction, listen for the `DESTROY` event.
*
* If you **do not** need to run Phaser again on the same web page you can set the `noReturn` argument to `true` and it will free-up
* memory being held by the core Phaser plugins. If you do need to create another game instance on the same page, leave this as `false`.
*
* @method Phaser.Game#destroy
* @fires Phaser.Core.Events#DESTROY
* @since 3.0.0
*
* @param {boolean} removeCanvas - Set to `true` if you would like the parent canvas element removed from the DOM, or `false` to leave it in place.
* @param {boolean} [noReturn=false] - If `true` all the core Phaser plugins are destroyed. You cannot create another instance of Phaser on the same web page if you do this.
*/
destroy: function(removeCanvas, noReturn) {
if (noReturn === void 0) {
noReturn = false;
}
this.pendingDestroy = true;
this.removeCanvas = removeCanvas;
this.noReturn = noReturn;
},
/**
* Destroys this Phaser.Game instance, all global systems, all sub-systems and all Scenes.
*
* @method Phaser.Game#runDestroy
* @private
* @since 3.5.0
*/
runDestroy: function() {
this.scene.destroy();
this.events.emit(Events.DESTROY);
this.events.removeAllListeners();
if (this.renderer) {
this.renderer.destroy();
}
if (this.removeCanvas && this.canvas) {
CanvasPool.remove(this.canvas);
if (this.canvas.parentNode) {
this.canvas.parentNode.removeChild(this.canvas);
}
}
if (this.domContainer && this.domContainer.parentNode) {
this.domContainer.parentNode.removeChild(this.domContainer);
}
this.loop.destroy();
this.pendingDestroy = false;
}
});
module2.exports = Game;
}
),
/***/
65898: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var GetValue = __webpack_require__2(35154);
var NOOP = __webpack_require__2(29747);
var RequestAnimationFrame = __webpack_require__2(43092);
var TimeStep = new Class({
initialize: function TimeStep2(game, config) {
this.game = game;
this.raf = new RequestAnimationFrame();
this.started = false;
this.running = false;
this.minFps = GetValue(config, "min", 5);
this.targetFps = GetValue(config, "target", 60);
this.fpsLimit = GetValue(config, "limit", 0);
this.hasFpsLimit = this.fpsLimit > 0;
this._limitRate = this.hasFpsLimit ? 1e3 / this.fpsLimit : 0;
this._min = 1e3 / this.minFps;
this._target = 1e3 / this.targetFps;
this.actualFps = this.targetFps;
this.nextFpsUpdate = 0;
this.framesThisSecond = 0;
this.callback = NOOP;
this.forceSetTimeOut = GetValue(config, "forceSetTimeOut", false);
this.time = 0;
this.startTime = 0;
this.lastTime = 0;
this.frame = 0;
this.inFocus = true;
this.pauseDuration = 0;
this._pauseTime = 0;
this._coolDown = 0;
this.delta = 0;
this.deltaIndex = 0;
this.deltaHistory = [];
this.deltaSmoothingMax = GetValue(config, "deltaHistory", 10);
this.panicMax = GetValue(config, "panicMax", 120);
this.rawDelta = 0;
this.now = 0;
this.smoothStep = GetValue(config, "smoothStep", true);
},
/**
* Called by the Game instance when the DOM window.onBlur event triggers.
*
* @method Phaser.Core.TimeStep#blur
* @since 3.0.0
*/
blur: function() {
this.inFocus = false;
},
/**
* Called by the Game instance when the DOM window.onFocus event triggers.
*
* @method Phaser.Core.TimeStep#focus
* @since 3.0.0
*/
focus: function() {
this.inFocus = true;
this.resetDelta();
},
/**
* Called when the visibility API says the game is 'hidden' (tab switch out of view, etc)
*
* @method Phaser.Core.TimeStep#pause
* @since 3.0.0
*/
pause: function() {
this._pauseTime = window.performance.now();
},
/**
* Called when the visibility API says the game is 'visible' again (tab switch back into view, etc)
*
* @method Phaser.Core.TimeStep#resume
* @since 3.0.0
*/
resume: function() {
this.resetDelta();
this.pauseDuration = this.time - this._pauseTime;
this.startTime += this.pauseDuration;
},
/**
* Resets the time, lastTime, fps averages and delta history.
* Called automatically when a browser sleeps them resumes.
*
* @method Phaser.Core.TimeStep#resetDelta
* @since 3.0.0
*/
resetDelta: function() {
var now = window.performance.now();
this.time = now;
this.lastTime = now;
this.nextFpsUpdate = now + 1e3;
this.framesThisSecond = 0;
for (var i = 0; i < this.deltaSmoothingMax; i++) {
this.deltaHistory[i] = Math.min(this._target, this.deltaHistory[i]);
}
this.delta = 0;
this.deltaIndex = 0;
this._coolDown = this.panicMax;
},
/**
* Starts the Time Step running, if it is not already doing so.
* Called automatically by the Game Boot process.
*
* @method Phaser.Core.TimeStep#start
* @since 3.0.0
*
* @param {Phaser.Types.Core.TimeStepCallback} callback - The callback to be invoked each time the Time Step steps.
*/
start: function(callback) {
if (this.started) {
return this;
}
this.started = true;
this.running = true;
for (var i = 0; i < this.deltaSmoothingMax; i++) {
this.deltaHistory[i] = this._target;
}
this.resetDelta();
this.startTime = window.performance.now();
this.callback = callback;
var step = this.hasFpsLimit ? this.stepLimitFPS.bind(this) : this.step.bind(this);
this.raf.start(step, this.forceSetTimeOut, this._target);
},
/**
* Takes the delta value and smooths it based on the previous frames.
*
* Called automatically as part of the step.
*
* @method Phaser.Core.TimeStep#smoothDelta
* @since 3.60.0
*
* @param {number} delta - The delta value for this step.
*
* @return {number} The smoothed delta value.
*/
smoothDelta: function(delta) {
var idx = this.deltaIndex;
var history = this.deltaHistory;
var max = this.deltaSmoothingMax;
if (this._coolDown > 0 || !this.inFocus) {
this._coolDown--;
delta = Math.min(delta, this._target);
}
if (delta > this._min) {
delta = history[idx];
delta = Math.min(delta, this._min);
}
history[idx] = delta;
this.deltaIndex++;
if (this.deltaIndex >= max) {
this.deltaIndex = 0;
}
var avg = 0;
for (var i = 0; i < max; i++) {
avg += history[i];
}
avg /= max;
return avg;
},
/**
* Update the estimate of the frame rate, `fps`. Every second, the number
* of frames that occurred in that second are included in an exponential
* moving average of all frames per second, with an alpha of 0.25. This
* means that more recent seconds affect the estimated frame rate more than
* older seconds.
*
* When a browser window is NOT minimized, but is covered up (i.e. you're using
* another app which has spawned a window over the top of the browser), then it
* will start to throttle the raf callback time. It waits for a while, and then
* starts to drop the frame rate at 1 frame per second until it's down to just over 1fps.
* So if the game was running at 60fps, and the player opens a new window, then
* after 60 seconds (+ the 'buffer time') it'll be down to 1fps, so rafin'g at 1Hz.
*
* When they make the game visible again, the frame rate is increased at a rate of
* approx. 8fps, back up to 60fps (or the max it can obtain)
*
* There is no easy way to determine if this drop in frame rate is because the
* browser is throttling raf, or because the game is struggling with performance
* because you're asking it to do too much on the device.
*
* Compute the new exponential moving average with an alpha of 0.25.
*
* @method Phaser.Core.TimeStep#updateFPS
* @since 3.60.0
*
* @param {number} time - The timestamp passed in from RequestAnimationFrame or setTimeout.
*/
updateFPS: function(time) {
this.actualFps = 0.25 * this.framesThisSecond + 0.75 * this.actualFps;
this.nextFpsUpdate = time + 1e3;
this.framesThisSecond = 0;
},
/**
* The main step method with an fps limiter. This is called each time the browser updates, either by Request Animation Frame,
* or by Set Timeout. It is responsible for calculating the delta values, frame totals, cool down history and more.
* You generally should never call this method directly.
*
* @method Phaser.Core.TimeStep#stepLimitFPS
* @since 3.60.0
*
* @param {number} time - The timestamp passed in from RequestAnimationFrame or setTimeout.
*/
stepLimitFPS: function(time) {
this.now = time;
var delta = Math.max(0, time - this.lastTime);
this.rawDelta = delta;
this.time += this.rawDelta;
if (this.smoothStep) {
delta = this.smoothDelta(delta);
}
this.delta += delta;
if (time >= this.nextFpsUpdate) {
this.updateFPS(time);
}
this.framesThisSecond++;
if (this.delta >= this._limitRate) {
this.callback(time, this.delta);
this.delta = 0;
}
this.lastTime = time;
this.frame++;
},
/**
* The main step method. This is called each time the browser updates, either by Request Animation Frame,
* or by Set Timeout. It is responsible for calculating the delta values, frame totals, cool down history and more.
* You generally should never call this method directly.
*
* @method Phaser.Core.TimeStep#step
* @since 3.0.0
*
* @param {number} time - The timestamp passed in from RequestAnimationFrame or setTimeout.
*/
step: function(time) {
this.now = time;
var delta = Math.max(0, time - this.lastTime);
this.rawDelta = delta;
this.time += this.rawDelta;
if (this.smoothStep) {
delta = this.smoothDelta(delta);
}
this.delta = delta;
if (time >= this.nextFpsUpdate) {
this.updateFPS(time);
}
this.framesThisSecond++;
this.callback(time, delta);
this.lastTime = time;
this.frame++;
},
/**
* Manually calls `TimeStep.step`.
*
* @method Phaser.Core.TimeStep#tick
* @since 3.0.0
*/
tick: function() {
var now = window.performance.now();
if (this.hasFpsLimit) {
this.stepLimitFPS(now);
} else {
this.step(now);
}
},
/**
* Sends the TimeStep to sleep, stopping Request Animation Frame (or SetTimeout) and toggling the `running` flag to false.
*
* @method Phaser.Core.TimeStep#sleep
* @since 3.0.0
*/
sleep: function() {
if (this.running) {
this.raf.stop();
this.running = false;
}
},
/**
* Wakes-up the TimeStep, restarting Request Animation Frame (or SetTimeout) and toggling the `running` flag to true.
* The `seamless` argument controls if the wake-up should adjust the start time or not.
*
* @method Phaser.Core.TimeStep#wake
* @since 3.0.0
*
* @param {boolean} [seamless=false] - Adjust the startTime based on the lastTime values.
*/
wake: function(seamless) {
if (seamless === void 0) {
seamless = false;
}
var now = window.performance.now();
if (this.running) {
return;
} else if (seamless) {
this.startTime += -this.lastTime + (this.lastTime + now);
}
var step = this.hasFpsLimit ? this.stepLimitFPS.bind(this) : this.step.bind(this);
this.raf.start(step, this.forceSetTimeOut, this._target);
this.running = true;
this.nextFpsUpdate = now + 1e3;
this.framesThisSecond = 0;
this.fpsLimitTriggered = false;
this.tick();
},
/**
* Gets the duration which the game has been running, in seconds.
*
* @method Phaser.Core.TimeStep#getDuration
* @since 3.17.0
*
* @return {number} The duration in seconds.
*/
getDuration: function() {
return Math.round(this.lastTime - this.startTime) / 1e3;
},
/**
* Gets the duration which the game has been running, in ms.
*
* @method Phaser.Core.TimeStep#getDurationMS
* @since 3.17.0
*
* @return {number} The duration in ms.
*/
getDurationMS: function() {
return Math.round(this.lastTime - this.startTime);
},
/**
* Stops the TimeStep running.
*
* @method Phaser.Core.TimeStep#stop
* @since 3.0.0
*
* @return {this} The TimeStep object.
*/
stop: function() {
this.running = false;
this.started = false;
this.raf.stop();
return this;
},
/**
* Destroys the TimeStep. This will stop Request Animation Frame, stop the step, clear the callbacks and null
* any objects.
*
* @method Phaser.Core.TimeStep#destroy
* @since 3.0.0
*/
destroy: function() {
this.stop();
this.raf.destroy();
this.raf = null;
this.game = null;
this.callback = null;
}
});
module2.exports = TimeStep;
}
),
/***/
51085: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Events = __webpack_require__2(8443);
var VisibilityHandler = function(game) {
var hiddenVar;
var eventEmitter = game.events;
if (document.hidden !== void 0) {
hiddenVar = "visibilitychange";
} else {
var vendors = ["webkit", "moz", "ms"];
vendors.forEach(function(prefix) {
if (document[prefix + "Hidden"] !== void 0) {
document.hidden = function() {
return document[prefix + "Hidden"];
};
hiddenVar = prefix + "visibilitychange";
}
});
}
var onChange = function(event) {
if (document.hidden || event.type === "pause") {
eventEmitter.emit(Events.HIDDEN);
} else {
eventEmitter.emit(Events.VISIBLE);
}
};
if (hiddenVar) {
document.addEventListener(hiddenVar, onChange, false);
}
window.onblur = function() {
eventEmitter.emit(Events.BLUR);
};
window.onfocus = function() {
eventEmitter.emit(Events.FOCUS);
};
if (window.focus && game.config.autoFocus) {
window.focus();
}
};
module2.exports = VisibilityHandler;
}
),
/***/
97217: (
/***/
(module2) => {
module2.exports = "blur";
}
),
/***/
47548: (
/***/
(module2) => {
module2.exports = "boot";
}
),
/***/
19814: (
/***/
(module2) => {
module2.exports = "contextlost";
}
),
/***/
68446: (
/***/
(module2) => {
module2.exports = "destroy";
}
),
/***/
41700: (
/***/
(module2) => {
module2.exports = "focus";
}
),
/***/
25432: (
/***/
(module2) => {
module2.exports = "hidden";
}
),
/***/
65942: (
/***/
(module2) => {
module2.exports = "pause";
}
),
/***/
59211: (
/***/
(module2) => {
module2.exports = "postrender";
}
),
/***/
47789: (
/***/
(module2) => {
module2.exports = "poststep";
}
),
/***/
39066: (
/***/
(module2) => {
module2.exports = "prerender";
}
),
/***/
460: (
/***/
(module2) => {
module2.exports = "prestep";
}
),
/***/
16175: (
/***/
(module2) => {
module2.exports = "ready";
}
),
/***/
42331: (
/***/
(module2) => {
module2.exports = "resume";
}
),
/***/
11966: (
/***/
(module2) => {
module2.exports = "step";
}
),
/***/
32969: (
/***/
(module2) => {
module2.exports = "systemready";
}
),
/***/
94830: (
/***/
(module2) => {
module2.exports = "visible";
}
),
/***/
8443: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
BLUR: __webpack_require__2(97217),
BOOT: __webpack_require__2(47548),
CONTEXT_LOST: __webpack_require__2(19814),
DESTROY: __webpack_require__2(68446),
FOCUS: __webpack_require__2(41700),
HIDDEN: __webpack_require__2(25432),
PAUSE: __webpack_require__2(65942),
POST_RENDER: __webpack_require__2(59211),
POST_STEP: __webpack_require__2(47789),
PRE_RENDER: __webpack_require__2(39066),
PRE_STEP: __webpack_require__2(460),
READY: __webpack_require__2(16175),
RESUME: __webpack_require__2(42331),
STEP: __webpack_require__2(11966),
SYSTEM_READY: __webpack_require__2(32969),
VISIBLE: __webpack_require__2(94830)
};
}
),
/***/
42857: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Config: __webpack_require__2(69547),
CreateRenderer: __webpack_require__2(86054),
DebugHeader: __webpack_require__2(96391),
Events: __webpack_require__2(8443),
TimeStep: __webpack_require__2(65898),
VisibilityHandler: __webpack_require__2(51085)
};
}
),
/***/
99584: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Arne16 = __webpack_require__2(5290);
var CanvasPool = __webpack_require__2(27919);
var GetValue = __webpack_require__2(35154);
var GenerateTexture = function(config) {
var data = GetValue(config, "data", []);
var canvas = GetValue(config, "canvas", null);
var palette = GetValue(config, "palette", Arne16);
var pixelWidth = GetValue(config, "pixelWidth", 1);
var pixelHeight = GetValue(config, "pixelHeight", pixelWidth);
var resizeCanvas = GetValue(config, "resizeCanvas", true);
var clearCanvas = GetValue(config, "clearCanvas", true);
var preRender = GetValue(config, "preRender", null);
var postRender = GetValue(config, "postRender", null);
var width = Math.floor(Math.abs(data[0].length * pixelWidth));
var height = Math.floor(Math.abs(data.length * pixelHeight));
if (!canvas) {
canvas = CanvasPool.create2D(this, width, height);
resizeCanvas = false;
clearCanvas = false;
}
if (resizeCanvas) {
canvas.width = width;
canvas.height = height;
}
var ctx = canvas.getContext("2d", { willReadFrequently: true });
if (clearCanvas) {
ctx.clearRect(0, 0, width, height);
}
if (preRender) {
preRender(canvas, ctx);
}
for (var y = 0; y < data.length; y++) {
var row = data[y];
for (var x = 0; x < row.length; x++) {
var d = row[x];
if (d !== "." && d !== " ") {
ctx.fillStyle = palette[d];
ctx.fillRect(x * pixelWidth, y * pixelHeight, pixelWidth, pixelHeight);
}
}
}
if (postRender) {
postRender(canvas, ctx);
}
return canvas;
};
module2.exports = GenerateTexture;
}
),
/***/
15822: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
GenerateTexture: __webpack_require__2(99584),
Palettes: __webpack_require__2(57763)
};
}
),
/***/
5290: (
/***/
(module2) => {
module2.exports = {
0: "#000",
1: "#9D9D9D",
2: "#FFF",
3: "#BE2633",
4: "#E06F8B",
5: "#493C2B",
6: "#A46422",
7: "#EB8931",
8: "#F7E26B",
9: "#2F484E",
A: "#44891A",
B: "#A3CE27",
C: "#1B2632",
D: "#005784",
E: "#31A2F2",
F: "#B2DCEF"
};
}
),
/***/
23816: (
/***/
(module2) => {
module2.exports = {
0: "#000",
1: "#fff",
2: "#8b4131",
3: "#7bbdc5",
4: "#8b41ac",
5: "#6aac41",
6: "#3931a4",
7: "#d5de73",
8: "#945a20",
9: "#5a4100",
A: "#bd736a",
B: "#525252",
C: "#838383",
D: "#acee8b",
E: "#7b73de",
F: "#acacac"
};
}
),
/***/
9866: (
/***/
(module2) => {
module2.exports = {
0: "#000",
1: "#2234d1",
2: "#0c7e45",
3: "#44aacc",
4: "#8a3622",
5: "#5c2e78",
6: "#aa5c3d",
7: "#b5b5b5",
8: "#5e606e",
9: "#4c81fb",
A: "#6cd947",
B: "#7be2f9",
C: "#eb8a60",
D: "#e23d69",
E: "#ffd93f",
F: "#fff"
};
}
),
/***/
77552: (
/***/
(module2) => {
module2.exports = {
0: "#000",
1: "#191028",
2: "#46af45",
3: "#a1d685",
4: "#453e78",
5: "#7664fe",
6: "#833129",
7: "#9ec2e8",
8: "#dc534b",
9: "#e18d79",
A: "#d6b97b",
B: "#e9d8a1",
C: "#216c4b",
D: "#d365c8",
E: "#afaab9",
F: "#f5f4eb"
};
}
),
/***/
92259: (
/***/
(module2) => {
module2.exports = {
0: "#000",
1: "#191028",
2: "#46af45",
3: "#a1d685",
4: "#453e78",
5: "#7664fe",
6: "#833129",
7: "#9ec2e8",
8: "#dc534b",
9: "#e18d79",
A: "#d6b97b",
B: "#e9d8a1",
C: "#216c4b",
D: "#d365c8",
E: "#afaab9",
F: "#fff"
};
}
),
/***/
57763: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
ARNE16: __webpack_require__2(5290),
C64: __webpack_require__2(23816),
CGA: __webpack_require__2(9866),
JMP: __webpack_require__2(77552),
MSX: __webpack_require__2(92259)
};
}
),
/***/
46728: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CubicBezier = __webpack_require__2(36316);
var Curve = __webpack_require__2(80021);
var Vector2 = __webpack_require__2(26099);
var CubicBezierCurve = new Class({
Extends: Curve,
initialize: function CubicBezierCurve2(p0, p1, p2, p3) {
Curve.call(this, "CubicBezierCurve");
if (Array.isArray(p0)) {
p3 = new Vector2(p0[6], p0[7]);
p2 = new Vector2(p0[4], p0[5]);
p1 = new Vector2(p0[2], p0[3]);
p0 = new Vector2(p0[0], p0[1]);
}
this.p0 = p0;
this.p1 = p1;
this.p2 = p2;
this.p3 = p3;
},
/**
* Gets the starting point on the curve.
*
* @method Phaser.Curves.CubicBezier#getStartPoint
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created.
*
* @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned.
*/
getStartPoint: function(out) {
if (out === void 0) {
out = new Vector2();
}
return out.copy(this.p0);
},
/**
* Returns the resolution of this curve.
*
* @method Phaser.Curves.CubicBezier#getResolution
* @since 3.0.0
*
* @param {number} divisions - The amount of divisions used by this curve.
*
* @return {number} The resolution of the curve.
*/
getResolution: function(divisions) {
return divisions;
},
/**
* Get point at relative position in curve according to length.
*
* @method Phaser.Curves.CubicBezier#getPoint
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end.
* @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created.
*
* @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned.
*/
getPoint: function(t, out) {
if (out === void 0) {
out = new Vector2();
}
var p0 = this.p0;
var p1 = this.p1;
var p2 = this.p2;
var p3 = this.p3;
return out.set(CubicBezier(t, p0.x, p1.x, p2.x, p3.x), CubicBezier(t, p0.y, p1.y, p2.y, p3.y));
},
/**
* Draws this curve to the specified graphics object.
*
* @method Phaser.Curves.CubicBezier#draw
* @since 3.0.0
*
* @generic {Phaser.GameObjects.Graphics} G - [graphics,$return]
*
* @param {Phaser.GameObjects.Graphics} graphics - The graphics object this curve should be drawn to.
* @param {number} [pointsTotal=32] - The number of intermediary points that make up this curve. A higher number of points will result in a smoother curve.
*
* @return {Phaser.GameObjects.Graphics} The graphics object this curve was drawn to. Useful for method chaining.
*/
draw: function(graphics, pointsTotal) {
if (pointsTotal === void 0) {
pointsTotal = 32;
}
var points = this.getPoints(pointsTotal);
graphics.beginPath();
graphics.moveTo(this.p0.x, this.p0.y);
for (var i = 1; i < points.length; i++) {
graphics.lineTo(points[i].x, points[i].y);
}
graphics.strokePath();
return graphics;
},
/**
* Returns a JSON object that describes this curve.
*
* @method Phaser.Curves.CubicBezier#toJSON
* @since 3.0.0
*
* @return {Phaser.Types.Curves.JSONCurve} The JSON object containing this curve data.
*/
toJSON: function() {
return {
type: this.type,
points: [
this.p0.x,
this.p0.y,
this.p1.x,
this.p1.y,
this.p2.x,
this.p2.y,
this.p3.x,
this.p3.y
]
};
}
});
CubicBezierCurve.fromJSON = function(data) {
var points = data.points;
var p0 = new Vector2(points[0], points[1]);
var p1 = new Vector2(points[2], points[3]);
var p2 = new Vector2(points[4], points[5]);
var p3 = new Vector2(points[6], points[7]);
return new CubicBezierCurve(p0, p1, p2, p3);
};
module2.exports = CubicBezierCurve;
}
),
/***/
80021: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var FromPoints = __webpack_require__2(19217);
var Rectangle = __webpack_require__2(87841);
var Vector2 = __webpack_require__2(26099);
var Curve = new Class({
initialize: function Curve2(type) {
this.type = type;
this.defaultDivisions = 5;
this.arcLengthDivisions = 100;
this.cacheArcLengths = [];
this.needsUpdate = true;
this.active = true;
this._tmpVec2A = new Vector2();
this._tmpVec2B = new Vector2();
},
/**
* Draws this curve on the given Graphics object.
*
* The curve is drawn using `Graphics.strokePoints` so will be drawn at whatever the present Graphics stroke color is.
* The Graphics object is not cleared before the draw, so the curve will appear on-top of anything else already rendered to it.
*
* @method Phaser.Curves.Curve#draw
* @since 3.0.0
*
* @generic {Phaser.GameObjects.Graphics} G - [graphics,$return]
*
* @param {Phaser.GameObjects.Graphics} graphics - The Graphics instance onto which this curve will be drawn.
* @param {number} [pointsTotal=32] - The resolution of the curve. The higher the value the smoother it will render, at the cost of rendering performance.
*
* @return {Phaser.GameObjects.Graphics} The Graphics object to which the curve was drawn.
*/
draw: function(graphics, pointsTotal) {
if (pointsTotal === void 0) {
pointsTotal = 32;
}
return graphics.strokePoints(this.getPoints(pointsTotal));
},
/**
* Returns a Rectangle where the position and dimensions match the bounds of this Curve.
*
* You can control the accuracy of the bounds. The value given is used to work out how many points
* to plot across the curve. Higher values are more accurate at the cost of calculation speed.
*
* @method Phaser.Curves.Curve#getBounds
* @since 3.0.0
*
* @param {Phaser.Geom.Rectangle} [out] - The Rectangle to store the bounds in. If falsey a new object will be created.
* @param {number} [accuracy=16] - The accuracy of the bounds calculations.
*
* @return {Phaser.Geom.Rectangle} A Rectangle object holding the bounds of this curve. If `out` was given it will be this object.
*/
getBounds: function(out, accuracy) {
if (!out) {
out = new Rectangle();
}
if (accuracy === void 0) {
accuracy = 16;
}
var len = this.getLength();
if (accuracy > len) {
accuracy = len / 2;
}
var spaced = Math.max(1, Math.round(len / accuracy));
return FromPoints(this.getSpacedPoints(spaced), out);
},
/**
* Returns an array of points, spaced out X distance pixels apart.
* The smaller the distance, the larger the array will be.
*
* @method Phaser.Curves.Curve#getDistancePoints
* @since 3.0.0
*
* @param {number} distance - The distance, in pixels, between each point along the curve.
*
* @return {Phaser.Geom.Point[]} An Array of Point objects.
*/
getDistancePoints: function(distance) {
var len = this.getLength();
var spaced = Math.max(1, len / distance);
return this.getSpacedPoints(spaced);
},
/**
* Get a point at the end of the curve.
*
* @method Phaser.Curves.Curve#getEndPoint
* @since 3.0.0
*
* @param {Phaser.Math.Vector2} [out] - Optional Vector object to store the result in.
*
* @return {Phaser.Math.Vector2} Vector2 containing the coordinates of the curves end point.
*/
getEndPoint: function(out) {
if (out === void 0) {
out = new Vector2();
}
return this.getPointAt(1, out);
},
/**
* Get total curve arc length
*
* @method Phaser.Curves.Curve#getLength
* @since 3.0.0
*
* @return {number} The total length of the curve.
*/
getLength: function() {
var lengths = this.getLengths();
return lengths[lengths.length - 1];
},
/**
* Get a list of cumulative segment lengths.
*
* These lengths are
*
* - [0] 0
* - [1] The first segment
* - [2] The first and second segment
* - ...
* - [divisions] All segments
*
* @method Phaser.Curves.Curve#getLengths
* @since 3.0.0
*
* @param {number} [divisions] - The number of divisions or segments.
*
* @return {number[]} An array of cumulative lengths.
*/
getLengths: function(divisions) {
if (divisions === void 0) {
divisions = this.arcLengthDivisions;
}
if (this.cacheArcLengths.length === divisions + 1 && !this.needsUpdate) {
return this.cacheArcLengths;
}
this.needsUpdate = false;
var cache = [];
var current;
var last = this.getPoint(0, this._tmpVec2A);
var sum = 0;
cache.push(0);
for (var p = 1; p <= divisions; p++) {
current = this.getPoint(p / divisions, this._tmpVec2B);
sum += current.distance(last);
cache.push(sum);
last.copy(current);
}
this.cacheArcLengths = cache;
return cache;
},
// Get point at relative position in curve according to arc length
// - u [0 .. 1]
/**
* Get a point at a relative position on the curve, by arc length.
*
* @method Phaser.Curves.Curve#getPointAt
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {number} u - The relative position, [0..1].
* @param {Phaser.Math.Vector2} [out] - A point to store the result in.
*
* @return {Phaser.Math.Vector2} The point.
*/
getPointAt: function(u, out) {
var t = this.getUtoTmapping(u);
return this.getPoint(t, out);
},
// Get sequence of points using getPoint( t )
/**
* Get a sequence of evenly spaced points from the curve.
*
* You can pass `divisions`, `stepRate`, or neither.
*
* The number of divisions will be
*
* 1. `divisions`, if `divisions` > 0; or
* 2. `this.getLength / stepRate`, if `stepRate` > 0; or
* 3. `this.defaultDivisions`
*
* `1 + divisions` points will be returned.
*
* @method Phaser.Curves.Curve#getPoints
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2[]} O - [out,$return]
*
* @param {number} [divisions] - The number of divisions to make.
* @param {number} [stepRate] - The curve distance between points, implying `divisions`.
* @param {(array|Phaser.Math.Vector2[])} [out] - An optional array to store the points in.
*
* @return {(array|Phaser.Math.Vector2[])} An array of Points from the curve.
*/
getPoints: function(divisions, stepRate, out) {
if (out === void 0) {
out = [];
}
if (!divisions) {
if (!stepRate) {
divisions = this.defaultDivisions;
} else {
divisions = this.getLength() / stepRate;
}
}
for (var d = 0; d <= divisions; d++) {
out.push(this.getPoint(d / divisions));
}
return out;
},
/**
* Get a random point from the curve.
*
* @method Phaser.Curves.Curve#getRandomPoint
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {Phaser.Math.Vector2} [out] - A point object to store the result in.
*
* @return {Phaser.Math.Vector2} The point.
*/
getRandomPoint: function(out) {
if (out === void 0) {
out = new Vector2();
}
return this.getPoint(Math.random(), out);
},
// Get sequence of points using getPointAt( u )
/**
* Get a sequence of equally spaced points (by arc distance) from the curve.
*
* `1 + divisions` points will be returned.
*
* @method Phaser.Curves.Curve#getSpacedPoints
* @since 3.0.0
*
* @param {number} [divisions=this.defaultDivisions] - The number of divisions to make.
* @param {number} [stepRate] - Step between points. Used to calculate the number of points to return when divisions is falsy. Ignored if divisions is positive.
* @param {(array|Phaser.Math.Vector2[])} [out] - An optional array to store the points in.
*
* @return {Phaser.Math.Vector2[]} An array of points.
*/
getSpacedPoints: function(divisions, stepRate, out) {
if (out === void 0) {
out = [];
}
if (!divisions) {
if (!stepRate) {
divisions = this.defaultDivisions;
} else {
divisions = this.getLength() / stepRate;
}
}
for (var d = 0; d <= divisions; d++) {
var t = this.getUtoTmapping(d / divisions, null, divisions);
out.push(this.getPoint(t));
}
return out;
},
/**
* Get a point at the start of the curve.
*
* @method Phaser.Curves.Curve#getStartPoint
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {Phaser.Math.Vector2} [out] - A point to store the result in.
*
* @return {Phaser.Math.Vector2} The point.
*/
getStartPoint: function(out) {
if (out === void 0) {
out = new Vector2();
}
return this.getPointAt(0, out);
},
/**
* Get a unit vector tangent at a relative position on the curve.
* In case any sub curve does not implement its tangent derivation,
* 2 points a small delta apart will be used to find its gradient
* which seems to give a reasonable approximation
*
* @method Phaser.Curves.Curve#getTangent
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {number} t - The relative position on the curve, [0..1].
* @param {Phaser.Math.Vector2} [out] - A vector to store the result in.
*
* @return {Phaser.Math.Vector2} Vector approximating the tangent line at the point t (delta +/- 0.0001)
*/
getTangent: function(t, out) {
if (out === void 0) {
out = new Vector2();
}
var delta = 1e-4;
var t1 = t - delta;
var t2 = t + delta;
if (t1 < 0) {
t1 = 0;
}
if (t2 > 1) {
t2 = 1;
}
this.getPoint(t1, this._tmpVec2A);
this.getPoint(t2, out);
return out.subtract(this._tmpVec2A).normalize();
},
/**
* Get a unit vector tangent at a relative position on the curve, by arc length.
*
* @method Phaser.Curves.Curve#getTangentAt
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {number} u - The relative position on the curve, [0..1].
* @param {Phaser.Math.Vector2} [out] - A vector to store the result in.
*
* @return {Phaser.Math.Vector2} The tangent vector.
*/
getTangentAt: function(u, out) {
var t = this.getUtoTmapping(u);
return this.getTangent(t, out);
},
/**
* Given a distance in pixels, get a t to find p.
*
* @method Phaser.Curves.Curve#getTFromDistance
* @since 3.0.0
*
* @param {number} distance - The distance, in pixels.
* @param {number} [divisions] - Optional amount of divisions.
*
* @return {number} The distance.
*/
getTFromDistance: function(distance, divisions) {
if (distance <= 0) {
return 0;
}
return this.getUtoTmapping(0, distance, divisions);
},
/**
* Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant.
*
* @method Phaser.Curves.Curve#getUtoTmapping
* @since 3.0.0
*
* @param {number} u - A float between 0 and 1.
* @param {number} distance - The distance, in pixels.
* @param {number} [divisions] - Optional amount of divisions.
*
* @return {number} The equidistant value.
*/
getUtoTmapping: function(u, distance, divisions) {
var arcLengths = this.getLengths(divisions);
var i = 0;
var il = arcLengths.length;
var targetArcLength;
if (distance) {
targetArcLength = Math.min(distance, arcLengths[il - 1]);
} else {
targetArcLength = u * arcLengths[il - 1];
}
var low = 0;
var high = il - 1;
var comparison;
while (low <= high) {
i = Math.floor(low + (high - low) / 2);
comparison = arcLengths[i] - targetArcLength;
if (comparison < 0) {
low = i + 1;
} else if (comparison > 0) {
high = i - 1;
} else {
high = i;
break;
}
}
i = high;
if (arcLengths[i] === targetArcLength) {
return i / (il - 1);
}
var lengthBefore = arcLengths[i];
var lengthAfter = arcLengths[i + 1];
var segmentLength = lengthAfter - lengthBefore;
var segmentFraction = (targetArcLength - lengthBefore) / segmentLength;
return (i + segmentFraction) / (il - 1);
},
/**
* Calculate and cache the arc lengths.
*
* @method Phaser.Curves.Curve#updateArcLengths
* @since 3.0.0
*
* @see Phaser.Curves.Curve#getLengths()
*/
updateArcLengths: function() {
this.needsUpdate = true;
this.getLengths();
}
});
module2.exports = Curve;
}
),
/***/
73825: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Curve = __webpack_require__2(80021);
var DegToRad = __webpack_require__2(39506);
var GetValue = __webpack_require__2(35154);
var RadToDeg = __webpack_require__2(43396);
var Vector2 = __webpack_require__2(26099);
var EllipseCurve = new Class({
Extends: Curve,
initialize: function EllipseCurve2(x, y, xRadius, yRadius, startAngle, endAngle, clockwise, rotation) {
if (typeof x === "object") {
var config = x;
x = GetValue(config, "x", 0);
y = GetValue(config, "y", 0);
xRadius = GetValue(config, "xRadius", 0);
yRadius = GetValue(config, "yRadius", xRadius);
startAngle = GetValue(config, "startAngle", 0);
endAngle = GetValue(config, "endAngle", 360);
clockwise = GetValue(config, "clockwise", false);
rotation = GetValue(config, "rotation", 0);
} else {
if (yRadius === void 0) {
yRadius = xRadius;
}
if (startAngle === void 0) {
startAngle = 0;
}
if (endAngle === void 0) {
endAngle = 360;
}
if (clockwise === void 0) {
clockwise = false;
}
if (rotation === void 0) {
rotation = 0;
}
}
Curve.call(this, "EllipseCurve");
this.p0 = new Vector2(x, y);
this._xRadius = xRadius;
this._yRadius = yRadius;
this._startAngle = DegToRad(startAngle);
this._endAngle = DegToRad(endAngle);
this._clockwise = clockwise;
this._rotation = DegToRad(rotation);
},
/**
* Gets the starting point on the curve.
*
* @method Phaser.Curves.Ellipse#getStartPoint
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created.
*
* @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned.
*/
getStartPoint: function(out) {
if (out === void 0) {
out = new Vector2();
}
return this.getPoint(0, out);
},
/**
* Get the resolution of the curve.
*
* @method Phaser.Curves.Ellipse#getResolution
* @since 3.0.0
*
* @param {number} divisions - Optional divisions value.
*
* @return {number} The curve resolution.
*/
getResolution: function(divisions) {
return divisions * 2;
},
/**
* Get point at relative position in curve according to length.
*
* @method Phaser.Curves.Ellipse#getPoint
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end.
* @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created.
*
* @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned.
*/
getPoint: function(t, out) {
if (out === void 0) {
out = new Vector2();
}
var twoPi = Math.PI * 2;
var deltaAngle = this._endAngle - this._startAngle;
var samePoints = Math.abs(deltaAngle) < Number.EPSILON;
while (deltaAngle < 0) {
deltaAngle += twoPi;
}
while (deltaAngle > twoPi) {
deltaAngle -= twoPi;
}
if (deltaAngle < Number.EPSILON) {
if (samePoints) {
deltaAngle = 0;
} else {
deltaAngle = twoPi;
}
}
if (this._clockwise && !samePoints) {
if (deltaAngle === twoPi) {
deltaAngle = -twoPi;
} else {
deltaAngle = deltaAngle - twoPi;
}
}
var angle = this._startAngle + t * deltaAngle;
var x = this.p0.x + this._xRadius * Math.cos(angle);
var y = this.p0.y + this._yRadius * Math.sin(angle);
if (this._rotation !== 0) {
var cos = Math.cos(this._rotation);
var sin = Math.sin(this._rotation);
var tx = x - this.p0.x;
var ty = y - this.p0.y;
x = tx * cos - ty * sin + this.p0.x;
y = tx * sin + ty * cos + this.p0.y;
}
return out.set(x, y);
},
/**
* Sets the horizontal radius of this curve.
*
* @method Phaser.Curves.Ellipse#setXRadius
* @since 3.0.0
*
* @param {number} value - The horizontal radius of this curve.
*
* @return {this} This curve object.
*/
setXRadius: function(value) {
this.xRadius = value;
return this;
},
/**
* Sets the vertical radius of this curve.
*
* @method Phaser.Curves.Ellipse#setYRadius
* @since 3.0.0
*
* @param {number} value - The vertical radius of this curve.
*
* @return {this} This curve object.
*/
setYRadius: function(value) {
this.yRadius = value;
return this;
},
/**
* Sets the width of this curve.
*
* @method Phaser.Curves.Ellipse#setWidth
* @since 3.0.0
*
* @param {number} value - The width of this curve.
*
* @return {this} This curve object.
*/
setWidth: function(value) {
this.xRadius = value / 2;
return this;
},
/**
* Sets the height of this curve.
*
* @method Phaser.Curves.Ellipse#setHeight
* @since 3.0.0
*
* @param {number} value - The height of this curve.
*
* @return {this} This curve object.
*/
setHeight: function(value) {
this.yRadius = value / 2;
return this;
},
/**
* Sets the start angle of this curve.
*
* @method Phaser.Curves.Ellipse#setStartAngle
* @since 3.0.0
*
* @param {number} value - The start angle of this curve, in radians.
*
* @return {this} This curve object.
*/
setStartAngle: function(value) {
this.startAngle = value;
return this;
},
/**
* Sets the end angle of this curve.
*
* @method Phaser.Curves.Ellipse#setEndAngle
* @since 3.0.0
*
* @param {number} value - The end angle of this curve, in radians.
*
* @return {this} This curve object.
*/
setEndAngle: function(value) {
this.endAngle = value;
return this;
},
/**
* Sets if this curve extends clockwise or anti-clockwise.
*
* @method Phaser.Curves.Ellipse#setClockwise
* @since 3.0.0
*
* @param {boolean} value - The clockwise state of this curve.
*
* @return {this} This curve object.
*/
setClockwise: function(value) {
this.clockwise = value;
return this;
},
/**
* Sets the rotation of this curve.
*
* @method Phaser.Curves.Ellipse#setRotation
* @since 3.0.0
*
* @param {number} value - The rotation of this curve, in radians.
*
* @return {this} This curve object.
*/
setRotation: function(value) {
this.rotation = value;
return this;
},
/**
* The x coordinate of the center of the ellipse.
*
* @name Phaser.Curves.Ellipse#x
* @type {number}
* @since 3.0.0
*/
x: {
get: function() {
return this.p0.x;
},
set: function(value) {
this.p0.x = value;
}
},
/**
* The y coordinate of the center of the ellipse.
*
* @name Phaser.Curves.Ellipse#y
* @type {number}
* @since 3.0.0
*/
y: {
get: function() {
return this.p0.y;
},
set: function(value) {
this.p0.y = value;
}
},
/**
* The horizontal radius of the ellipse.
*
* @name Phaser.Curves.Ellipse#xRadius
* @type {number}
* @since 3.0.0
*/
xRadius: {
get: function() {
return this._xRadius;
},
set: function(value) {
this._xRadius = value;
}
},
/**
* The vertical radius of the ellipse.
*
* @name Phaser.Curves.Ellipse#yRadius
* @type {number}
* @since 3.0.0
*/
yRadius: {
get: function() {
return this._yRadius;
},
set: function(value) {
this._yRadius = value;
}
},
/**
* The start angle of the ellipse in degrees.
*
* @name Phaser.Curves.Ellipse#startAngle
* @type {number}
* @since 3.0.0
*/
startAngle: {
get: function() {
return RadToDeg(this._startAngle);
},
set: function(value) {
this._startAngle = DegToRad(value);
}
},
/**
* The end angle of the ellipse in degrees.
*
* @name Phaser.Curves.Ellipse#endAngle
* @type {number}
* @since 3.0.0
*/
endAngle: {
get: function() {
return RadToDeg(this._endAngle);
},
set: function(value) {
this._endAngle = DegToRad(value);
}
},
/**
* `true` if the ellipse rotation is clockwise or `false` if anti-clockwise.
*
* @name Phaser.Curves.Ellipse#clockwise
* @type {boolean}
* @since 3.0.0
*/
clockwise: {
get: function() {
return this._clockwise;
},
set: function(value) {
this._clockwise = value;
}
},
/**
* The rotation of the ellipse, relative to the center, in degrees.
*
* @name Phaser.Curves.Ellipse#angle
* @type {number}
* @since 3.14.0
*/
angle: {
get: function() {
return RadToDeg(this._rotation);
},
set: function(value) {
this._rotation = DegToRad(value);
}
},
/**
* The rotation of the ellipse, relative to the center, in radians.
*
* @name Phaser.Curves.Ellipse#rotation
* @type {number}
* @since 3.0.0
*/
rotation: {
get: function() {
return this._rotation;
},
set: function(value) {
this._rotation = value;
}
},
/**
* JSON serialization of the curve.
*
* @method Phaser.Curves.Ellipse#toJSON
* @since 3.0.0
*
* @return {Phaser.Types.Curves.JSONEllipseCurve} The JSON object containing this curve data.
*/
toJSON: function() {
return {
type: this.type,
x: this.p0.x,
y: this.p0.y,
xRadius: this._xRadius,
yRadius: this._yRadius,
startAngle: RadToDeg(this._startAngle),
endAngle: RadToDeg(this._endAngle),
clockwise: this._clockwise,
rotation: RadToDeg(this._rotation)
};
}
});
EllipseCurve.fromJSON = function(data) {
return new EllipseCurve(data);
};
module2.exports = EllipseCurve;
}
),
/***/
33951: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Curve = __webpack_require__2(80021);
var FromPoints = __webpack_require__2(19217);
var Rectangle = __webpack_require__2(87841);
var Vector2 = __webpack_require__2(26099);
var LineCurve = new Class({
Extends: Curve,
initialize: (
// vec2s or array
function LineCurve2(p0, p1) {
Curve.call(this, "LineCurve");
if (Array.isArray(p0)) {
p1 = new Vector2(p0[2], p0[3]);
p0 = new Vector2(p0[0], p0[1]);
}
this.p0 = p0;
this.p1 = p1;
this.arcLengthDivisions = 1;
}
),
/**
* Returns a Rectangle where the position and dimensions match the bounds of this Curve.
*
* @method Phaser.Curves.Line#getBounds
* @since 3.0.0
*
* @generic {Phaser.Geom.Rectangle} O - [out,$return]
*
* @param {Phaser.Geom.Rectangle} [out] - A Rectangle object to store the bounds in. If not given a new Rectangle will be created.
*
* @return {Phaser.Geom.Rectangle} A Rectangle object holding the bounds of this curve. If `out` was given it will be this object.
*/
getBounds: function(out) {
if (out === void 0) {
out = new Rectangle();
}
return FromPoints([this.p0, this.p1], out);
},
/**
* Gets the starting point on the curve.
*
* @method Phaser.Curves.Line#getStartPoint
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created.
*
* @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned.
*/
getStartPoint: function(out) {
if (out === void 0) {
out = new Vector2();
}
return out.copy(this.p0);
},
/**
* Gets the resolution of the line.
*
* @method Phaser.Curves.Line#getResolution
* @since 3.0.0
*
* @param {number} [divisions=1] - The number of divisions to consider.
*
* @return {number} The resolution. Equal to the number of divisions.
*/
getResolution: function(divisions) {
if (divisions === void 0) {
divisions = 1;
}
return divisions;
},
/**
* Get point at relative position in curve according to length.
*
* @method Phaser.Curves.Line#getPoint
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end.
* @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created.
*
* @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned.
*/
getPoint: function(t, out) {
if (out === void 0) {
out = new Vector2();
}
if (t === 1) {
return out.copy(this.p1);
}
out.copy(this.p1).subtract(this.p0).scale(t).add(this.p0);
return out;
},
// Line curve is linear, so we can overwrite default getPointAt
/**
* Gets a point at a given position on the line.
*
* @method Phaser.Curves.Line#getPointAt
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {number} u - The position along the curve to return. Where 0 is the start and 1 is the end.
* @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created.
*
* @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned.
*/
getPointAt: function(u, out) {
return this.getPoint(u, out);
},
/**
* Gets the slope of the line as a unit vector.
*
* @method Phaser.Curves.Line#getTangent
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {number} [t] - The relative position on the line, [0..1].
* @param {Phaser.Math.Vector2} [out] - A vector to store the result in.
*
* @return {Phaser.Math.Vector2} The tangent vector.
*/
getTangent: function(t, out) {
if (out === void 0) {
out = new Vector2();
}
out.copy(this.p1).subtract(this.p0).normalize();
return out;
},
/**
* Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant.
*
* @method Phaser.Curves.Line#getUtoTmapping
* @since 3.0.0
*
* @param {number} u - A float between 0 and 1.
* @param {number} distance - The distance, in pixels.
* @param {number} [divisions] - Optional amount of divisions.
*
* @return {number} The equidistant value.
*/
getUtoTmapping: function(u, distance, divisions) {
var t;
if (distance) {
var arcLengths = this.getLengths(divisions);
var lineLength = arcLengths[arcLengths.length - 1];
var targetLineLength = Math.min(distance, lineLength);
t = targetLineLength / lineLength;
} else {
t = u;
}
return t;
},
// Override default Curve.draw because this is better than calling getPoints on a line!
/**
* Draws this curve on the given Graphics object.
*
* The curve is drawn using `Graphics.lineBetween` so will be drawn at whatever the present Graphics line color is.
* The Graphics object is not cleared before the draw, so the curve will appear on-top of anything else already rendered to it.
*
* @method Phaser.Curves.Line#draw
* @since 3.0.0
*
* @generic {Phaser.GameObjects.Graphics} G - [graphics,$return]
*
* @param {Phaser.GameObjects.Graphics} graphics - The Graphics instance onto which this curve will be drawn.
*
* @return {Phaser.GameObjects.Graphics} The Graphics object to which the curve was drawn.
*/
draw: function(graphics) {
graphics.lineBetween(this.p0.x, this.p0.y, this.p1.x, this.p1.y);
return graphics;
},
/**
* Gets a JSON representation of the line.
*
* @method Phaser.Curves.Line#toJSON
* @since 3.0.0
*
* @return {Phaser.Types.Curves.JSONCurve} The JSON object containing this curve data.
*/
toJSON: function() {
return {
type: this.type,
points: [
this.p0.x,
this.p0.y,
this.p1.x,
this.p1.y
]
};
}
});
LineCurve.fromJSON = function(data) {
var points = data.points;
var p0 = new Vector2(points[0], points[1]);
var p1 = new Vector2(points[2], points[3]);
return new LineCurve(p0, p1);
};
module2.exports = LineCurve;
}
),
/***/
14744: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Curve = __webpack_require__2(80021);
var QuadraticBezierInterpolation = __webpack_require__2(32112);
var Vector2 = __webpack_require__2(26099);
var QuadraticBezier = new Class({
Extends: Curve,
initialize: function QuadraticBezier2(p0, p1, p2) {
Curve.call(this, "QuadraticBezierCurve");
if (Array.isArray(p0)) {
p2 = new Vector2(p0[4], p0[5]);
p1 = new Vector2(p0[2], p0[3]);
p0 = new Vector2(p0[0], p0[1]);
}
this.p0 = p0;
this.p1 = p1;
this.p2 = p2;
},
/**
* Gets the starting point on the curve.
*
* @method Phaser.Curves.QuadraticBezier#getStartPoint
* @since 3.2.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created.
*
* @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned.
*/
getStartPoint: function(out) {
if (out === void 0) {
out = new Vector2();
}
return out.copy(this.p0);
},
/**
* Get the resolution of the curve.
*
* @method Phaser.Curves.QuadraticBezier#getResolution
* @since 3.2.0
*
* @param {number} divisions - Optional divisions value.
*
* @return {number} The curve resolution.
*/
getResolution: function(divisions) {
return divisions;
},
/**
* Get point at relative position in curve according to length.
*
* @method Phaser.Curves.QuadraticBezier#getPoint
* @since 3.2.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end.
* @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created.
*
* @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned.
*/
getPoint: function(t, out) {
if (out === void 0) {
out = new Vector2();
}
var p0 = this.p0;
var p1 = this.p1;
var p2 = this.p2;
return out.set(
QuadraticBezierInterpolation(t, p0.x, p1.x, p2.x),
QuadraticBezierInterpolation(t, p0.y, p1.y, p2.y)
);
},
/**
* Draws this curve on the given Graphics object.
*
* The curve is drawn using `Graphics.strokePoints` so will be drawn at whatever the present Graphics stroke color is.
* The Graphics object is not cleared before the draw, so the curve will appear on-top of anything else already rendered to it.
*
* @method Phaser.Curves.QuadraticBezier#draw
* @since 3.2.0
*
* @generic {Phaser.GameObjects.Graphics} G - [graphics,$return]
*
* @param {Phaser.GameObjects.Graphics} graphics - `Graphics` object to draw onto.
* @param {number} [pointsTotal=32] - Number of points to be used for drawing the curve. Higher numbers result in smoother curve but require more processing.
*
* @return {Phaser.GameObjects.Graphics} `Graphics` object that was drawn to.
*/
draw: function(graphics, pointsTotal) {
if (pointsTotal === void 0) {
pointsTotal = 32;
}
var points = this.getPoints(pointsTotal);
graphics.beginPath();
graphics.moveTo(this.p0.x, this.p0.y);
for (var i = 1; i < points.length; i++) {
graphics.lineTo(points[i].x, points[i].y);
}
graphics.strokePath();
return graphics;
},
/**
* Converts the curve into a JSON compatible object.
*
* @method Phaser.Curves.QuadraticBezier#toJSON
* @since 3.2.0
*
* @return {Phaser.Types.Curves.JSONCurve} The JSON object containing this curve data.
*/
toJSON: function() {
return {
type: this.type,
points: [
this.p0.x,
this.p0.y,
this.p1.x,
this.p1.y,
this.p2.x,
this.p2.y
]
};
}
});
QuadraticBezier.fromJSON = function(data) {
var points = data.points;
var p0 = new Vector2(points[0], points[1]);
var p1 = new Vector2(points[2], points[3]);
var p2 = new Vector2(points[4], points[5]);
return new QuadraticBezier(p0, p1, p2);
};
module2.exports = QuadraticBezier;
}
),
/***/
42534: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CatmullRom = __webpack_require__2(87842);
var Class = __webpack_require__2(83419);
var Curve = __webpack_require__2(80021);
var Vector2 = __webpack_require__2(26099);
var SplineCurve = new Class({
Extends: Curve,
initialize: function SplineCurve2(points) {
if (points === void 0) {
points = [];
}
Curve.call(this, "SplineCurve");
this.points = [];
this.addPoints(points);
},
/**
* Add a list of points to the current list of Vector2 points of the curve.
*
* @method Phaser.Curves.Spline#addPoints
* @since 3.0.0
*
* @param {(Phaser.Math.Vector2[]|number[]|number[][])} points - The points that configure the curve.
*
* @return {this} This curve object.
*/
addPoints: function(points) {
for (var i = 0; i < points.length; i++) {
var p = new Vector2();
if (typeof points[i] === "number") {
p.x = points[i];
p.y = points[i + 1];
i++;
} else if (Array.isArray(points[i])) {
p.x = points[i][0];
p.y = points[i][1];
} else {
p.x = points[i].x;
p.y = points[i].y;
}
this.points.push(p);
}
return this;
},
/**
* Add a point to the current list of Vector2 points of the curve.
*
* @method Phaser.Curves.Spline#addPoint
* @since 3.0.0
*
* @param {number} x - The x coordinate of this curve
* @param {number} y - The y coordinate of this curve
*
* @return {Phaser.Math.Vector2} The new Vector2 added to the curve
*/
addPoint: function(x, y) {
var vec = new Vector2(x, y);
this.points.push(vec);
return vec;
},
/**
* Gets the starting point on the curve.
*
* @method Phaser.Curves.Spline#getStartPoint
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created.
*
* @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned.
*/
getStartPoint: function(out) {
if (out === void 0) {
out = new Vector2();
}
return out.copy(this.points[0]);
},
/**
* Get the resolution of the curve.
*
* @method Phaser.Curves.Spline#getResolution
* @since 3.0.0
*
* @param {number} divisions - Optional divisions value.
*
* @return {number} The curve resolution.
*/
getResolution: function(divisions) {
return divisions * this.points.length;
},
/**
* Get point at relative position in curve according to length.
*
* @method Phaser.Curves.Spline#getPoint
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end.
* @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created.
*
* @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned.
*/
getPoint: function(t, out) {
if (out === void 0) {
out = new Vector2();
}
var points = this.points;
var point = (points.length - 1) * t;
var intPoint = Math.floor(point);
var weight = point - intPoint;
var p0 = points[intPoint === 0 ? intPoint : intPoint - 1];
var p1 = points[intPoint];
var p2 = points[intPoint > points.length - 2 ? points.length - 1 : intPoint + 1];
var p3 = points[intPoint > points.length - 3 ? points.length - 1 : intPoint + 2];
return out.set(CatmullRom(weight, p0.x, p1.x, p2.x, p3.x), CatmullRom(weight, p0.y, p1.y, p2.y, p3.y));
},
/**
* Exports a JSON object containing this curve data.
*
* @method Phaser.Curves.Spline#toJSON
* @since 3.0.0
*
* @return {Phaser.Types.Curves.JSONCurve} The JSON object containing this curve data.
*/
toJSON: function() {
var points = [];
for (var i = 0; i < this.points.length; i++) {
points.push(this.points[i].x);
points.push(this.points[i].y);
}
return {
type: this.type,
points
};
}
});
SplineCurve.fromJSON = function(data) {
return new SplineCurve(data.points);
};
module2.exports = SplineCurve;
}
),
/***/
25410: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Path: __webpack_require__2(46669),
MoveTo: __webpack_require__2(68618),
CubicBezier: __webpack_require__2(46728),
Curve: __webpack_require__2(80021),
Ellipse: __webpack_require__2(73825),
Line: __webpack_require__2(33951),
QuadraticBezier: __webpack_require__2(14744),
Spline: __webpack_require__2(42534)
};
}
),
/***/
68618: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Vector2 = __webpack_require__2(26099);
var MoveTo = new Class({
initialize: function MoveTo2(x, y) {
this.active = false;
this.p0 = new Vector2(x, y);
},
/**
* Get point at relative position in curve according to length.
*
* @method Phaser.Curves.MoveTo#getPoint
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {number} t - The position along the curve to return. Where 0 is the start and 1 is the end.
* @param {Phaser.Math.Vector2} [out] - A Vector2 object to store the result in. If not given will be created.
*
* @return {Phaser.Math.Vector2} The coordinates of the point on the curve. If an `out` object was given this will be returned.
*/
getPoint: function(t, out) {
if (out === void 0) {
out = new Vector2();
}
return out.copy(this.p0);
},
/**
* Retrieves the point at given position in the curve. This will always return this curve's only point.
*
* @method Phaser.Curves.MoveTo#getPointAt
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {number} u - The position in the path to retrieve, between 0 and 1. Not used.
* @param {Phaser.Math.Vector2} [out] - An optional vector in which to store the point.
*
* @return {Phaser.Math.Vector2} The modified `out` vector, or a new `Vector2` if none was provided.
*/
getPointAt: function(u, out) {
return this.getPoint(u, out);
},
/**
* Gets the resolution of this curve.
*
* @method Phaser.Curves.MoveTo#getResolution
* @since 3.0.0
*
* @return {number} The resolution of this curve. For a MoveTo the value is always 1.
*/
getResolution: function() {
return 1;
},
/**
* Gets the length of this curve.
*
* @method Phaser.Curves.MoveTo#getLength
* @since 3.0.0
*
* @return {number} The length of this curve. For a MoveTo the value is always 0.
*/
getLength: function() {
return 0;
},
/**
* Converts this curve into a JSON-serializable object.
*
* @method Phaser.Curves.MoveTo#toJSON
* @since 3.0.0
*
* @return {Phaser.Types.Curves.JSONCurve} A primitive object with the curve's type and only point.
*/
toJSON: function() {
return {
type: "MoveTo",
points: [
this.p0.x,
this.p0.y
]
};
}
});
module2.exports = MoveTo;
}
),
/***/
46669: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CubicBezierCurve = __webpack_require__2(46728);
var EllipseCurve = __webpack_require__2(73825);
var GameObjectFactory = __webpack_require__2(39429);
var LineCurve = __webpack_require__2(33951);
var MovePathTo = __webpack_require__2(68618);
var QuadraticBezierCurve = __webpack_require__2(14744);
var Rectangle = __webpack_require__2(87841);
var SplineCurve = __webpack_require__2(42534);
var Vector2 = __webpack_require__2(26099);
var MATH_CONST = __webpack_require__2(36383);
var Path = new Class({
initialize: function Path2(x, y) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
this.name = "";
this.defaultDivisions = 12;
this.curves = [];
this.cacheLengths = [];
this.autoClose = false;
this.startPoint = new Vector2();
this._tmpVec2A = new Vector2();
this._tmpVec2B = new Vector2();
if (typeof x === "object") {
this.fromJSON(x);
} else {
this.startPoint.set(x, y);
}
},
/**
* Appends a Curve to the end of the Path.
*
* The Curve does not have to start where the Path ends or, for an empty Path, at its defined starting point.
*
* @method Phaser.Curves.Path#add
* @since 3.0.0
*
* @param {Phaser.Curves.Curve} curve - The Curve to append.
*
* @return {this} This Path object.
*/
add: function(curve) {
this.curves.push(curve);
return this;
},
/**
* Creates a circular Ellipse Curve positioned at the end of the Path.
*
* @method Phaser.Curves.Path#circleTo
* @since 3.0.0
*
* @param {number} radius - The radius of the circle.
* @param {boolean} [clockwise=false] - `true` to create a clockwise circle as opposed to a counter-clockwise circle.
* @param {number} [rotation=0] - The rotation of the circle in degrees.
*
* @return {this} This Path object.
*/
circleTo: function(radius, clockwise, rotation) {
if (clockwise === void 0) {
clockwise = false;
}
return this.ellipseTo(radius, radius, 0, 360, clockwise, rotation);
},
/**
* Ensures that the Path is closed.
*
* A closed Path starts and ends at the same point. If the Path is not closed, a straight Line Curve will be created from the ending point directly to the starting point. During the check, the actual starting point of the Path, i.e. the starting point of the first Curve, will be used as opposed to the Path's defined {@link startPoint}, which could differ.
*
* Calling this method on an empty Path will result in an error.
*
* @method Phaser.Curves.Path#closePath
* @since 3.0.0
*
* @return {this} This Path object.
*/
closePath: function() {
var startPoint = this.curves[0].getPoint(0);
var endPoint = this.curves[this.curves.length - 1].getPoint(1);
if (!startPoint.equals(endPoint)) {
this.curves.push(new LineCurve(endPoint, startPoint));
}
return this;
},
/**
* Creates a cubic bezier curve starting at the previous end point and ending at p3, using p1 and p2 as control points.
*
* @method Phaser.Curves.Path#cubicBezierTo
* @since 3.0.0
*
* @param {(number|Phaser.Math.Vector2)} x - The x coordinate of the end point. Or, if a Vector2, the p1 value.
* @param {(number|Phaser.Math.Vector2)} y - The y coordinate of the end point. Or, if a Vector2, the p2 value.
* @param {(number|Phaser.Math.Vector2)} control1X - The x coordinate of the first control point. Or, if a Vector2, the p3 value.
* @param {number} [control1Y] - The y coordinate of the first control point. Not used if Vector2s are provided as the first 3 arguments.
* @param {number} [control2X] - The x coordinate of the second control point. Not used if Vector2s are provided as the first 3 arguments.
* @param {number} [control2Y] - The y coordinate of the second control point. Not used if Vector2s are provided as the first 3 arguments.
*
* @return {this} This Path object.
*/
cubicBezierTo: function(x, y, control1X, control1Y, control2X, control2Y) {
var p0 = this.getEndPoint();
var p1;
var p2;
var p3;
if (x instanceof Vector2) {
p1 = x;
p2 = y;
p3 = control1X;
} else {
p1 = new Vector2(control1X, control1Y);
p2 = new Vector2(control2X, control2Y);
p3 = new Vector2(x, y);
}
return this.add(new CubicBezierCurve(p0, p1, p2, p3));
},
// Creates a quadratic bezier curve starting at the previous end point and ending at p2, using p1 as a control point
/**
* Creates a Quadratic Bezier Curve starting at the ending point of the Path.
*
* @method Phaser.Curves.Path#quadraticBezierTo
* @since 3.2.0
*
* @param {(number|Phaser.Math.Vector2[])} x - The X coordinate of the second control point or, if it's a `Vector2`, the first control point.
* @param {number} [y] - The Y coordinate of the second control point or, if `x` is a `Vector2`, the second control point.
* @param {number} [controlX] - If `x` is not a `Vector2`, the X coordinate of the first control point.
* @param {number} [controlY] - If `x` is not a `Vector2`, the Y coordinate of the first control point.
*
* @return {this} This Path object.
*/
quadraticBezierTo: function(x, y, controlX, controlY) {
var p0 = this.getEndPoint();
var p1;
var p2;
if (x instanceof Vector2) {
p1 = x;
p2 = y;
} else {
p1 = new Vector2(controlX, controlY);
p2 = new Vector2(x, y);
}
return this.add(new QuadraticBezierCurve(p0, p1, p2));
},
/**
* Draws all Curves in the Path to a Graphics Game Object.
*
* @method Phaser.Curves.Path#draw
* @since 3.0.0
*
* @generic {Phaser.GameObjects.Graphics} G - [out,$return]
*
* @param {Phaser.GameObjects.Graphics} graphics - The Graphics Game Object to draw to.
* @param {number} [pointsTotal=32] - The number of points to draw for each Curve. Higher numbers result in a smoother curve but require more processing.
*
* @return {Phaser.GameObjects.Graphics} The Graphics object which was drawn to.
*/
draw: function(graphics, pointsTotal) {
for (var i = 0; i < this.curves.length; i++) {
var curve = this.curves[i];
if (!curve.active) {
continue;
}
curve.draw(graphics, pointsTotal);
}
return graphics;
},
/**
* Creates an ellipse curve positioned at the previous end point, using the given parameters.
*
* @method Phaser.Curves.Path#ellipseTo
* @since 3.0.0
*
* @param {number} [xRadius=0] - The horizontal radius of ellipse.
* @param {number} [yRadius=0] - The vertical radius of ellipse.
* @param {number} [startAngle=0] - The start angle of the ellipse, in degrees.
* @param {number} [endAngle=360] - The end angle of the ellipse, in degrees.
* @param {boolean} [clockwise=false] - Whether the ellipse angles are given as clockwise (`true`) or counter-clockwise (`false`).
* @param {number} [rotation=0] - The rotation of the ellipse, in degrees.
*
* @return {this} This Path object.
*/
ellipseTo: function(xRadius, yRadius, startAngle, endAngle, clockwise, rotation) {
var ellipse = new EllipseCurve(0, 0, xRadius, yRadius, startAngle, endAngle, clockwise, rotation);
var end = this.getEndPoint(this._tmpVec2A);
var start = ellipse.getStartPoint(this._tmpVec2B);
end.subtract(start);
ellipse.x = end.x;
ellipse.y = end.y;
return this.add(ellipse);
},
/**
* Creates a Path from a Path Configuration object.
*
* The provided object should be a {@link Phaser.Types.Curves.JSONPath}, as returned by {@link #toJSON}. Providing a malformed object may cause errors.
*
* @method Phaser.Curves.Path#fromJSON
* @since 3.0.0
*
* @param {Phaser.Types.Curves.JSONPath} data - The JSON object containing the Path data.
*
* @return {this} This Path object.
*/
fromJSON: function(data) {
this.curves = [];
this.cacheLengths = [];
this.startPoint.set(data.x, data.y);
this.autoClose = data.autoClose;
for (var i = 0; i < data.curves.length; i++) {
var curve = data.curves[i];
switch (curve.type) {
case "LineCurve":
this.add(LineCurve.fromJSON(curve));
break;
case "EllipseCurve":
this.add(EllipseCurve.fromJSON(curve));
break;
case "SplineCurve":
this.add(SplineCurve.fromJSON(curve));
break;
case "CubicBezierCurve":
this.add(CubicBezierCurve.fromJSON(curve));
break;
case "QuadraticBezierCurve":
this.add(QuadraticBezierCurve.fromJSON(curve));
break;
}
}
return this;
},
/**
* Returns a Rectangle with a position and size matching the bounds of this Path.
*
* @method Phaser.Curves.Path#getBounds
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {Phaser.Geom.Rectangle} [out] - The Rectangle to store the bounds in.
* @param {number} [accuracy=16] - The accuracy of the bounds calculations. Higher values are more accurate at the cost of calculation speed.
*
* @return {Phaser.Geom.Rectangle} The modified `out` Rectangle, or a new Rectangle if none was provided.
*/
getBounds: function(out, accuracy) {
if (out === void 0) {
out = new Rectangle();
}
if (accuracy === void 0) {
accuracy = 16;
}
out.x = Number.MAX_VALUE;
out.y = Number.MAX_VALUE;
var bounds = new Rectangle();
var maxRight = MATH_CONST.MIN_SAFE_INTEGER;
var maxBottom = MATH_CONST.MIN_SAFE_INTEGER;
for (var i = 0; i < this.curves.length; i++) {
var curve = this.curves[i];
if (!curve.active) {
continue;
}
curve.getBounds(bounds, accuracy);
out.x = Math.min(out.x, bounds.x);
out.y = Math.min(out.y, bounds.y);
maxRight = Math.max(maxRight, bounds.right);
maxBottom = Math.max(maxBottom, bounds.bottom);
}
out.right = maxRight;
out.bottom = maxBottom;
return out;
},
/**
* Returns an array containing the length of the Path at the end of each Curve.
*
* The result of this method will be cached to avoid recalculating it in subsequent calls. The cache is only invalidated when the {@link #curves} array changes in length, leading to potential inaccuracies if a Curve in the Path is changed, or if a Curve is removed and another is added in its place.
*
* @method Phaser.Curves.Path#getCurveLengths
* @since 3.0.0
*
* @return {number[]} An array containing the length of the Path at the end of each one of its Curves.
*/
getCurveLengths: function() {
if (this.cacheLengths.length === this.curves.length) {
return this.cacheLengths;
}
var lengths = [];
var sums = 0;
for (var i = 0; i < this.curves.length; i++) {
sums += this.curves[i].getLength();
lengths.push(sums);
}
this.cacheLengths = lengths;
return lengths;
},
/**
* Returns the Curve that forms the Path at the given normalized location (between 0 and 1).
*
* @method Phaser.Curves.Path#getCurveAt
* @since 3.60.0
*
* @param {number} t - The normalized location on the Path, between 0 and 1.
*
* @return {?Phaser.Curves.Curve} The Curve that is part of this Path at a given location, or `null` if no curve was found.
*/
getCurveAt: function(t) {
var d = t * this.getLength();
var curveLengths = this.getCurveLengths();
var i = 0;
while (i < curveLengths.length) {
if (curveLengths[i] >= d) {
return this.curves[i];
}
i++;
}
return null;
},
/**
* Returns the ending point of the Path.
*
* A Path's ending point is equivalent to the ending point of the last Curve in the Path. For an empty Path, the ending point is at the Path's defined {@link #startPoint}.
*
* @method Phaser.Curves.Path#getEndPoint
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {Phaser.Math.Vector2} [out] - The object to store the point in.
*
* @return {Phaser.Math.Vector2} The modified `out` object, or a new Vector2 if none was provided.
*/
getEndPoint: function(out) {
if (out === void 0) {
out = new Vector2();
}
if (this.curves.length > 0) {
this.curves[this.curves.length - 1].getPoint(1, out);
} else {
out.copy(this.startPoint);
}
return out;
},
/**
* Returns the total length of the Path.
*
* @see {@link #getCurveLengths}
*
* @method Phaser.Curves.Path#getLength
* @since 3.0.0
*
* @return {number} The total length of the Path.
*/
getLength: function() {
var lens = this.getCurveLengths();
return lens[lens.length - 1];
},
// To get accurate point with reference to
// entire path distance at time t,
// following has to be done:
// 1. Length of each sub path have to be known
// 2. Locate and identify type of curve
// 3. Get t for the curve
// 4. Return curve.getPointAt(t')
/**
* Calculates the coordinates of the point at the given normalized location (between 0 and 1) on the Path.
*
* The location is relative to the entire Path, not to an individual Curve. A location of 0.5 is always in the middle of the Path and is thus an equal distance away from both its starting and ending points. In a Path with one Curve, it would be in the middle of the Curve; in a Path with two Curves, it could be anywhere on either one of them depending on their lengths.
*
* @method Phaser.Curves.Path#getPoint
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {number} t - The location of the point to return, between 0 and 1.
* @param {Phaser.Math.Vector2} [out] - The object in which to store the calculated point.
*
* @return {?Phaser.Math.Vector2} The modified `out` object, or a new `Vector2` if none was provided.
*/
getPoint: function(t, out) {
if (out === void 0) {
out = new Vector2();
}
var d = t * this.getLength();
var curveLengths = this.getCurveLengths();
var i = 0;
while (i < curveLengths.length) {
if (curveLengths[i] >= d) {
var diff = curveLengths[i] - d;
var curve = this.curves[i];
var segmentLength = curve.getLength();
var u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;
return curve.getPointAt(u, out);
}
i++;
}
return null;
},
/**
* Get a sequence of points on the path.
*
* @method Phaser.Curves.Path#getPoints
* @since 3.0.0
*
* @param {number} [divisions] - The number of divisions to make per resolution per curve.
* @param {number} [stepRate] - The curve distance between points per curve, implying `divisions`.
*
* @return {Phaser.Math.Vector2[]} An array of Vector2 objects that containing the points along the Path.
*/
getPoints: function(divisions, stepRate) {
if (!divisions && !stepRate) {
divisions = this.defaultDivisions;
}
var points = [];
var last;
for (var i = 0; i < this.curves.length; i++) {
var curve = this.curves[i];
if (!curve.active) {
continue;
}
var resolution = curve.getResolution(divisions);
var pts = curve.getPoints(resolution, stepRate);
for (var j = 0; j < pts.length; j++) {
var point = pts[j];
if (last && last.equals(point)) {
continue;
}
points.push(point);
last = point;
}
}
if (this.autoClose && points.length > 1 && !points[points.length - 1].equals(points[0])) {
points.push(points[0]);
}
return points;
},
/**
* Returns a randomly chosen point anywhere on the path. This follows the same rules as `getPoint` in that it may return a point on any Curve inside this path.
*
* When calling this method multiple times, the points are not guaranteed to be equally spaced spatially.
*
* @method Phaser.Curves.Path#getRandomPoint
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {Phaser.Math.Vector2} [out] - `Vector2` instance that should be used for storing the result. If `undefined` a new `Vector2` will be created.
*
* @return {Phaser.Math.Vector2} The modified `out` object, or a new `Vector2` if none was provided.
*/
getRandomPoint: function(out) {
if (out === void 0) {
out = new Vector2();
}
return this.getPoint(Math.random(), out);
},
/**
* Divides this Path into a set of equally spaced points,
*
* The resulting points are equally spaced with respect to the points' position on the path, but not necessarily equally spaced spatially.
*
* @method Phaser.Curves.Path#getSpacedPoints
* @since 3.0.0
*
* @param {number} [divisions=40] - The amount of points to divide this Path into.
*
* @return {Phaser.Math.Vector2[]} A list of the points this path was subdivided into.
*/
getSpacedPoints: function(divisions) {
if (divisions === void 0) {
divisions = 40;
}
var points = [];
for (var i = 0; i <= divisions; i++) {
points.push(this.getPoint(i / divisions));
}
if (this.autoClose) {
points.push(points[0]);
}
return points;
},
/**
* Returns the starting point of the Path.
*
* @method Phaser.Curves.Path#getStartPoint
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {Phaser.Math.Vector2} [out] - `Vector2` instance that should be used for storing the result. If `undefined` a new `Vector2` will be created.
*
* @return {Phaser.Math.Vector2} The modified `out` object, or a new Vector2 if none was provided.
*/
getStartPoint: function(out) {
if (out === void 0) {
out = new Vector2();
}
return out.copy(this.startPoint);
},
/**
* Gets a unit vector tangent at a relative position on the path.
*
* @method Phaser.Curves.Path#getTangent
* @since 3.23.0
*
* @generic {Phaser.Math.Vector2} O - [out,$return]
*
* @param {number} t - The relative position on the path, [0..1].
* @param {Phaser.Math.Vector2} [out] - A vector to store the result in.
*
* @return {Phaser.Math.Vector2} Vector approximating the tangent line at the point t (delta +/- 0.0001)
*/
getTangent: function(t, out) {
if (out === void 0) {
out = new Vector2();
}
var d = t * this.getLength();
var curveLengths = this.getCurveLengths();
var i = 0;
while (i < curveLengths.length) {
if (curveLengths[i] >= d) {
var diff = curveLengths[i] - d;
var curve = this.curves[i];
var segmentLength = curve.getLength();
var u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;
return curve.getTangentAt(u, out);
}
i++;
}
return null;
},
/**
* Creates a line curve from the previous end point to x/y.
*
* @method Phaser.Curves.Path#lineTo
* @since 3.0.0
*
* @param {(number|Phaser.Math.Vector2|Phaser.Types.Math.Vector2Like)} x - The X coordinate of the line's end point, or a `Vector2` / `Vector2Like` containing the entire end point.
* @param {number} [y] - The Y coordinate of the line's end point, if a number was passed as the X parameter.
*
* @return {this} This Path object.
*/
lineTo: function(x, y) {
if (x instanceof Vector2) {
this._tmpVec2B.copy(x);
} else if (typeof x === "object") {
this._tmpVec2B.setFromObject(x);
} else {
this._tmpVec2B.set(x, y);
}
var end = this.getEndPoint(this._tmpVec2A);
return this.add(new LineCurve([end.x, end.y, this._tmpVec2B.x, this._tmpVec2B.y]));
},
/**
* Creates a spline curve starting at the previous end point, using the given points on the curve.
*
* @method Phaser.Curves.Path#splineTo
* @since 3.0.0
*
* @param {Phaser.Math.Vector2[]} points - The points the newly created spline curve should consist of.
*
* @return {this} This Path object.
*/
splineTo: function(points) {
points.unshift(this.getEndPoint());
return this.add(new SplineCurve(points));
},
/**
* Creates a "gap" in this path from the path's current end point to the given coordinates.
*
* After calling this function, this Path's end point will be equal to the given coordinates
*
* @method Phaser.Curves.Path#moveTo
* @since 3.0.0
*
* @param {(number|Phaser.Math.Vector2|Phaser.Types.Math.Vector2Like)} x - The X coordinate of the position to move the path's end point to, or a `Vector2` / `Vector2Like` containing the entire new end point.
* @param {number} [y] - The Y coordinate of the position to move the path's end point to, if a number was passed as the X coordinate.
*
* @return {this} This Path object.
*/
moveTo: function(x, y) {
if (x instanceof Vector2) {
return this.add(new MovePathTo(x.x, x.y));
} else {
return this.add(new MovePathTo(x, y));
}
},
/**
* Converts this Path to a JSON object containing the path information and its constituent curves.
*
* @method Phaser.Curves.Path#toJSON
* @since 3.0.0
*
* @return {Phaser.Types.Curves.JSONPath} The JSON object containing this path's data.
*/
toJSON: function() {
var out = [];
for (var i = 0; i < this.curves.length; i++) {
out.push(this.curves[i].toJSON());
}
return {
type: "Path",
x: this.startPoint.x,
y: this.startPoint.y,
autoClose: this.autoClose,
curves: out
};
},
/**
* cacheLengths must be recalculated.
*
* @method Phaser.Curves.Path#updateArcLengths
* @since 3.0.0
*/
updateArcLengths: function() {
this.cacheLengths = [];
this.getCurveLengths();
},
/**
* Disposes of this Path, clearing its internal references to objects so they can be garbage-collected.
*
* @method Phaser.Curves.Path#destroy
* @since 3.0.0
*/
destroy: function() {
this.curves.length = 0;
this.cacheLengths.length = 0;
this.startPoint = void 0;
}
});
GameObjectFactory.register("path", function(x, y) {
return new Path(x, y);
});
module2.exports = Path;
}
),
/***/
45893: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Events = __webpack_require__2(24882);
var DataManager = new Class({
initialize: function DataManager2(parent, eventEmitter) {
this.parent = parent;
this.events = eventEmitter;
if (!eventEmitter) {
this.events = parent.events ? parent.events : parent;
}
this.list = {};
this.values = {};
this._frozen = false;
if (!parent.hasOwnProperty("sys") && this.events) {
this.events.once(Events.DESTROY, this.destroy, this);
}
},
/**
* Retrieves the value for the given key, or undefined if it doesn't exist.
*
* You can also access values via the `values` object. For example, if you had a key called `gold` you can do either:
*
* ```javascript
* this.data.get('gold');
* ```
*
* Or access the value directly:
*
* ```javascript
* this.data.values.gold;
* ```
*
* You can also pass in an array of keys, in which case an array of values will be returned:
*
* ```javascript
* this.data.get([ 'gold', 'armor', 'health' ]);
* ```
*
* This approach is useful for destructuring arrays in ES6.
*
* @method Phaser.Data.DataManager#get
* @since 3.0.0
*
* @param {(string|string[])} key - The key of the value to retrieve, or an array of keys.
*
* @return {*} The value belonging to the given key, or an array of values, the order of which will match the input array.
*/
get: function(key) {
var list = this.list;
if (Array.isArray(key)) {
var output = [];
for (var i = 0; i < key.length; i++) {
output.push(list[key[i]]);
}
return output;
} else {
return list[key];
}
},
/**
* Retrieves all data values in a new object.
*
* @method Phaser.Data.DataManager#getAll
* @since 3.0.0
*
* @return {Object.<string, *>} All data values.
*/
getAll: function() {
var results = {};
for (var key in this.list) {
if (this.list.hasOwnProperty(key)) {
results[key] = this.list[key];
}
}
return results;
},
/**
* Queries the DataManager for the values of keys matching the given regular expression.
*
* @method Phaser.Data.DataManager#query
* @since 3.0.0
*
* @param {RegExp} search - A regular expression object. If a non-RegExp object obj is passed, it is implicitly converted to a RegExp by using new RegExp(obj).
*
* @return {Object.<string, *>} The values of the keys matching the search string.
*/
query: function(search) {
var results = {};
for (var key in this.list) {
if (this.list.hasOwnProperty(key) && key.match(search)) {
results[key] = this.list[key];
}
}
return results;
},
/**
* Sets a value for the given key. If the key doesn't already exist in the Data Manager then it is created.
*
* ```javascript
* data.set('name', 'Red Gem Stone');
* ```
*
* You can also pass in an object of key value pairs as the first argument:
*
* ```javascript
* data.set({ name: 'Red Gem Stone', level: 2, owner: 'Link', gold: 50 });
* ```
*
* To get a value back again you can call `get`:
*
* ```javascript
* data.get('gold');
* ```
*
* Or you can access the value directly via the `values` property, where it works like any other variable:
*
* ```javascript
* data.values.gold += 50;
* ```
*
* When the value is first set, a `setdata` event is emitted.
*
* If the key already exists, a `changedata` event is emitted instead, along an event named after the key.
* For example, if you updated an existing key called `PlayerLives` then it would emit the event `changedata-PlayerLives`.
* These events will be emitted regardless if you use this method to set the value, or the direct `values` setter.
*
* Please note that the data keys are case-sensitive and must be valid JavaScript Object property strings.
* This means the keys `gold` and `Gold` are treated as two unique values within the Data Manager.
*
* @method Phaser.Data.DataManager#set
* @fires Phaser.Data.Events#SET_DATA
* @fires Phaser.Data.Events#CHANGE_DATA
* @fires Phaser.Data.Events#CHANGE_DATA_KEY
* @since 3.0.0
*
* @generic {any} T
* @genericUse {(string|T)} - [key]
*
* @param {(string|object)} key - The key to set the value for. Or an object of key value pairs. If an object the `data` argument is ignored.
* @param {*} [data] - The value to set for the given key. If an object is provided as the key this argument is ignored.
*
* @return {this} This Data Manager instance.
*/
set: function(key, data) {
if (this._frozen) {
return this;
}
if (typeof key === "string") {
return this.setValue(key, data);
} else {
for (var entry in key) {
this.setValue(entry, key[entry]);
}
}
return this;
},
/**
* Increase a value for the given key. If the key doesn't already exist in the Data Manager then it is increased from 0.
*
* When the value is first set, a `setdata` event is emitted.
*
* @method Phaser.Data.DataManager#inc
* @fires Phaser.Data.Events#SET_DATA
* @fires Phaser.Data.Events#CHANGE_DATA
* @fires Phaser.Data.Events#CHANGE_DATA_KEY
* @since 3.23.0
*
* @param {string} key - The key to change the value for.
* @param {number} [amount=1] - The amount to increase the given key by. Pass a negative value to decrease the key.
*
* @return {this} This Data Manager instance.
*/
inc: function(key, amount) {
if (this._frozen) {
return this;
}
if (amount === void 0) {
amount = 1;
}
var value = this.get(key);
if (value === void 0) {
value = 0;
}
this.set(key, value + amount);
return this;
},
/**
* Toggle a boolean value for the given key. If the key doesn't already exist in the Data Manager then it is toggled from false.
*
* When the value is first set, a `setdata` event is emitted.
*
* @method Phaser.Data.DataManager#toggle
* @fires Phaser.Data.Events#SET_DATA
* @fires Phaser.Data.Events#CHANGE_DATA
* @fires Phaser.Data.Events#CHANGE_DATA_KEY
* @since 3.23.0
*
* @param {string} key - The key to toggle the value for.
*
* @return {this} This Data Manager instance.
*/
toggle: function(key) {
if (this._frozen) {
return this;
}
this.set(key, !this.get(key));
return this;
},
/**
* Internal value setter, called automatically by the `set` method.
*
* @method Phaser.Data.DataManager#setValue
* @fires Phaser.Data.Events#SET_DATA
* @fires Phaser.Data.Events#CHANGE_DATA
* @fires Phaser.Data.Events#CHANGE_DATA_KEY
* @private
* @since 3.10.0
*
* @param {string} key - The key to set the value for.
* @param {*} data - The value to set.
*
* @return {this} This Data Manager instance.
*/
setValue: function(key, data) {
if (this._frozen) {
return this;
}
if (this.has(key)) {
this.values[key] = data;
} else {
var _this = this;
var list = this.list;
var events = this.events;
var parent = this.parent;
Object.defineProperty(this.values, key, {
enumerable: true,
configurable: true,
get: function() {
return list[key];
},
set: function(value) {
if (!_this._frozen) {
var previousValue = list[key];
list[key] = value;
events.emit(Events.CHANGE_DATA, parent, key, value, previousValue);
events.emit(Events.CHANGE_DATA_KEY + key, parent, value, previousValue);
}
}
});
list[key] = data;
events.emit(Events.SET_DATA, parent, key, data);
}
return this;
},
/**
* Passes all data entries to the given callback.
*
* @method Phaser.Data.DataManager#each
* @since 3.0.0
*
* @param {DataEachCallback} callback - The function to call.
* @param {*} [context] - Value to use as `this` when executing callback.
* @param {...*} [args] - Additional arguments that will be passed to the callback, after the game object, key, and data.
*
* @return {this} This Data Manager instance.
*/
each: function(callback, context) {
var args = [this.parent, null, void 0];
for (var i = 1; i < arguments.length; i++) {
args.push(arguments[i]);
}
for (var key in this.list) {
args[1] = key;
args[2] = this.list[key];
callback.apply(context, args);
}
return this;
},
/**
* Merge the given object of key value pairs into this DataManager.
*
* Any newly created values will emit a `setdata` event. Any updated values (see the `overwrite` argument)
* will emit a `changedata` event.
*
* @method Phaser.Data.DataManager#merge
* @fires Phaser.Data.Events#SET_DATA
* @fires Phaser.Data.Events#CHANGE_DATA
* @fires Phaser.Data.Events#CHANGE_DATA_KEY
* @since 3.0.0
*
* @param {Object.<string, *>} data - The data to merge.
* @param {boolean} [overwrite=true] - Whether to overwrite existing data. Defaults to true.
*
* @return {this} This Data Manager instance.
*/
merge: function(data, overwrite) {
if (overwrite === void 0) {
overwrite = true;
}
for (var key in data) {
if (data.hasOwnProperty(key) && (overwrite || !overwrite && !this.has(key))) {
this.setValue(key, data[key]);
}
}
return this;
},
/**
* Remove the value for the given key.
*
* If the key is found in this Data Manager it is removed from the internal lists and a
* `removedata` event is emitted.
*
* You can also pass in an array of keys, in which case all keys in the array will be removed:
*
* ```javascript
* this.data.remove([ 'gold', 'armor', 'health' ]);
* ```
*
* @method Phaser.Data.DataManager#remove
* @fires Phaser.Data.Events#REMOVE_DATA
* @since 3.0.0
*
* @param {(string|string[])} key - The key to remove, or an array of keys to remove.
*
* @return {this} This Data Manager instance.
*/
remove: function(key) {
if (this._frozen) {
return this;
}
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
this.removeValue(key[i]);
}
} else {
return this.removeValue(key);
}
return this;
},
/**
* Internal value remover, called automatically by the `remove` method.
*
* @method Phaser.Data.DataManager#removeValue
* @private
* @fires Phaser.Data.Events#REMOVE_DATA
* @since 3.10.0
*
* @param {string} key - The key to set the value for.
*
* @return {this} This Data Manager instance.
*/
removeValue: function(key) {
if (this.has(key)) {
var data = this.list[key];
delete this.list[key];
delete this.values[key];
this.events.emit(Events.REMOVE_DATA, this.parent, key, data);
}
return this;
},
/**
* Retrieves the data associated with the given 'key', deletes it from this Data Manager, then returns it.
*
* @method Phaser.Data.DataManager#pop
* @fires Phaser.Data.Events#REMOVE_DATA
* @since 3.0.0
*
* @param {string} key - The key of the value to retrieve and delete.
*
* @return {*} The value of the given key.
*/
pop: function(key) {
var data = void 0;
if (!this._frozen && this.has(key)) {
data = this.list[key];
delete this.list[key];
delete this.values[key];
this.events.emit(Events.REMOVE_DATA, this.parent, key, data);
}
return data;
},
/**
* Determines whether the given key is set in this Data Manager.
*
* Please note that the keys are case-sensitive and must be valid JavaScript Object property strings.
* This means the keys `gold` and `Gold` are treated as two unique values within the Data Manager.
*
* @method Phaser.Data.DataManager#has
* @since 3.0.0
*
* @param {string} key - The key to check.
*
* @return {boolean} Returns `true` if the key exists, otherwise `false`.
*/
has: function(key) {
return this.list.hasOwnProperty(key);
},
/**
* Freeze or unfreeze this Data Manager. A frozen Data Manager will block all attempts
* to create new values or update existing ones.
*
* @method Phaser.Data.DataManager#setFreeze
* @since 3.0.0
*
* @param {boolean} value - Whether to freeze or unfreeze the Data Manager.
*
* @return {this} This Data Manager instance.
*/
setFreeze: function(value) {
this._frozen = value;
return this;
},
/**
* Delete all data in this Data Manager and unfreeze it.
*
* @method Phaser.Data.DataManager#reset
* @since 3.0.0
*
* @return {this} This Data Manager instance.
*/
reset: function() {
for (var key in this.list) {
delete this.list[key];
delete this.values[key];
}
this._frozen = false;
return this;
},
/**
* Destroy this data manager.
*
* @method Phaser.Data.DataManager#destroy
* @since 3.0.0
*/
destroy: function() {
this.reset();
this.events.off(Events.CHANGE_DATA);
this.events.off(Events.SET_DATA);
this.events.off(Events.REMOVE_DATA);
this.parent = null;
},
/**
* Gets or sets the frozen state of this Data Manager.
* A frozen Data Manager will block all attempts to create new values or update existing ones.
*
* @name Phaser.Data.DataManager#freeze
* @type {boolean}
* @since 3.0.0
*/
freeze: {
get: function() {
return this._frozen;
},
set: function(value) {
this._frozen = value ? true : false;
}
},
/**
* Return the total number of entries in this Data Manager.
*
* @name Phaser.Data.DataManager#count
* @type {number}
* @since 3.0.0
*/
count: {
get: function() {
var i = 0;
for (var key in this.list) {
if (this.list[key] !== void 0) {
i++;
}
}
return i;
}
}
});
module2.exports = DataManager;
}
),
/***/
63646: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var DataManager = __webpack_require__2(45893);
var PluginCache = __webpack_require__2(37277);
var SceneEvents = __webpack_require__2(44594);
var DataManagerPlugin = new Class({
Extends: DataManager,
initialize: function DataManagerPlugin2(scene) {
DataManager.call(this, scene, scene.sys.events);
this.scene = scene;
this.systems = scene.sys;
scene.sys.events.once(SceneEvents.BOOT, this.boot, this);
scene.sys.events.on(SceneEvents.START, this.start, this);
},
/**
* This method is called automatically, only once, when the Scene is first created.
* Do not invoke it directly.
*
* @method Phaser.Data.DataManagerPlugin#boot
* @private
* @since 3.5.1
*/
boot: function() {
this.events = this.systems.events;
this.events.once(SceneEvents.DESTROY, this.destroy, this);
},
/**
* This method is called automatically by the Scene when it is starting up.
* It is responsible for creating local systems, properties and listening for Scene events.
* Do not invoke it directly.
*
* @method Phaser.Data.DataManagerPlugin#start
* @private
* @since 3.5.0
*/
start: function() {
this.events.once(SceneEvents.SHUTDOWN, this.shutdown, this);
},
/**
* The Scene that owns this plugin is shutting down.
* We need to kill and reset all internal properties as well as stop listening to Scene events.
*
* @method Phaser.Data.DataManagerPlugin#shutdown
* @private
* @since 3.5.0
*/
shutdown: function() {
this.systems.events.off(SceneEvents.SHUTDOWN, this.shutdown, this);
},
/**
* The Scene that owns this plugin is being destroyed.
* We need to shutdown and then kill off all external references.
*
* @method Phaser.Data.DataManagerPlugin#destroy
* @since 3.5.0
*/
destroy: function() {
DataManager.prototype.destroy.call(this);
this.events.off(SceneEvents.START, this.start, this);
this.scene = null;
this.systems = null;
}
});
PluginCache.register("DataManagerPlugin", DataManagerPlugin, "data");
module2.exports = DataManagerPlugin;
}
),
/***/
10700: (
/***/
(module2) => {
module2.exports = "changedata";
}
),
/***/
93608: (
/***/
(module2) => {
module2.exports = "changedata-";
}
),
/***/
60883: (
/***/
(module2) => {
module2.exports = "destroy";
}
),
/***/
69780: (
/***/
(module2) => {
module2.exports = "removedata";
}
),
/***/
22166: (
/***/
(module2) => {
module2.exports = "setdata";
}
),
/***/
24882: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
CHANGE_DATA: __webpack_require__2(10700),
CHANGE_DATA_KEY: __webpack_require__2(93608),
DESTROY: __webpack_require__2(60883),
REMOVE_DATA: __webpack_require__2(69780),
SET_DATA: __webpack_require__2(22166)
};
}
),
/***/
44965: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
DataManager: __webpack_require__2(45893),
DataManagerPlugin: __webpack_require__2(63646),
Events: __webpack_require__2(24882)
};
}
),
/***/
7098: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Browser = __webpack_require__2(84148);
var Audio2 = {
flac: false,
aac: false,
audioData: false,
dolby: false,
m4a: false,
mp3: false,
ogg: false,
opus: false,
wav: false,
webAudio: false,
webm: false
};
function init() {
if (typeof importScripts === "function") {
return Audio2;
}
Audio2.audioData = !!window["Audio"];
Audio2.webAudio = !!(window["AudioContext"] || window["webkitAudioContext"]);
var audioElement = document.createElement("audio");
var result = !!audioElement.canPlayType;
try {
if (result) {
var CanPlay = function(type1, type2) {
var canPlayType1 = audioElement.canPlayType("audio/" + type1).replace(/^no$/, "");
if (type2) {
return Boolean(canPlayType1 || audioElement.canPlayType("audio/" + type2).replace(/^no$/, ""));
} else {
return Boolean(canPlayType1);
}
};
Audio2.ogg = CanPlay('ogg; codecs="vorbis"');
Audio2.opus = CanPlay('ogg; codecs="opus"', "opus");
Audio2.mp3 = CanPlay("mpeg");
Audio2.wav = CanPlay("wav");
Audio2.m4a = CanPlay("x-m4a");
Audio2.aac = CanPlay("aac");
Audio2.flac = CanPlay("flac", "x-flac");
Audio2.webm = CanPlay('webm; codecs="vorbis"');
if (audioElement.canPlayType('audio/mp4; codecs="ec-3"') !== "") {
if (Browser.edge) {
Audio2.dolby = true;
} else if (Browser.safari && Browser.safariVersion >= 9) {
if (/Mac OS X (\d+)_(\d+)/.test(navigator.userAgent)) {
var major = parseInt(RegExp.$1, 10);
var minor = parseInt(RegExp.$2, 10);
if (major === 10 && minor >= 11 || major > 10) {
Audio2.dolby = true;
}
}
}
}
}
} catch (e) {
}
return Audio2;
}
module2.exports = init();
}
),
/***/
84148: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var OS = __webpack_require__2(25892);
var Browser = {
chrome: false,
chromeVersion: 0,
edge: false,
firefox: false,
firefoxVersion: 0,
ie: false,
ieVersion: 0,
mobileSafari: false,
opera: false,
safari: false,
safariVersion: 0,
silk: false,
trident: false,
tridentVersion: 0,
es2019: false
};
function init() {
var ua = navigator.userAgent;
if (/Edg\/\d+/.test(ua)) {
Browser.edge = true;
Browser.es2019 = true;
} else if (/OPR/.test(ua)) {
Browser.opera = true;
Browser.es2019 = true;
} else if (/Chrome\/(\d+)/.test(ua) && !OS.windowsPhone) {
Browser.chrome = true;
Browser.chromeVersion = parseInt(RegExp.$1, 10);
Browser.es2019 = Browser.chromeVersion > 69;
} else if (/Firefox\D+(\d+)/.test(ua)) {
Browser.firefox = true;
Browser.firefoxVersion = parseInt(RegExp.$1, 10);
Browser.es2019 = Browser.firefoxVersion > 10;
} else if (/AppleWebKit\/(?!.*CriOS)/.test(ua) && OS.iOS) {
Browser.mobileSafari = true;
Browser.es2019 = true;
} else if (/MSIE (\d+\.\d+);/.test(ua)) {
Browser.ie = true;
Browser.ieVersion = parseInt(RegExp.$1, 10);
} else if (/Version\/(\d+\.\d+(\.\d+)?) Safari/.test(ua) && !OS.windowsPhone) {
Browser.safari = true;
Browser.safariVersion = parseInt(RegExp.$1, 10);
Browser.es2019 = Browser.safariVersion > 10;
} else if (/Trident\/(\d+\.\d+)(.*)rv:(\d+\.\d+)/.test(ua)) {
Browser.ie = true;
Browser.trident = true;
Browser.tridentVersion = parseInt(RegExp.$1, 10);
Browser.ieVersion = parseInt(RegExp.$3, 10);
}
if (/Silk/.test(ua)) {
Browser.silk = true;
}
return Browser;
}
module2.exports = init();
}
),
/***/
89289: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CanvasPool = __webpack_require__2(27919);
var CanvasFeatures = {
supportInverseAlpha: false,
supportNewBlendModes: false
};
function checkBlendMode() {
var pngHead = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAABAQMAAADD8p2OAAAAA1BMVEX/";
var pngEnd = "AAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==";
var magenta = new Image();
magenta.onload = function() {
var yellow = new Image();
yellow.onload = function() {
var canvas = CanvasPool.create2D(yellow, 6);
var context = canvas.getContext("2d", { willReadFrequently: true });
context.globalCompositeOperation = "multiply";
context.drawImage(magenta, 0, 0);
context.drawImage(yellow, 2, 0);
if (!context.getImageData(2, 0, 1, 1)) {
return false;
}
var data = context.getImageData(2, 0, 1, 1).data;
CanvasPool.remove(yellow);
CanvasFeatures.supportNewBlendModes = data[0] === 255 && data[1] === 0 && data[2] === 0;
};
yellow.src = pngHead + "/wCKxvRF" + pngEnd;
};
magenta.src = pngHead + "AP804Oa6" + pngEnd;
return false;
}
function checkInverseAlpha() {
var canvas = CanvasPool.create2D(this, 2);
var context = canvas.getContext("2d", { willReadFrequently: true });
context.fillStyle = "rgba(10, 20, 30, 0.5)";
context.fillRect(0, 0, 1, 1);
var s1 = context.getImageData(0, 0, 1, 1);
if (s1 === null) {
return false;
}
context.putImageData(s1, 1, 0);
var s2 = context.getImageData(1, 0, 1, 1);
var result = s2.data[0] === s1.data[0] && s2.data[1] === s1.data[1] && s2.data[2] === s1.data[2] && s2.data[3] === s1.data[3];
CanvasPool.remove(this);
return result;
}
function init() {
if (typeof importScripts !== "function" && document !== void 0) {
CanvasFeatures.supportNewBlendModes = checkBlendMode();
CanvasFeatures.supportInverseAlpha = checkInverseAlpha();
}
return CanvasFeatures;
}
module2.exports = init();
}
),
/***/
89357: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var OS = __webpack_require__2(25892);
var Browser = __webpack_require__2(84148);
var CanvasPool = __webpack_require__2(27919);
var Features = {
canvas: false,
canvasBitBltShift: null,
file: false,
fileSystem: false,
getUserMedia: true,
littleEndian: false,
localStorage: false,
pointerLock: false,
stableSort: false,
support32bit: false,
vibration: false,
webGL: false,
worker: false
};
function checkIsLittleEndian() {
var a = new ArrayBuffer(4);
var b = new Uint8Array(a);
var c = new Uint32Array(a);
b[0] = 161;
b[1] = 178;
b[2] = 195;
b[3] = 212;
if (c[0] === 3569595041) {
return true;
}
if (c[0] === 2712847316) {
return false;
} else {
return null;
}
}
function init() {
if (typeof importScripts === "function") {
return Features;
}
Features.canvas = !!window["CanvasRenderingContext2D"];
try {
Features.localStorage = !!localStorage.getItem;
} catch (error) {
Features.localStorage = false;
}
Features.file = !!window["File"] && !!window["FileReader"] && !!window["FileList"] && !!window["Blob"];
Features.fileSystem = !!window["requestFileSystem"];
var isUint8 = false;
var testWebGL = function() {
if (window["WebGLRenderingContext"]) {
try {
var canvas = CanvasPool.createWebGL(this);
var ctx = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
var canvas2D = CanvasPool.create2D(this);
var ctx2D = canvas2D.getContext("2d", { willReadFrequently: true });
var image = ctx2D.createImageData(1, 1);
isUint8 = image.data instanceof Uint8ClampedArray;
CanvasPool.remove(canvas);
CanvasPool.remove(canvas2D);
return !!ctx;
} catch (e) {
return false;
}
}
return false;
};
Features.webGL = testWebGL();
Features.worker = !!window["Worker"];
Features.pointerLock = "pointerLockElement" in document || "mozPointerLockElement" in document || "webkitPointerLockElement" in document;
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia || navigator.oGetUserMedia;
window.URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
Features.getUserMedia = Features.getUserMedia && !!navigator.getUserMedia && !!window.URL;
if (Browser.firefox && Browser.firefoxVersion < 21) {
Features.getUserMedia = false;
}
if (!OS.iOS && (Browser.ie || Browser.firefox || Browser.chrome)) {
Features.canvasBitBltShift = true;
}
if (Browser.safari || Browser.mobileSafari) {
Features.canvasBitBltShift = false;
}
navigator.vibrate = navigator.vibrate || navigator.webkitVibrate || navigator.mozVibrate || navigator.msVibrate;
if (navigator.vibrate) {
Features.vibration = true;
}
if (typeof ArrayBuffer !== "undefined" && typeof Uint8Array !== "undefined" && typeof Uint32Array !== "undefined") {
Features.littleEndian = checkIsLittleEndian();
}
Features.support32bit = typeof ArrayBuffer !== "undefined" && typeof Uint8ClampedArray !== "undefined" && typeof Int32Array !== "undefined" && Features.littleEndian !== null && isUint8;
return Features;
}
module2.exports = init();
}
),
/***/
91639: (
/***/
(module2) => {
var Fullscreen = {
available: false,
cancel: "",
keyboard: false,
request: ""
};
function init() {
if (typeof importScripts === "function") {
return Fullscreen;
}
var i;
var suffix1 = "Fullscreen";
var suffix2 = "FullScreen";
var fs = [
"request" + suffix1,
"request" + suffix2,
"webkitRequest" + suffix1,
"webkitRequest" + suffix2,
"msRequest" + suffix1,
"msRequest" + suffix2,
"mozRequest" + suffix2,
"mozRequest" + suffix1
];
for (i = 0; i < fs.length; i++) {
if (document.documentElement[fs[i]]) {
Fullscreen.available = true;
Fullscreen.request = fs[i];
break;
}
}
var cfs = [
"cancel" + suffix2,
"exit" + suffix1,
"webkitCancel" + suffix2,
"webkitExit" + suffix1,
"msCancel" + suffix2,
"msExit" + suffix1,
"mozCancel" + suffix2,
"mozExit" + suffix1
];
if (Fullscreen.available) {
for (i = 0; i < cfs.length; i++) {
if (document[cfs[i]]) {
Fullscreen.cancel = cfs[i];
break;
}
}
}
if (window["Element"] && Element["ALLOW_KEYBOARD_INPUT"] && !/ Version\/5\.1(?:\.\d+)? Safari\//.test(navigator.userAgent)) {
Fullscreen.keyboard = true;
}
Object.defineProperty(Fullscreen, "active", { get: function() {
return !!(document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement);
} });
return Fullscreen;
}
module2.exports = init();
}
),
/***/
31784: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Browser = __webpack_require__2(84148);
var Input = {
gamepads: false,
mspointer: false,
touch: false,
wheelEvent: null
};
function init() {
if (typeof importScripts === "function") {
return Input;
}
if ("ontouchstart" in document.documentElement || navigator.maxTouchPoints && navigator.maxTouchPoints >= 1) {
Input.touch = true;
}
if (navigator.msPointerEnabled || navigator.pointerEnabled) {
Input.mspointer = true;
}
if (navigator.getGamepads) {
Input.gamepads = true;
}
if ("onwheel" in window || Browser.ie && "WheelEvent" in window) {
Input.wheelEvent = "wheel";
} else if ("onmousewheel" in window) {
Input.wheelEvent = "mousewheel";
} else if (Browser.firefox && "MouseScrollEvent" in window) {
Input.wheelEvent = "DOMMouseScroll";
}
return Input;
}
module2.exports = init();
}
),
/***/
25892: (
/***/
(module2) => {
var OS = {
android: false,
chromeOS: false,
cordova: false,
crosswalk: false,
desktop: false,
ejecta: false,
electron: false,
iOS: false,
iOSVersion: 0,
iPad: false,
iPhone: false,
kindle: false,
linux: false,
macOS: false,
node: false,
nodeWebkit: false,
pixelRatio: 1,
webApp: false,
windows: false,
windowsPhone: false
};
function init() {
if (typeof importScripts === "function") {
return OS;
}
var ua = navigator.userAgent;
if (/Windows/.test(ua)) {
OS.windows = true;
} else if (/Mac OS/.test(ua) && !/like Mac OS/.test(ua)) {
if (navigator.maxTouchPoints && navigator.maxTouchPoints > 2) {
OS.iOS = true;
OS.iPad = true;
navigator.appVersion.match(/Version\/(\d+)/);
OS.iOSVersion = parseInt(RegExp.$1, 10);
} else {
OS.macOS = true;
}
} else if (/Android/.test(ua)) {
OS.android = true;
} else if (/Linux/.test(ua)) {
OS.linux = true;
} else if (/iP[ao]d|iPhone/i.test(ua)) {
OS.iOS = true;
navigator.appVersion.match(/OS (\d+)/);
OS.iOSVersion = parseInt(RegExp.$1, 10);
OS.iPhone = ua.toLowerCase().indexOf("iphone") !== -1;
OS.iPad = ua.toLowerCase().indexOf("ipad") !== -1;
} else if (/Kindle/.test(ua) || /\bKF[A-Z][A-Z]+/.test(ua) || /Silk.*Mobile Safari/.test(ua)) {
OS.kindle = true;
} else if (/CrOS/.test(ua)) {
OS.chromeOS = true;
}
if (/Windows Phone/i.test(ua) || /IEMobile/i.test(ua)) {
OS.android = false;
OS.iOS = false;
OS.macOS = false;
OS.windows = true;
OS.windowsPhone = true;
}
var silk = /Silk/.test(ua);
if (OS.windows || OS.macOS || OS.linux && !silk || OS.chromeOS) {
OS.desktop = true;
}
if (OS.windowsPhone || /Windows NT/i.test(ua) && /Touch/i.test(ua)) {
OS.desktop = false;
}
if (navigator.standalone) {
OS.webApp = true;
}
if (typeof importScripts !== "function") {
if (window.cordova !== void 0) {
OS.cordova = true;
}
if (window.ejecta !== void 0) {
OS.ejecta = true;
}
}
if (typeof process !== "undefined" && process.versions && process.versions.node) {
OS.node = true;
}
if (OS.node && typeof process.versions === "object") {
OS.nodeWebkit = !!process.versions["node-webkit"];
OS.electron = !!process.versions.electron;
}
if (/Crosswalk/.test(ua)) {
OS.crosswalk = true;
}
OS.pixelRatio = window["devicePixelRatio"] || 1;
return OS;
}
module2.exports = init();
}
),
/***/
43267: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetFastValue = __webpack_require__2(95540);
var Video = {
h264: false,
hls: false,
mp4: false,
m4v: false,
ogg: false,
vp9: false,
webm: false,
hasRequestVideoFrame: false
};
function init() {
if (typeof importScripts === "function") {
return Video;
}
var videoElement = document.createElement("video");
var result = !!videoElement.canPlayType;
var no = /^no$/;
try {
if (result) {
if (videoElement.canPlayType('video/ogg; codecs="theora"').replace(no, "")) {
Video.ogg = true;
}
if (videoElement.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(no, "")) {
Video.h264 = true;
Video.mp4 = true;
}
if (videoElement.canPlayType("video/x-m4v").replace(no, "")) {
Video.m4v = true;
}
if (videoElement.canPlayType('video/webm; codecs="vp8, vorbis"').replace(no, "")) {
Video.webm = true;
}
if (videoElement.canPlayType('video/webm; codecs="vp9"').replace(no, "")) {
Video.vp9 = true;
}
if (videoElement.canPlayType('application/x-mpegURL; codecs="avc1.42E01E"').replace(no, "")) {
Video.hls = true;
}
}
} catch (e) {
}
if (videoElement.parentNode) {
videoElement.parentNode.removeChild(videoElement);
}
Video.getVideoURL = function(urls) {
if (!Array.isArray(urls)) {
urls = [urls];
}
for (var i = 0; i < urls.length; i++) {
var url = GetFastValue(urls[i], "url", urls[i]);
if (url.indexOf("blob:") === 0) {
return {
url,
type: ""
};
}
var videoType;
if (url.indexOf("data:") === 0) {
videoType = url.split(",")[0].match(/\/(.*?);/);
} else {
videoType = url.match(/\.([a-zA-Z0-9]+)($|\?)/);
}
videoType = GetFastValue(urls[i], "type", videoType ? videoType[1] : "").toLowerCase();
if (Video[videoType]) {
return {
url,
type: videoType
};
}
}
return null;
};
return Video;
}
module2.exports = init();
}
),
/***/
82264: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
os: __webpack_require__2(25892),
browser: __webpack_require__2(84148),
features: __webpack_require__2(89357),
input: __webpack_require__2(31784),
audio: __webpack_require__2(7098),
video: __webpack_require__2(43267),
fullscreen: __webpack_require__2(91639),
canvasFeatures: __webpack_require__2(89289)
};
}
),
/***/
89422: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var tempMatrix = new Float32Array(20);
var ColorMatrix = new Class({
initialize: function ColorMatrix2() {
this._matrix = new Float32Array(20);
this.alpha = 1;
this._dirty = true;
this._data = new Float32Array(20);
this.reset();
},
/**
* Sets this ColorMatrix from the given array of color values.
*
* @method Phaser.Display.ColorMatrix#set
* @since 3.50.0
*
* @param {(number[]|Float32Array)} value - The ColorMatrix values to set. Must have 20 elements.
*
* @return {this} This ColorMatrix instance.
*/
set: function(value) {
this._matrix.set(value);
this._dirty = true;
return this;
},
/**
* Resets the ColorMatrix to default values and also resets
* the `alpha` property back to 1.
*
* @method Phaser.Display.ColorMatrix#reset
* @since 3.50.0
*
* @return {this} This ColorMatrix instance.
*/
reset: function() {
var m = this._matrix;
m.fill(0);
m[0] = 1;
m[6] = 1;
m[12] = 1;
m[18] = 1;
this.alpha = 1;
this._dirty = true;
return this;
},
/**
* Gets the ColorMatrix as a Float32Array.
*
* Can be used directly as a 1fv shader uniform value.
*
* @method Phaser.Display.ColorMatrix#getData
* @since 3.50.0
*
* @return {Float32Array} The ColorMatrix as a Float32Array.
*/
getData: function() {
var data = this._data;
if (this._dirty) {
data.set(this._matrix);
data[4] /= 255;
data[9] /= 255;
data[14] /= 255;
data[19] /= 255;
this._dirty = false;
}
return data;
},
/**
* Changes the brightness of this ColorMatrix by the given amount.
*
* @method Phaser.Display.ColorMatrix#brightness
* @since 3.50.0
*
* @param {number} [value=0] - The amount of brightness to apply to this ColorMatrix. Between 0 (black) and 1.
* @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
*
* @return {this} This ColorMatrix instance.
*/
brightness: function(value, multiply) {
if (value === void 0) {
value = 0;
}
if (multiply === void 0) {
multiply = false;
}
var b = value;
return this.multiply([
b,
0,
0,
0,
0,
0,
b,
0,
0,
0,
0,
0,
b,
0,
0,
0,
0,
0,
1,
0
], multiply);
},
/**
* Changes the saturation of this ColorMatrix by the given amount.
*
* @method Phaser.Display.ColorMatrix#saturate
* @since 3.50.0
*
* @param {number} [value=0] - The amount of saturation to apply to this ColorMatrix.
* @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
*
* @return {this} This ColorMatrix instance.
*/
saturate: function(value, multiply) {
if (value === void 0) {
value = 0;
}
if (multiply === void 0) {
multiply = false;
}
var x = value * 2 / 3 + 1;
var y = (x - 1) * -0.5;
return this.multiply([
x,
y,
y,
0,
0,
y,
x,
y,
0,
0,
y,
y,
x,
0,
0,
0,
0,
0,
1,
0
], multiply);
},
/**
* Desaturates this ColorMatrix (removes color from it).
*
* @method Phaser.Display.ColorMatrix#saturation
* @since 3.50.0
*
* @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
*
* @return {this} This ColorMatrix instance.
*/
desaturate: function(multiply) {
if (multiply === void 0) {
multiply = false;
}
return this.saturate(-1, multiply);
},
/**
* Rotates the hues of this ColorMatrix by the value given.
*
* @method Phaser.Display.ColorMatrix#hue
* @since 3.50.0
*
* @param {number} [rotation=0] - The amount of hue rotation to apply to this ColorMatrix, in degrees.
* @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
*
* @return {this} This ColorMatrix instance.
*/
hue: function(rotation, multiply) {
if (rotation === void 0) {
rotation = 0;
}
if (multiply === void 0) {
multiply = false;
}
rotation = rotation / 180 * Math.PI;
var cos = Math.cos(rotation);
var sin = Math.sin(rotation);
var lumR = 0.213;
var lumG = 0.715;
var lumB = 0.072;
return this.multiply([
lumR + cos * (1 - lumR) + sin * -lumR,
lumG + cos * -lumG + sin * -lumG,
lumB + cos * -lumB + sin * (1 - lumB),
0,
0,
lumR + cos * -lumR + sin * 0.143,
lumG + cos * (1 - lumG) + sin * 0.14,
lumB + cos * -lumB + sin * -0.283,
0,
0,
lumR + cos * -lumR + sin * -(1 - lumR),
lumG + cos * -lumG + sin * lumG,
lumB + cos * (1 - lumB) + sin * lumB,
0,
0,
0,
0,
0,
1,
0
], multiply);
},
/**
* Sets this ColorMatrix to be grayscale.
*
* @method Phaser.Display.ColorMatrix#grayscale
* @since 3.50.0
*
* @param {number} [value=1] - The grayscale scale (0 is black).
* @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
*
* @return {this} This ColorMatrix instance.
*/
grayscale: function(value, multiply) {
if (value === void 0) {
value = 1;
}
if (multiply === void 0) {
multiply = false;
}
return this.saturate(-value, multiply);
},
/**
* Sets this ColorMatrix to be black and white.
*
* @method Phaser.Display.ColorMatrix#blackWhite
* @since 3.50.0
*
* @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
*
* @return {this} This ColorMatrix instance.
*/
blackWhite: function(multiply) {
if (multiply === void 0) {
multiply = false;
}
return this.multiply(ColorMatrix.BLACK_WHITE, multiply);
},
/**
* Change the contrast of this ColorMatrix by the amount given.
*
* @method Phaser.Display.ColorMatrix#contrast
* @since 3.50.0
*
* @param {number} [value=0] - The amount of contrast to apply to this ColorMatrix.
* @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
*
* @return {this} This ColorMatrix instance.
*/
contrast: function(value, multiply) {
if (value === void 0) {
value = 0;
}
if (multiply === void 0) {
multiply = false;
}
var v = value + 1;
var o = -0.5 * (v - 1);
return this.multiply([
v,
0,
0,
0,
o,
0,
v,
0,
0,
o,
0,
0,
v,
0,
o,
0,
0,
0,
1,
0
], multiply);
},
/**
* Converts this ColorMatrix to have negative values.
*
* @method Phaser.Display.ColorMatrix#negative
* @since 3.50.0
*
* @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
*
* @return {this} This ColorMatrix instance.
*/
negative: function(multiply) {
if (multiply === void 0) {
multiply = false;
}
return this.multiply(ColorMatrix.NEGATIVE, multiply);
},
/**
* Apply a desaturated luminance to this ColorMatrix.
*
* @method Phaser.Display.ColorMatrix#desaturateLuminance
* @since 3.50.0
*
* @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
*
* @return {this} This ColorMatrix instance.
*/
desaturateLuminance: function(multiply) {
if (multiply === void 0) {
multiply = false;
}
return this.multiply(ColorMatrix.DESATURATE_LUMINANCE, multiply);
},
/**
* Applies a sepia tone to this ColorMatrix.
*
* @method Phaser.Display.ColorMatrix#sepia
* @since 3.50.0
*
* @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
*
* @return {this} This ColorMatrix instance.
*/
sepia: function(multiply) {
if (multiply === void 0) {
multiply = false;
}
return this.multiply(ColorMatrix.SEPIA, multiply);
},
/**
* Applies a night vision tone to this ColorMatrix.
*
* @method Phaser.Display.ColorMatrix#night
* @since 3.50.0
*
* @param {number} [intensity=0.1] - The intensity of this effect.
* @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
*
* @return {this} This ColorMatrix instance.
*/
night: function(intensity, multiply) {
if (intensity === void 0) {
intensity = 0.1;
}
if (multiply === void 0) {
multiply = false;
}
return this.multiply([
intensity * -2,
-intensity,
0,
0,
0,
-intensity,
0,
intensity,
0,
0,
0,
intensity,
intensity * 2,
0,
0,
0,
0,
0,
1,
0
], multiply);
},
/**
* Applies a trippy color tone to this ColorMatrix.
*
* @method Phaser.Display.ColorMatrix#lsd
* @since 3.50.0
*
* @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
*
* @return {this} This ColorMatrix instance.
*/
lsd: function(multiply) {
if (multiply === void 0) {
multiply = false;
}
return this.multiply(ColorMatrix.LSD, multiply);
},
/**
* Applies a brown tone to this ColorMatrix.
*
* @method Phaser.Display.ColorMatrix#brown
* @since 3.50.0
*
* @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
*
* @return {this} This ColorMatrix instance.
*/
brown: function(multiply) {
if (multiply === void 0) {
multiply = false;
}
return this.multiply(ColorMatrix.BROWN, multiply);
},
/**
* Applies a vintage pinhole color effect to this ColorMatrix.
*
* @method Phaser.Display.ColorMatrix#vintagePinhole
* @since 3.50.0
*
* @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
*
* @return {this} This ColorMatrix instance.
*/
vintagePinhole: function(multiply) {
if (multiply === void 0) {
multiply = false;
}
return this.multiply(ColorMatrix.VINTAGE, multiply);
},
/**
* Applies a kodachrome color effect to this ColorMatrix.
*
* @method Phaser.Display.ColorMatrix#kodachrome
* @since 3.50.0
*
* @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
*
* @return {this} This ColorMatrix instance.
*/
kodachrome: function(multiply) {
if (multiply === void 0) {
multiply = false;
}
return this.multiply(ColorMatrix.KODACHROME, multiply);
},
/**
* Applies a technicolor color effect to this ColorMatrix.
*
* @method Phaser.Display.ColorMatrix#technicolor
* @since 3.50.0
*
* @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
*
* @return {this} This ColorMatrix instance.
*/
technicolor: function(multiply) {
if (multiply === void 0) {
multiply = false;
}
return this.multiply(ColorMatrix.TECHNICOLOR, multiply);
},
/**
* Applies a polaroid color effect to this ColorMatrix.
*
* @method Phaser.Display.ColorMatrix#polaroid
* @since 3.50.0
*
* @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
*
* @return {this} This ColorMatrix instance.
*/
polaroid: function(multiply) {
if (multiply === void 0) {
multiply = false;
}
return this.multiply(ColorMatrix.POLAROID, multiply);
},
/**
* Shifts the values of this ColorMatrix into BGR order.
*
* @method Phaser.Display.ColorMatrix#shiftToBGR
* @since 3.50.0
*
* @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
*
* @return {this} This ColorMatrix instance.
*/
shiftToBGR: function(multiply) {
if (multiply === void 0) {
multiply = false;
}
return this.multiply(ColorMatrix.SHIFT_BGR, multiply);
},
/**
* Multiplies the two given matrices.
*
* @method Phaser.Display.ColorMatrix#multiply
* @since 3.50.0
*
* @param {number[]} a - The 5x4 array to multiply with ColorMatrix._matrix.
* @param {boolean} [multiply=false] - Multiply the resulting ColorMatrix (`true`), or set it (`false`) ?
*
* @return {this} This ColorMatrix instance.
*/
multiply: function(a, multiply) {
if (multiply === void 0) {
multiply = false;
}
if (!multiply) {
this.reset();
}
var m = this._matrix;
var c = tempMatrix;
c.set(m);
m.set([
// R
c[0] * a[0] + c[1] * a[5] + c[2] * a[10] + c[3] * a[15],
c[0] * a[1] + c[1] * a[6] + c[2] * a[11] + c[3] * a[16],
c[0] * a[2] + c[1] * a[7] + c[2] * a[12] + c[3] * a[17],
c[0] * a[3] + c[1] * a[8] + c[2] * a[13] + c[3] * a[18],
c[0] * a[4] + c[1] * a[9] + c[2] * a[14] + c[3] * a[19] + c[4],
// G
c[5] * a[0] + c[6] * a[5] + c[7] * a[10] + c[8] * a[15],
c[5] * a[1] + c[6] * a[6] + c[7] * a[11] + c[8] * a[16],
c[5] * a[2] + c[6] * a[7] + c[7] * a[12] + c[8] * a[17],
c[5] * a[3] + c[6] * a[8] + c[7] * a[13] + c[8] * a[18],
c[5] * a[4] + c[6] * a[9] + c[7] * a[14] + c[8] * a[19] + c[9],
// B
c[10] * a[0] + c[11] * a[5] + c[12] * a[10] + c[13] * a[15],
c[10] * a[1] + c[11] * a[6] + c[12] * a[11] + c[13] * a[16],
c[10] * a[2] + c[11] * a[7] + c[12] * a[12] + c[13] * a[17],
c[10] * a[3] + c[11] * a[8] + c[12] * a[13] + c[13] * a[18],
c[10] * a[4] + c[11] * a[9] + c[12] * a[14] + c[13] * a[19] + c[14],
// A
c[15] * a[0] + c[16] * a[5] + c[17] * a[10] + c[18] * a[15],
c[15] * a[1] + c[16] * a[6] + c[17] * a[11] + c[18] * a[16],
c[15] * a[2] + c[16] * a[7] + c[17] * a[12] + c[18] * a[17],
c[15] * a[3] + c[16] * a[8] + c[17] * a[13] + c[18] * a[18],
c[15] * a[4] + c[16] * a[9] + c[17] * a[14] + c[18] * a[19] + c[19]
]);
this._dirty = true;
return this;
}
});
ColorMatrix.BLACK_WHITE = [0.3, 0.6, 0.1, 0, 0, 0.3, 0.6, 0.1, 0, 0, 0.3, 0.6, 0.1, 0, 0, 0, 0, 0, 1, 0];
ColorMatrix.NEGATIVE = [-1, 0, 0, 1, 0, 0, -1, 0, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 1, 0];
ColorMatrix.DESATURATE_LUMINANCE = [0.2764723, 0.929708, 0.0938197, 0, -37.1, 0.2764723, 0.929708, 0.0938197, 0, -37.1, 0.2764723, 0.929708, 0.0938197, 0, -37.1, 0, 0, 0, 1, 0];
ColorMatrix.SEPIA = [0.393, 0.7689999, 0.18899999, 0, 0, 0.349, 0.6859999, 0.16799999, 0, 0, 0.272, 0.5339999, 0.13099999, 0, 0, 0, 0, 0, 1, 0];
ColorMatrix.LSD = [2, -0.4, 0.5, 0, 0, -0.5, 2, -0.4, 0, 0, -0.4, -0.5, 3, 0, 0, 0, 0, 0, 1, 0];
ColorMatrix.BROWN = [0.5997023498159715, 0.34553243048391263, -0.2708298674538042, 0, 47.43192855600873, -0.037703249837783157, 0.8609577587992641, 0.15059552388459913, 0, -36.96841498319127, 0.24113635128153335, -0.07441037908422492, 0.44972182064877153, 0, -7.562075277591283, 0, 0, 0, 1, 0];
ColorMatrix.VINTAGE = [0.6279345635605994, 0.3202183420819367, -0.03965408211312453, 0, 9.651285835294123, 0.02578397704808868, 0.6441188644374771, 0.03259127616149294, 0, 7.462829176470591, 0.0466055556782719, -0.0851232987247891, 0.5241648018700465, 0, 5.159190588235296, 0, 0, 0, 1, 0];
ColorMatrix.KODACHROME = [1.1285582396593525, -0.3967382283601348, -0.03992559172921793, 0, 63.72958762196502, -0.16404339962244616, 1.0835251566291304, -0.05498805115633132, 0, 24.732407896706203, -0.16786010706155763, -0.5603416277695248, 1.6014850761964943, 0, 35.62982807460946, 0, 0, 0, 1, 0];
ColorMatrix.TECHNICOLOR = [1.9125277891456083, -0.8545344976951645, -0.09155508482755585, 0, 11.793603434377337, -0.3087833385928097, 1.7658908555458428, -0.10601743074722245, 0, -70.35205161461398, -0.231103377548616, -0.7501899197440212, 1.847597816108189, 0, 30.950940869491138, 0, 0, 0, 1, 0];
ColorMatrix.POLAROID = [1.438, -0.062, -0.062, 0, 0, -0.122, 1.378, -0.122, 0, 0, -0.016, -0.016, 1.483, 0, 0, 0, 0, 0, 1, 0];
ColorMatrix.SHIFT_BGR = [0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0];
module2.exports = ColorMatrix;
}
),
/***/
51767: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var NOOP = __webpack_require__2(29747);
var RGB = new Class({
initialize: function RGB2(red, green, blue) {
this._rgb = [0, 0, 0];
this.onChangeCallback = NOOP;
this.dirty = false;
this.set(red, green, blue);
},
/**
* Sets the red, green and blue values of this RGB object, flags it as being
* dirty and then invokes the `onChangeCallback`, if set.
*
* @method Phaser.Display.RGB#set
* @since 3.50.0
*
* @param {number} [red=0] - The red color value. A number between 0 and 1.
* @param {number} [green=0] - The green color value. A number between 0 and 1.
* @param {number} [blue=0] - The blue color value. A number between 0 and 1.
*
* @return {this} This RGB instance.
*/
set: function(red, green, blue) {
if (red === void 0) {
red = 0;
}
if (green === void 0) {
green = 0;
}
if (blue === void 0) {
blue = 0;
}
this._rgb = [red, green, blue];
this.onChange();
return this;
},
/**
* Compares the given rgb parameters with those in this object and returns
* a boolean `true` value if they are equal, otherwise it returns `false`.
*
* @method Phaser.Display.RGB#equals
* @since 3.50.0
*
* @param {number} red - The red value to compare with this object.
* @param {number} green - The green value to compare with this object.
* @param {number} blue - The blue value to compare with this object.
*
* @return {boolean} `true` if the given values match those in this object, otherwise `false`.
*/
equals: function(red, green, blue) {
var rgb = this._rgb;
return rgb[0] === red && rgb[1] === green && rgb[2] === blue;
},
/**
* Internal on change handler. Sets this object as being dirty and
* then invokes the `onChangeCallback`, if set, passing in the
* new RGB values.
*
* @method Phaser.Display.RGB#onChange
* @since 3.50.0
*/
onChange: function() {
this.dirty = true;
var rgb = this._rgb;
this.onChangeCallback.call(this, rgb[0], rgb[1], rgb[2]);
},
/**
* The red color value. Between 0 and 1.
*
* Changing this property will flag this RGB object as being dirty
* and invoke the `onChangeCallback` , if set.
*
* @name Phaser.Display.RGB#r
* @type {number}
* @since 3.50.0
*/
r: {
get: function() {
return this._rgb[0];
},
set: function(value) {
this._rgb[0] = value;
this.onChange();
}
},
/**
* The green color value. Between 0 and 1.
*
* Changing this property will flag this RGB object as being dirty
* and invoke the `onChangeCallback` , if set.
*
* @name Phaser.Display.RGB#g
* @type {number}
* @since 3.50.0
*/
g: {
get: function() {
return this._rgb[1];
},
set: function(value) {
this._rgb[1] = value;
this.onChange();
}
},
/**
* The blue color value. Between 0 and 1.
*
* Changing this property will flag this RGB object as being dirty
* and invoke the `onChangeCallback` , if set.
*
* @name Phaser.Display.RGB#b
* @type {number}
* @since 3.50.0
*/
b: {
get: function() {
return this._rgb[2];
},
set: function(value) {
this._rgb[2] = value;
this.onChange();
}
},
/**
* Nulls any external references this object contains.
*
* @method Phaser.Display.RGB#destroy
* @since 3.50.0
*/
destroy: function() {
this.onChangeCallback = null;
}
});
module2.exports = RGB;
}
),
/***/
60461: (
/***/
(module2) => {
var ALIGN_CONST = {
/**
* A constant representing a top-left alignment or position.
* @constant
* @name Phaser.Display.Align.TOP_LEFT
* @since 3.0.0
* @type {number}
*/
TOP_LEFT: 0,
/**
* A constant representing a top-center alignment or position.
* @constant
* @name Phaser.Display.Align.TOP_CENTER
* @since 3.0.0
* @type {number}
*/
TOP_CENTER: 1,
/**
* A constant representing a top-right alignment or position.
* @constant
* @name Phaser.Display.Align.TOP_RIGHT
* @since 3.0.0
* @type {number}
*/
TOP_RIGHT: 2,
/**
* A constant representing a left-top alignment or position.
* @constant
* @name Phaser.Display.Align.LEFT_TOP
* @since 3.0.0
* @type {number}
*/
LEFT_TOP: 3,
/**
* A constant representing a left-center alignment or position.
* @constant
* @name Phaser.Display.Align.LEFT_CENTER
* @since 3.0.0
* @type {number}
*/
LEFT_CENTER: 4,
/**
* A constant representing a left-bottom alignment or position.
* @constant
* @name Phaser.Display.Align.LEFT_BOTTOM
* @since 3.0.0
* @type {number}
*/
LEFT_BOTTOM: 5,
/**
* A constant representing a center alignment or position.
* @constant
* @name Phaser.Display.Align.CENTER
* @since 3.0.0
* @type {number}
*/
CENTER: 6,
/**
* A constant representing a right-top alignment or position.
* @constant
* @name Phaser.Display.Align.RIGHT_TOP
* @since 3.0.0
* @type {number}
*/
RIGHT_TOP: 7,
/**
* A constant representing a right-center alignment or position.
* @constant
* @name Phaser.Display.Align.RIGHT_CENTER
* @since 3.0.0
* @type {number}
*/
RIGHT_CENTER: 8,
/**
* A constant representing a right-bottom alignment or position.
* @constant
* @name Phaser.Display.Align.RIGHT_BOTTOM
* @since 3.0.0
* @type {number}
*/
RIGHT_BOTTOM: 9,
/**
* A constant representing a bottom-left alignment or position.
* @constant
* @name Phaser.Display.Align.BOTTOM_LEFT
* @since 3.0.0
* @type {number}
*/
BOTTOM_LEFT: 10,
/**
* A constant representing a bottom-center alignment or position.
* @constant
* @name Phaser.Display.Align.BOTTOM_CENTER
* @since 3.0.0
* @type {number}
*/
BOTTOM_CENTER: 11,
/**
* A constant representing a bottom-right alignment or position.
* @constant
* @name Phaser.Display.Align.BOTTOM_RIGHT
* @since 3.0.0
* @type {number}
*/
BOTTOM_RIGHT: 12
};
module2.exports = ALIGN_CONST;
}
),
/***/
54312: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetBottom = __webpack_require__2(62235);
var GetCenterX = __webpack_require__2(35893);
var SetBottom = __webpack_require__2(86327);
var SetCenterX = __webpack_require__2(88417);
var BottomCenter = function(gameObject, alignIn, offsetX, offsetY) {
if (offsetX === void 0) {
offsetX = 0;
}
if (offsetY === void 0) {
offsetY = 0;
}
SetCenterX(gameObject, GetCenterX(alignIn) + offsetX);
SetBottom(gameObject, GetBottom(alignIn) + offsetY);
return gameObject;
};
module2.exports = BottomCenter;
}
),
/***/
46768: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetBottom = __webpack_require__2(62235);
var GetLeft = __webpack_require__2(26541);
var SetBottom = __webpack_require__2(86327);
var SetLeft = __webpack_require__2(385);
var BottomLeft = function(gameObject, alignIn, offsetX, offsetY) {
if (offsetX === void 0) {
offsetX = 0;
}
if (offsetY === void 0) {
offsetY = 0;
}
SetLeft(gameObject, GetLeft(alignIn) - offsetX);
SetBottom(gameObject, GetBottom(alignIn) + offsetY);
return gameObject;
};
module2.exports = BottomLeft;
}
),
/***/
35827: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetBottom = __webpack_require__2(62235);
var GetRight = __webpack_require__2(54380);
var SetBottom = __webpack_require__2(86327);
var SetRight = __webpack_require__2(40136);
var BottomRight = function(gameObject, alignIn, offsetX, offsetY) {
if (offsetX === void 0) {
offsetX = 0;
}
if (offsetY === void 0) {
offsetY = 0;
}
SetRight(gameObject, GetRight(alignIn) + offsetX);
SetBottom(gameObject, GetBottom(alignIn) + offsetY);
return gameObject;
};
module2.exports = BottomRight;
}
),
/***/
46871: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CenterOn = __webpack_require__2(66786);
var GetCenterX = __webpack_require__2(35893);
var GetCenterY = __webpack_require__2(7702);
var Center = function(gameObject, alignIn, offsetX, offsetY) {
if (offsetX === void 0) {
offsetX = 0;
}
if (offsetY === void 0) {
offsetY = 0;
}
CenterOn(gameObject, GetCenterX(alignIn) + offsetX, GetCenterY(alignIn) + offsetY);
return gameObject;
};
module2.exports = Center;
}
),
/***/
5198: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetCenterY = __webpack_require__2(7702);
var GetLeft = __webpack_require__2(26541);
var SetCenterY = __webpack_require__2(20786);
var SetLeft = __webpack_require__2(385);
var LeftCenter = function(gameObject, alignIn, offsetX, offsetY) {
if (offsetX === void 0) {
offsetX = 0;
}
if (offsetY === void 0) {
offsetY = 0;
}
SetLeft(gameObject, GetLeft(alignIn) - offsetX);
SetCenterY(gameObject, GetCenterY(alignIn) + offsetY);
return gameObject;
};
module2.exports = LeftCenter;
}
),
/***/
11879: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var ALIGN_CONST = __webpack_require__2(60461);
var AlignInMap = [];
AlignInMap[ALIGN_CONST.BOTTOM_CENTER] = __webpack_require__2(54312);
AlignInMap[ALIGN_CONST.BOTTOM_LEFT] = __webpack_require__2(46768);
AlignInMap[ALIGN_CONST.BOTTOM_RIGHT] = __webpack_require__2(35827);
AlignInMap[ALIGN_CONST.CENTER] = __webpack_require__2(46871);
AlignInMap[ALIGN_CONST.LEFT_CENTER] = __webpack_require__2(5198);
AlignInMap[ALIGN_CONST.RIGHT_CENTER] = __webpack_require__2(80503);
AlignInMap[ALIGN_CONST.TOP_CENTER] = __webpack_require__2(89698);
AlignInMap[ALIGN_CONST.TOP_LEFT] = __webpack_require__2(922);
AlignInMap[ALIGN_CONST.TOP_RIGHT] = __webpack_require__2(21373);
AlignInMap[ALIGN_CONST.LEFT_BOTTOM] = AlignInMap[ALIGN_CONST.BOTTOM_LEFT];
AlignInMap[ALIGN_CONST.LEFT_TOP] = AlignInMap[ALIGN_CONST.TOP_LEFT];
AlignInMap[ALIGN_CONST.RIGHT_BOTTOM] = AlignInMap[ALIGN_CONST.BOTTOM_RIGHT];
AlignInMap[ALIGN_CONST.RIGHT_TOP] = AlignInMap[ALIGN_CONST.TOP_RIGHT];
var QuickSet = function(child, alignIn, position, offsetX, offsetY) {
return AlignInMap[position](child, alignIn, offsetX, offsetY);
};
module2.exports = QuickSet;
}
),
/***/
80503: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetCenterY = __webpack_require__2(7702);
var GetRight = __webpack_require__2(54380);
var SetCenterY = __webpack_require__2(20786);
var SetRight = __webpack_require__2(40136);
var RightCenter = function(gameObject, alignIn, offsetX, offsetY) {
if (offsetX === void 0) {
offsetX = 0;
}
if (offsetY === void 0) {
offsetY = 0;
}
SetRight(gameObject, GetRight(alignIn) + offsetX);
SetCenterY(gameObject, GetCenterY(alignIn) + offsetY);
return gameObject;
};
module2.exports = RightCenter;
}
),
/***/
89698: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetCenterX = __webpack_require__2(35893);
var GetTop = __webpack_require__2(17717);
var SetCenterX = __webpack_require__2(88417);
var SetTop = __webpack_require__2(66737);
var TopCenter = function(gameObject, alignIn, offsetX, offsetY) {
if (offsetX === void 0) {
offsetX = 0;
}
if (offsetY === void 0) {
offsetY = 0;
}
SetCenterX(gameObject, GetCenterX(alignIn) + offsetX);
SetTop(gameObject, GetTop(alignIn) - offsetY);
return gameObject;
};
module2.exports = TopCenter;
}
),
/***/
922: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetLeft = __webpack_require__2(26541);
var GetTop = __webpack_require__2(17717);
var SetLeft = __webpack_require__2(385);
var SetTop = __webpack_require__2(66737);
var TopLeft = function(gameObject, alignIn, offsetX, offsetY) {
if (offsetX === void 0) {
offsetX = 0;
}
if (offsetY === void 0) {
offsetY = 0;
}
SetLeft(gameObject, GetLeft(alignIn) - offsetX);
SetTop(gameObject, GetTop(alignIn) - offsetY);
return gameObject;
};
module2.exports = TopLeft;
}
),
/***/
21373: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetRight = __webpack_require__2(54380);
var GetTop = __webpack_require__2(17717);
var SetRight = __webpack_require__2(40136);
var SetTop = __webpack_require__2(66737);
var TopRight = function(gameObject, alignIn, offsetX, offsetY) {
if (offsetX === void 0) {
offsetX = 0;
}
if (offsetY === void 0) {
offsetY = 0;
}
SetRight(gameObject, GetRight(alignIn) + offsetX);
SetTop(gameObject, GetTop(alignIn) - offsetY);
return gameObject;
};
module2.exports = TopRight;
}
),
/***/
91660: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
BottomCenter: __webpack_require__2(54312),
BottomLeft: __webpack_require__2(46768),
BottomRight: __webpack_require__2(35827),
Center: __webpack_require__2(46871),
LeftCenter: __webpack_require__2(5198),
QuickSet: __webpack_require__2(11879),
RightCenter: __webpack_require__2(80503),
TopCenter: __webpack_require__2(89698),
TopLeft: __webpack_require__2(922),
TopRight: __webpack_require__2(21373)
};
}
),
/***/
71926: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(60461);
var Extend = __webpack_require__2(79291);
var Align = {
In: __webpack_require__2(91660),
To: __webpack_require__2(16694)
};
Align = Extend(false, Align, CONST);
module2.exports = Align;
}
),
/***/
21578: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetBottom = __webpack_require__2(62235);
var GetCenterX = __webpack_require__2(35893);
var SetCenterX = __webpack_require__2(88417);
var SetTop = __webpack_require__2(66737);
var BottomCenter = function(gameObject, alignTo, offsetX, offsetY) {
if (offsetX === void 0) {
offsetX = 0;
}
if (offsetY === void 0) {
offsetY = 0;
}
SetCenterX(gameObject, GetCenterX(alignTo) + offsetX);
SetTop(gameObject, GetBottom(alignTo) + offsetY);
return gameObject;
};
module2.exports = BottomCenter;
}
),
/***/
10210: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetBottom = __webpack_require__2(62235);
var GetLeft = __webpack_require__2(26541);
var SetLeft = __webpack_require__2(385);
var SetTop = __webpack_require__2(66737);
var BottomLeft = function(gameObject, alignTo, offsetX, offsetY) {
if (offsetX === void 0) {
offsetX = 0;
}
if (offsetY === void 0) {
offsetY = 0;
}
SetLeft(gameObject, GetLeft(alignTo) - offsetX);
SetTop(gameObject, GetBottom(alignTo) + offsetY);
return gameObject;
};
module2.exports = BottomLeft;
}
),
/***/
82341: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetBottom = __webpack_require__2(62235);
var GetRight = __webpack_require__2(54380);
var SetRight = __webpack_require__2(40136);
var SetTop = __webpack_require__2(66737);
var BottomRight = function(gameObject, alignTo, offsetX, offsetY) {
if (offsetX === void 0) {
offsetX = 0;
}
if (offsetY === void 0) {
offsetY = 0;
}
SetRight(gameObject, GetRight(alignTo) + offsetX);
SetTop(gameObject, GetBottom(alignTo) + offsetY);
return gameObject;
};
module2.exports = BottomRight;
}
),
/***/
87958: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetBottom = __webpack_require__2(62235);
var GetLeft = __webpack_require__2(26541);
var SetBottom = __webpack_require__2(86327);
var SetRight = __webpack_require__2(40136);
var LeftBottom = function(gameObject, alignTo, offsetX, offsetY) {
if (offsetX === void 0) {
offsetX = 0;
}
if (offsetY === void 0) {
offsetY = 0;
}
SetRight(gameObject, GetLeft(alignTo) - offsetX);
SetBottom(gameObject, GetBottom(alignTo) + offsetY);
return gameObject;
};
module2.exports = LeftBottom;
}
),
/***/
40080: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetCenterY = __webpack_require__2(7702);
var GetLeft = __webpack_require__2(26541);
var SetCenterY = __webpack_require__2(20786);
var SetRight = __webpack_require__2(40136);
var LeftCenter = function(gameObject, alignTo, offsetX, offsetY) {
if (offsetX === void 0) {
offsetX = 0;
}
if (offsetY === void 0) {
offsetY = 0;
}
SetRight(gameObject, GetLeft(alignTo) - offsetX);
SetCenterY(gameObject, GetCenterY(alignTo) + offsetY);
return gameObject;
};
module2.exports = LeftCenter;
}
),
/***/
88466: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetLeft = __webpack_require__2(26541);
var GetTop = __webpack_require__2(17717);
var SetRight = __webpack_require__2(40136);
var SetTop = __webpack_require__2(66737);
var LeftTop = function(gameObject, alignTo, offsetX, offsetY) {
if (offsetX === void 0) {
offsetX = 0;
}
if (offsetY === void 0) {
offsetY = 0;
}
SetRight(gameObject, GetLeft(alignTo) - offsetX);
SetTop(gameObject, GetTop(alignTo) - offsetY);
return gameObject;
};
module2.exports = LeftTop;
}
),
/***/
38829: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var ALIGN_CONST = __webpack_require__2(60461);
var AlignToMap = [];
AlignToMap[ALIGN_CONST.BOTTOM_CENTER] = __webpack_require__2(21578);
AlignToMap[ALIGN_CONST.BOTTOM_LEFT] = __webpack_require__2(10210);
AlignToMap[ALIGN_CONST.BOTTOM_RIGHT] = __webpack_require__2(82341);
AlignToMap[ALIGN_CONST.LEFT_BOTTOM] = __webpack_require__2(87958);
AlignToMap[ALIGN_CONST.LEFT_CENTER] = __webpack_require__2(40080);
AlignToMap[ALIGN_CONST.LEFT_TOP] = __webpack_require__2(88466);
AlignToMap[ALIGN_CONST.RIGHT_BOTTOM] = __webpack_require__2(19211);
AlignToMap[ALIGN_CONST.RIGHT_CENTER] = __webpack_require__2(34609);
AlignToMap[ALIGN_CONST.RIGHT_TOP] = __webpack_require__2(48741);
AlignToMap[ALIGN_CONST.TOP_CENTER] = __webpack_require__2(49440);
AlignToMap[ALIGN_CONST.TOP_LEFT] = __webpack_require__2(81288);
AlignToMap[ALIGN_CONST.TOP_RIGHT] = __webpack_require__2(61323);
var QuickSet = function(child, alignTo, position, offsetX, offsetY) {
return AlignToMap[position](child, alignTo, offsetX, offsetY);
};
module2.exports = QuickSet;
}
),
/***/
19211: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetBottom = __webpack_require__2(62235);
var GetRight = __webpack_require__2(54380);
var SetBottom = __webpack_require__2(86327);
var SetLeft = __webpack_require__2(385);
var RightBottom = function(gameObject, alignTo, offsetX, offsetY) {
if (offsetX === void 0) {
offsetX = 0;
}
if (offsetY === void 0) {
offsetY = 0;
}
SetLeft(gameObject, GetRight(alignTo) + offsetX);
SetBottom(gameObject, GetBottom(alignTo) + offsetY);
return gameObject;
};
module2.exports = RightBottom;
}
),
/***/
34609: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetCenterY = __webpack_require__2(7702);
var GetRight = __webpack_require__2(54380);
var SetCenterY = __webpack_require__2(20786);
var SetLeft = __webpack_require__2(385);
var RightCenter = function(gameObject, alignTo, offsetX, offsetY) {
if (offsetX === void 0) {
offsetX = 0;
}
if (offsetY === void 0) {
offsetY = 0;
}
SetLeft(gameObject, GetRight(alignTo) + offsetX);
SetCenterY(gameObject, GetCenterY(alignTo) + offsetY);
return gameObject;
};
module2.exports = RightCenter;
}
),
/***/
48741: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetRight = __webpack_require__2(54380);
var GetTop = __webpack_require__2(17717);
var SetLeft = __webpack_require__2(385);
var SetTop = __webpack_require__2(66737);
var RightTop = function(gameObject, alignTo, offsetX, offsetY) {
if (offsetX === void 0) {
offsetX = 0;
}
if (offsetY === void 0) {
offsetY = 0;
}
SetLeft(gameObject, GetRight(alignTo) + offsetX);
SetTop(gameObject, GetTop(alignTo) - offsetY);
return gameObject;
};
module2.exports = RightTop;
}
),
/***/
49440: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetCenterX = __webpack_require__2(35893);
var GetTop = __webpack_require__2(17717);
var SetBottom = __webpack_require__2(86327);
var SetCenterX = __webpack_require__2(88417);
var TopCenter = function(gameObject, alignTo, offsetX, offsetY) {
if (offsetX === void 0) {
offsetX = 0;
}
if (offsetY === void 0) {
offsetY = 0;
}
SetCenterX(gameObject, GetCenterX(alignTo) + offsetX);
SetBottom(gameObject, GetTop(alignTo) - offsetY);
return gameObject;
};
module2.exports = TopCenter;
}
),
/***/
81288: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetLeft = __webpack_require__2(26541);
var GetTop = __webpack_require__2(17717);
var SetBottom = __webpack_require__2(86327);
var SetLeft = __webpack_require__2(385);
var TopLeft = function(gameObject, alignTo, offsetX, offsetY) {
if (offsetX === void 0) {
offsetX = 0;
}
if (offsetY === void 0) {
offsetY = 0;
}
SetLeft(gameObject, GetLeft(alignTo) - offsetX);
SetBottom(gameObject, GetTop(alignTo) - offsetY);
return gameObject;
};
module2.exports = TopLeft;
}
),
/***/
61323: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetRight = __webpack_require__2(54380);
var GetTop = __webpack_require__2(17717);
var SetBottom = __webpack_require__2(86327);
var SetRight = __webpack_require__2(40136);
var TopRight = function(gameObject, alignTo, offsetX, offsetY) {
if (offsetX === void 0) {
offsetX = 0;
}
if (offsetY === void 0) {
offsetY = 0;
}
SetRight(gameObject, GetRight(alignTo) + offsetX);
SetBottom(gameObject, GetTop(alignTo) - offsetY);
return gameObject;
};
module2.exports = TopRight;
}
),
/***/
16694: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
BottomCenter: __webpack_require__2(21578),
BottomLeft: __webpack_require__2(10210),
BottomRight: __webpack_require__2(82341),
LeftBottom: __webpack_require__2(87958),
LeftCenter: __webpack_require__2(40080),
LeftTop: __webpack_require__2(88466),
QuickSet: __webpack_require__2(38829),
RightBottom: __webpack_require__2(19211),
RightCenter: __webpack_require__2(34609),
RightTop: __webpack_require__2(48741),
TopCenter: __webpack_require__2(49440),
TopLeft: __webpack_require__2(81288),
TopRight: __webpack_require__2(61323)
};
}
),
/***/
66786: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var SetCenterX = __webpack_require__2(88417);
var SetCenterY = __webpack_require__2(20786);
var CenterOn = function(gameObject, x, y) {
SetCenterX(gameObject, x);
return SetCenterY(gameObject, y);
};
module2.exports = CenterOn;
}
),
/***/
62235: (
/***/
(module2) => {
var GetBottom = function(gameObject) {
return gameObject.y + gameObject.height - gameObject.height * gameObject.originY;
};
module2.exports = GetBottom;
}
),
/***/
72873: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetBottom = __webpack_require__2(62235);
var GetLeft = __webpack_require__2(26541);
var GetRight = __webpack_require__2(54380);
var GetTop = __webpack_require__2(17717);
var Rectangle = __webpack_require__2(87841);
var GetBounds = function(gameObject, output) {
if (output === void 0) {
output = new Rectangle();
}
var left = GetLeft(gameObject);
var top = GetTop(gameObject);
output.x = left;
output.y = top;
output.width = GetRight(gameObject) - left;
output.height = GetBottom(gameObject) - top;
return output;
};
module2.exports = GetBounds;
}
),
/***/
35893: (
/***/
(module2) => {
var GetCenterX = function(gameObject) {
return gameObject.x - gameObject.width * gameObject.originX + gameObject.width * 0.5;
};
module2.exports = GetCenterX;
}
),
/***/
7702: (
/***/
(module2) => {
var GetCenterY = function(gameObject) {
return gameObject.y - gameObject.height * gameObject.originY + gameObject.height * 0.5;
};
module2.exports = GetCenterY;
}
),
/***/
26541: (
/***/
(module2) => {
var GetLeft = function(gameObject) {
return gameObject.x - gameObject.width * gameObject.originX;
};
module2.exports = GetLeft;
}
),
/***/
87431: (
/***/
(module2) => {
var GetOffsetX = function(gameObject) {
return gameObject.width * gameObject.originX;
};
module2.exports = GetOffsetX;
}
),
/***/
46928: (
/***/
(module2) => {
var GetOffsetY = function(gameObject) {
return gameObject.height * gameObject.originY;
};
module2.exports = GetOffsetY;
}
),
/***/
54380: (
/***/
(module2) => {
var GetRight = function(gameObject) {
return gameObject.x + gameObject.width - gameObject.width * gameObject.originX;
};
module2.exports = GetRight;
}
),
/***/
17717: (
/***/
(module2) => {
var GetTop = function(gameObject) {
return gameObject.y - gameObject.height * gameObject.originY;
};
module2.exports = GetTop;
}
),
/***/
86327: (
/***/
(module2) => {
var SetBottom = function(gameObject, value) {
gameObject.y = value - gameObject.height + gameObject.height * gameObject.originY;
return gameObject;
};
module2.exports = SetBottom;
}
),
/***/
88417: (
/***/
(module2) => {
var SetCenterX = function(gameObject, x) {
var offsetX = gameObject.width * gameObject.originX;
gameObject.x = x + offsetX - gameObject.width * 0.5;
return gameObject;
};
module2.exports = SetCenterX;
}
),
/***/
20786: (
/***/
(module2) => {
var SetCenterY = function(gameObject, y) {
var offsetY = gameObject.height * gameObject.originY;
gameObject.y = y + offsetY - gameObject.height * 0.5;
return gameObject;
};
module2.exports = SetCenterY;
}
),
/***/
385: (
/***/
(module2) => {
var SetLeft = function(gameObject, value) {
gameObject.x = value + gameObject.width * gameObject.originX;
return gameObject;
};
module2.exports = SetLeft;
}
),
/***/
40136: (
/***/
(module2) => {
var SetRight = function(gameObject, value) {
gameObject.x = value - gameObject.width + gameObject.width * gameObject.originX;
return gameObject;
};
module2.exports = SetRight;
}
),
/***/
66737: (
/***/
(module2) => {
var SetTop = function(gameObject, value) {
gameObject.y = value + gameObject.height * gameObject.originY;
return gameObject;
};
module2.exports = SetTop;
}
),
/***/
58724: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
CenterOn: __webpack_require__2(66786),
GetBottom: __webpack_require__2(62235),
GetBounds: __webpack_require__2(72873),
GetCenterX: __webpack_require__2(35893),
GetCenterY: __webpack_require__2(7702),
GetLeft: __webpack_require__2(26541),
GetOffsetX: __webpack_require__2(87431),
GetOffsetY: __webpack_require__2(46928),
GetRight: __webpack_require__2(54380),
GetTop: __webpack_require__2(17717),
SetBottom: __webpack_require__2(86327),
SetCenterX: __webpack_require__2(88417),
SetCenterY: __webpack_require__2(20786),
SetLeft: __webpack_require__2(385),
SetRight: __webpack_require__2(40136),
SetTop: __webpack_require__2(66737)
};
}
),
/***/
20623: (
/***/
(module2) => {
var CanvasInterpolation = {
/**
* Sets the CSS image-rendering property on the given canvas to be 'crisp' (aka 'optimize contrast' on webkit).
*
* @function Phaser.Display.Canvas.CanvasInterpolation.setCrisp
* @since 3.0.0
*
* @param {HTMLCanvasElement} canvas - The canvas object to have the style set on.
*
* @return {HTMLCanvasElement} The canvas.
*/
setCrisp: function(canvas) {
var types = ["optimizeSpeed", "-moz-crisp-edges", "-o-crisp-edges", "-webkit-optimize-contrast", "optimize-contrast", "crisp-edges", "pixelated"];
types.forEach(function(type) {
canvas.style["image-rendering"] = type;
});
canvas.style.msInterpolationMode = "nearest-neighbor";
return canvas;
},
/**
* Sets the CSS image-rendering property on the given canvas to be 'bicubic' (aka 'auto').
*
* @function Phaser.Display.Canvas.CanvasInterpolation.setBicubic
* @since 3.0.0
*
* @param {HTMLCanvasElement} canvas - The canvas object to have the style set on.
*
* @return {HTMLCanvasElement} The canvas.
*/
setBicubic: function(canvas) {
canvas.style["image-rendering"] = "auto";
canvas.style.msInterpolationMode = "bicubic";
return canvas;
}
};
module2.exports = CanvasInterpolation;
}
),
/***/
27919: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(8054);
var Smoothing = __webpack_require__2(68703);
var pool = [];
var _disableContextSmoothing = false;
var CanvasPool = function() {
var create = function(parent, width, height, canvasType, selfParent) {
if (width === void 0) {
width = 1;
}
if (height === void 0) {
height = 1;
}
if (canvasType === void 0) {
canvasType = CONST.CANVAS;
}
if (selfParent === void 0) {
selfParent = false;
}
var canvas;
var container = first(canvasType);
if (container === null) {
container = {
parent,
canvas: document.createElement("canvas"),
type: canvasType
};
if (canvasType === CONST.CANVAS) {
pool.push(container);
}
canvas = container.canvas;
} else {
container.parent = parent;
canvas = container.canvas;
}
if (selfParent) {
container.parent = canvas;
}
canvas.width = width;
canvas.height = height;
if (_disableContextSmoothing && canvasType === CONST.CANVAS) {
Smoothing.disable(canvas.getContext("2d", { willReadFrequently: false }));
}
return canvas;
};
var create2D = function(parent, width, height) {
return create(parent, width, height, CONST.CANVAS);
};
var createWebGL = function(parent, width, height) {
return create(parent, width, height, CONST.WEBGL);
};
var first = function(canvasType) {
if (canvasType === void 0) {
canvasType = CONST.CANVAS;
}
if (canvasType === CONST.WEBGL) {
return null;
}
for (var i = 0; i < pool.length; i++) {
var container = pool[i];
if (!container.parent && container.type === canvasType) {
return container;
}
}
return null;
};
var remove = function(parent) {
var isCanvas = parent instanceof HTMLCanvasElement;
pool.forEach(function(container) {
if (isCanvas && container.canvas === parent || !isCanvas && container.parent === parent) {
container.parent = null;
container.canvas.width = 1;
container.canvas.height = 1;
}
});
};
var total = function() {
var c = 0;
pool.forEach(function(container) {
if (container.parent) {
c++;
}
});
return c;
};
var free = function() {
return pool.length - total();
};
var disableSmoothing = function() {
_disableContextSmoothing = true;
};
var enableSmoothing = function() {
_disableContextSmoothing = false;
};
return {
create2D,
create,
createWebGL,
disableSmoothing,
enableSmoothing,
first,
free,
pool,
remove,
total
};
};
module2.exports = CanvasPool();
}
),
/***/
68703: (
/***/
(module2) => {
var prefix = "";
var Smoothing = function() {
var getPrefix = function(context) {
var vendors = ["i", "webkitI", "msI", "mozI", "oI"];
for (var i = 0; i < vendors.length; i++) {
var s = vendors[i] + "mageSmoothingEnabled";
if (s in context) {
return s;
}
}
return null;
};
var enable = function(context) {
if (prefix === "") {
prefix = getPrefix(context);
}
if (prefix) {
context[prefix] = true;
}
return context;
};
var disable = function(context) {
if (prefix === "") {
prefix = getPrefix(context);
}
if (prefix) {
context[prefix] = false;
}
return context;
};
var isEnabled = function(context) {
return prefix !== null ? context[prefix] : null;
};
return {
disable,
enable,
getPrefix,
isEnabled
};
};
module2.exports = Smoothing();
}
),
/***/
65208: (
/***/
(module2) => {
var TouchAction = function(canvas, value) {
if (value === void 0) {
value = "none";
}
canvas.style["msTouchAction"] = value;
canvas.style["ms-touch-action"] = value;
canvas.style["touch-action"] = value;
return canvas;
};
module2.exports = TouchAction;
}
),
/***/
91610: (
/***/
(module2) => {
var UserSelect = function(canvas, value) {
if (value === void 0) {
value = "none";
}
var vendors = [
"-webkit-",
"-khtml-",
"-moz-",
"-ms-",
""
];
vendors.forEach(function(vendor) {
canvas.style[vendor + "user-select"] = value;
});
canvas.style["-webkit-touch-callout"] = value;
canvas.style["-webkit-tap-highlight-color"] = "rgba(0, 0, 0, 0)";
return canvas;
};
module2.exports = UserSelect;
}
),
/***/
26253: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
CanvasInterpolation: __webpack_require__2(20623),
CanvasPool: __webpack_require__2(27919),
Smoothing: __webpack_require__2(68703),
TouchAction: __webpack_require__2(65208),
UserSelect: __webpack_require__2(91610)
};
}
),
/***/
40987: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var GetColor = __webpack_require__2(37589);
var GetColor32 = __webpack_require__2(1e3);
var HSVToRGB = __webpack_require__2(7537);
var RGBToHSV = __webpack_require__2(87837);
var Color = new Class({
initialize: function Color2(red, green, blue, alpha) {
if (red === void 0) {
red = 0;
}
if (green === void 0) {
green = 0;
}
if (blue === void 0) {
blue = 0;
}
if (alpha === void 0) {
alpha = 255;
}
this.r = 0;
this.g = 0;
this.b = 0;
this.a = 255;
this._h = 0;
this._s = 0;
this._v = 0;
this._locked = false;
this.gl = [0, 0, 0, 1];
this._color = 0;
this._color32 = 0;
this._rgba = "";
this.setTo(red, green, blue, alpha);
},
/**
* Sets this color to be transparent. Sets all values to zero.
*
* @method Phaser.Display.Color#transparent
* @since 3.0.0
*
* @return {Phaser.Display.Color} This Color object.
*/
transparent: function() {
this._locked = true;
this.red = 0;
this.green = 0;
this.blue = 0;
this.alpha = 0;
this._locked = false;
return this.update(true);
},
/**
* Sets the color of this Color component.
*
* @method Phaser.Display.Color#setTo
* @since 3.0.0
*
* @param {number} red - The red color value. A number between 0 and 255.
* @param {number} green - The green color value. A number between 0 and 255.
* @param {number} blue - The blue color value. A number between 0 and 255.
* @param {number} [alpha=255] - The alpha value. A number between 0 and 255.
* @param {boolean} [updateHSV=true] - Update the HSV values after setting the RGB values?
*
* @return {Phaser.Display.Color} This Color object.
*/
setTo: function(red, green, blue, alpha, updateHSV) {
if (alpha === void 0) {
alpha = 255;
}
if (updateHSV === void 0) {
updateHSV = true;
}
this._locked = true;
this.red = red;
this.green = green;
this.blue = blue;
this.alpha = alpha;
this._locked = false;
return this.update(updateHSV);
},
/**
* Sets the red, green, blue and alpha GL values of this Color component.
*
* @method Phaser.Display.Color#setGLTo
* @since 3.0.0
*
* @param {number} red - The red color value. A number between 0 and 1.
* @param {number} green - The green color value. A number between 0 and 1.
* @param {number} blue - The blue color value. A number between 0 and 1.
* @param {number} [alpha=1] - The alpha value. A number between 0 and 1.
*
* @return {Phaser.Display.Color} This Color object.
*/
setGLTo: function(red, green, blue, alpha) {
if (alpha === void 0) {
alpha = 1;
}
this._locked = true;
this.redGL = red;
this.greenGL = green;
this.blueGL = blue;
this.alphaGL = alpha;
this._locked = false;
return this.update(true);
},
/**
* Sets the color based on the color object given.
*
* @method Phaser.Display.Color#setFromRGB
* @since 3.0.0
*
* @param {Phaser.Types.Display.InputColorObject} color - An object containing `r`, `g`, `b` and optionally `a` values in the range 0 to 255.
*
* @return {Phaser.Display.Color} This Color object.
*/
setFromRGB: function(color) {
this._locked = true;
this.red = color.r;
this.green = color.g;
this.blue = color.b;
if (color.hasOwnProperty("a")) {
this.alpha = color.a;
}
this._locked = false;
return this.update(true);
},
/**
* Sets the color based on the hue, saturation and lightness values given.
*
* @method Phaser.Display.Color#setFromHSV
* @since 3.13.0
*
* @param {number} h - The hue, in the range 0 - 1. This is the base color.
* @param {number} s - The saturation, in the range 0 - 1. This controls how much of the hue will be in the final color, where 1 is fully saturated and 0 will give you white.
* @param {number} v - The value, in the range 0 - 1. This controls how dark the color is. Where 1 is as bright as possible and 0 is black.
*
* @return {Phaser.Display.Color} This Color object.
*/
setFromHSV: function(h, s, v) {
return HSVToRGB(h, s, v, this);
},
/**
* Updates the internal cache values.
*
* @method Phaser.Display.Color#update
* @private
* @since 3.0.0
*
* @return {Phaser.Display.Color} This Color object.
*/
update: function(updateHSV) {
if (updateHSV === void 0) {
updateHSV = false;
}
if (this._locked) {
return this;
}
var r = this.r;
var g = this.g;
var b = this.b;
var a = this.a;
this._color = GetColor(r, g, b);
this._color32 = GetColor32(r, g, b, a);
this._rgba = "rgba(" + r + "," + g + "," + b + "," + a / 255 + ")";
if (updateHSV) {
RGBToHSV(r, g, b, this);
}
return this;
},
/**
* Updates the internal hsv cache values.
*
* @method Phaser.Display.Color#updateHSV
* @private
* @since 3.13.0
*
* @return {Phaser.Display.Color} This Color object.
*/
updateHSV: function() {
var r = this.r;
var g = this.g;
var b = this.b;
RGBToHSV(r, g, b, this);
return this;
},
/**
* Returns a new Color component using the values from this one.
*
* @method Phaser.Display.Color#clone
* @since 3.0.0
*
* @return {Phaser.Display.Color} A new Color object.
*/
clone: function() {
return new Color(this.r, this.g, this.b, this.a);
},
/**
* Sets this Color object to be grayscaled based on the shade value given.
*
* @method Phaser.Display.Color#gray
* @since 3.13.0
*
* @param {number} shade - A value between 0 and 255.
*
* @return {Phaser.Display.Color} This Color object.
*/
gray: function(shade) {
return this.setTo(shade, shade, shade);
},
/**
* Sets this Color object to be a random color between the `min` and `max` values given.
*
* @method Phaser.Display.Color#random
* @since 3.13.0
*
* @param {number} [min=0] - The minimum random color value. Between 0 and 255.
* @param {number} [max=255] - The maximum random color value. Between 0 and 255.
*
* @return {Phaser.Display.Color} This Color object.
*/
random: function(min, max) {
if (min === void 0) {
min = 0;
}
if (max === void 0) {
max = 255;
}
var r = Math.floor(min + Math.random() * (max - min));
var g = Math.floor(min + Math.random() * (max - min));
var b = Math.floor(min + Math.random() * (max - min));
return this.setTo(r, g, b);
},
/**
* Sets this Color object to be a random grayscale color between the `min` and `max` values given.
*
* @method Phaser.Display.Color#randomGray
* @since 3.13.0
*
* @param {number} [min=0] - The minimum random color value. Between 0 and 255.
* @param {number} [max=255] - The maximum random color value. Between 0 and 255.
*
* @return {Phaser.Display.Color} This Color object.
*/
randomGray: function(min, max) {
if (min === void 0) {
min = 0;
}
if (max === void 0) {
max = 255;
}
var s = Math.floor(min + Math.random() * (max - min));
return this.setTo(s, s, s);
},
/**
* Increase the saturation of this Color by the percentage amount given.
* The saturation is the amount of the base color in the hue.
*
* @method Phaser.Display.Color#saturate
* @since 3.13.0
*
* @param {number} amount - The percentage amount to change this color by. A value between 0 and 100.
*
* @return {Phaser.Display.Color} This Color object.
*/
saturate: function(amount) {
this.s += amount / 100;
return this;
},
/**
* Decrease the saturation of this Color by the percentage amount given.
* The saturation is the amount of the base color in the hue.
*
* @method Phaser.Display.Color#desaturate
* @since 3.13.0
*
* @param {number} amount - The percentage amount to change this color by. A value between 0 and 100.
*
* @return {Phaser.Display.Color} This Color object.
*/
desaturate: function(amount) {
this.s -= amount / 100;
return this;
},
/**
* Increase the lightness of this Color by the percentage amount given.
*
* @method Phaser.Display.Color#lighten
* @since 3.13.0
*
* @param {number} amount - The percentage amount to change this color by. A value between 0 and 100.
*
* @return {Phaser.Display.Color} This Color object.
*/
lighten: function(amount) {
this.v += amount / 100;
return this;
},
/**
* Decrease the lightness of this Color by the percentage amount given.
*
* @method Phaser.Display.Color#darken
* @since 3.13.0
*
* @param {number} amount - The percentage amount to change this color by. A value between 0 and 100.
*
* @return {Phaser.Display.Color} This Color object.
*/
darken: function(amount) {
this.v -= amount / 100;
return this;
},
/**
* Brighten this Color by the percentage amount given.
*
* @method Phaser.Display.Color#brighten
* @since 3.13.0
*
* @param {number} amount - The percentage amount to change this color by. A value between 0 and 100.
*
* @return {Phaser.Display.Color} This Color object.
*/
brighten: function(amount) {
var r = this.r;
var g = this.g;
var b = this.b;
r = Math.max(0, Math.min(255, r - Math.round(255 * -(amount / 100))));
g = Math.max(0, Math.min(255, g - Math.round(255 * -(amount / 100))));
b = Math.max(0, Math.min(255, b - Math.round(255 * -(amount / 100))));
return this.setTo(r, g, b);
},
/**
* The color of this Color component, not including the alpha channel.
*
* @name Phaser.Display.Color#color
* @type {number}
* @readonly
* @since 3.0.0
*/
color: {
get: function() {
return this._color;
}
},
/**
* The color of this Color component, including the alpha channel.
*
* @name Phaser.Display.Color#color32
* @type {number}
* @readonly
* @since 3.0.0
*/
color32: {
get: function() {
return this._color32;
}
},
/**
* The color of this Color component as a string which can be used in CSS color values.
*
* @name Phaser.Display.Color#rgba
* @type {string}
* @readonly
* @since 3.0.0
*/
rgba: {
get: function() {
return this._rgba;
}
},
/**
* The red color value, normalized to the range 0 to 1.
*
* @name Phaser.Display.Color#redGL
* @type {number}
* @since 3.0.0
*/
redGL: {
get: function() {
return this.gl[0];
},
set: function(value) {
this.gl[0] = Math.min(Math.abs(value), 1);
this.r = Math.floor(this.gl[0] * 255);
this.update(true);
}
},
/**
* The green color value, normalized to the range 0 to 1.
*
* @name Phaser.Display.Color#greenGL
* @type {number}
* @since 3.0.0
*/
greenGL: {
get: function() {
return this.gl[1];
},
set: function(value) {
this.gl[1] = Math.min(Math.abs(value), 1);
this.g = Math.floor(this.gl[1] * 255);
this.update(true);
}
},
/**
* The blue color value, normalized to the range 0 to 1.
*
* @name Phaser.Display.Color#blueGL
* @type {number}
* @since 3.0.0
*/
blueGL: {
get: function() {
return this.gl[2];
},
set: function(value) {
this.gl[2] = Math.min(Math.abs(value), 1);
this.b = Math.floor(this.gl[2] * 255);
this.update(true);
}
},
/**
* The alpha color value, normalized to the range 0 to 1.
*
* @name Phaser.Display.Color#alphaGL
* @type {number}
* @since 3.0.0
*/
alphaGL: {
get: function() {
return this.gl[3];
},
set: function(value) {
this.gl[3] = Math.min(Math.abs(value), 1);
this.a = Math.floor(this.gl[3] * 255);
this.update();
}
},
/**
* The red color value, normalized to the range 0 to 255.
*
* @name Phaser.Display.Color#red
* @type {number}
* @since 3.0.0
*/
red: {
get: function() {
return this.r;
},
set: function(value) {
value = Math.floor(Math.abs(value));
this.r = Math.min(value, 255);
this.gl[0] = value / 255;
this.update(true);
}
},
/**
* The green color value, normalized to the range 0 to 255.
*
* @name Phaser.Display.Color#green
* @type {number}
* @since 3.0.0
*/
green: {
get: function() {
return this.g;
},
set: function(value) {
value = Math.floor(Math.abs(value));
this.g = Math.min(value, 255);
this.gl[1] = value / 255;
this.update(true);
}
},
/**
* The blue color value, normalized to the range 0 to 255.
*
* @name Phaser.Display.Color#blue
* @type {number}
* @since 3.0.0
*/
blue: {
get: function() {
return this.b;
},
set: function(value) {
value = Math.floor(Math.abs(value));
this.b = Math.min(value, 255);
this.gl[2] = value / 255;
this.update(true);
}
},
/**
* The alpha color value, normalized to the range 0 to 255.
*
* @name Phaser.Display.Color#alpha
* @type {number}
* @since 3.0.0
*/
alpha: {
get: function() {
return this.a;
},
set: function(value) {
value = Math.floor(Math.abs(value));
this.a = Math.min(value, 255);
this.gl[3] = value / 255;
this.update();
}
},
/**
* The hue color value. A number between 0 and 1.
* This is the base color.
*
* @name Phaser.Display.Color#h
* @type {number}
* @since 3.13.0
*/
h: {
get: function() {
return this._h;
},
set: function(value) {
this._h = value;
HSVToRGB(value, this._s, this._v, this);
}
},
/**
* The saturation color value. A number between 0 and 1.
* This controls how much of the hue will be in the final color, where 1 is fully saturated and 0 will give you white.
*
* @name Phaser.Display.Color#s
* @type {number}
* @since 3.13.0
*/
s: {
get: function() {
return this._s;
},
set: function(value) {
this._s = value;
HSVToRGB(this._h, value, this._v, this);
}
},
/**
* The lightness color value. A number between 0 and 1.
* This controls how dark the color is. Where 1 is as bright as possible and 0 is black.
*
* @name Phaser.Display.Color#v
* @type {number}
* @since 3.13.0
*/
v: {
get: function() {
return this._v;
},
set: function(value) {
this._v = value;
HSVToRGB(this._h, this._s, value, this);
}
}
});
module2.exports = Color;
}
),
/***/
92728: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetColor = __webpack_require__2(37589);
var ColorSpectrum = function(limit) {
if (limit === void 0) {
limit = 1024;
}
var colors = [];
var range = 255;
var i;
var r = 255;
var g = 0;
var b = 0;
for (i = 0; i <= range; i++) {
colors.push({ r, g: i, b, color: GetColor(r, i, b) });
}
g = 255;
for (i = range; i >= 0; i--) {
colors.push({ r: i, g, b, color: GetColor(i, g, b) });
}
r = 0;
for (i = 0; i <= range; i++, g--) {
colors.push({ r, g, b: i, color: GetColor(r, g, i) });
}
g = 0;
b = 255;
for (i = 0; i <= range; i++, b--, r++) {
colors.push({ r, g, b, color: GetColor(r, g, b) });
}
if (limit === 1024) {
return colors;
} else {
var out = [];
var t = 0;
var inc = 1024 / limit;
for (i = 0; i < limit; i++) {
out.push(colors[Math.floor(t)]);
t += inc;
}
return out;
}
};
module2.exports = ColorSpectrum;
}
),
/***/
91588: (
/***/
(module2) => {
var ColorToRGBA = function(color) {
var output = {
r: color >> 16 & 255,
g: color >> 8 & 255,
b: color & 255,
a: 255
};
if (color > 16777215) {
output.a = color >>> 24;
}
return output;
};
module2.exports = ColorToRGBA;
}
),
/***/
62957: (
/***/
(module2) => {
var ComponentToHex = function(color) {
var hex = color.toString(16);
return hex.length === 1 ? "0" + hex : hex;
};
module2.exports = ComponentToHex;
}
),
/***/
37589: (
/***/
(module2) => {
var GetColor = function(red, green, blue) {
return red << 16 | green << 8 | blue;
};
module2.exports = GetColor;
}
),
/***/
1e3: (
/***/
(module2) => {
var GetColor32 = function(red, green, blue, alpha) {
return alpha << 24 | red << 16 | green << 8 | blue;
};
module2.exports = GetColor32;
}
),
/***/
62183: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Color = __webpack_require__2(40987);
var HueToComponent = __webpack_require__2(89528);
var HSLToColor = function(h, s, l) {
var r = l;
var g = l;
var b = l;
if (s !== 0) {
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = HueToComponent(p, q, h + 1 / 3);
g = HueToComponent(p, q, h);
b = HueToComponent(p, q, h - 1 / 3);
}
var color = new Color();
return color.setGLTo(r, g, b, 1);
};
module2.exports = HSLToColor;
}
),
/***/
27939: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var HSVToRGB = __webpack_require__2(7537);
var HSVColorWheel = function(s, v) {
if (s === void 0) {
s = 1;
}
if (v === void 0) {
v = 1;
}
var colors = [];
for (var c = 0; c <= 359; c++) {
colors.push(HSVToRGB(c / 359, s, v));
}
return colors;
};
module2.exports = HSVColorWheel;
}
),
/***/
7537: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetColor = __webpack_require__2(37589);
function ConvertValue(n, h, s, v) {
var k = (n + h * 6) % 6;
var min = Math.min(k, 4 - k, 1);
return Math.round(255 * (v - v * s * Math.max(0, min)));
}
var HSVToRGB = function(h, s, v, out) {
if (s === void 0) {
s = 1;
}
if (v === void 0) {
v = 1;
}
var r = ConvertValue(5, h, s, v);
var g = ConvertValue(3, h, s, v);
var b = ConvertValue(1, h, s, v);
if (!out) {
return { r, g, b, color: GetColor(r, g, b) };
} else if (out.setTo) {
return out.setTo(r, g, b, out.alpha, true);
} else {
out.r = r;
out.g = g;
out.b = b;
out.color = GetColor(r, g, b);
return out;
}
};
module2.exports = HSVToRGB;
}
),
/***/
70238: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Color = __webpack_require__2(40987);
var HexStringToColor = function(hex) {
var color = new Color();
hex = hex.replace(/^(?:#|0x)?([a-f\d])([a-f\d])([a-f\d])$/i, function(m, r2, g2, b2) {
return r2 + r2 + g2 + g2 + b2 + b2;
});
var result = /^(?:#|0x)?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
if (result) {
var r = parseInt(result[1], 16);
var g = parseInt(result[2], 16);
var b = parseInt(result[3], 16);
color.setTo(r, g, b);
}
return color;
};
module2.exports = HexStringToColor;
}
),
/***/
89528: (
/***/
(module2) => {
var HueToComponent = function(p, q, t) {
if (t < 0) {
t += 1;
}
if (t > 1) {
t -= 1;
}
if (t < 1 / 6) {
return p + (q - p) * 6 * t;
}
if (t < 1 / 2) {
return q;
}
if (t < 2 / 3) {
return p + (q - p) * (2 / 3 - t) * 6;
}
return p;
};
module2.exports = HueToComponent;
}
),
/***/
30100: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Color = __webpack_require__2(40987);
var IntegerToRGB = __webpack_require__2(90664);
var IntegerToColor = function(input) {
var rgb = IntegerToRGB(input);
return new Color(rgb.r, rgb.g, rgb.b, rgb.a);
};
module2.exports = IntegerToColor;
}
),
/***/
90664: (
/***/
(module2) => {
var IntegerToRGB = function(color) {
if (color > 16777215) {
return {
a: color >>> 24,
r: color >> 16 & 255,
g: color >> 8 & 255,
b: color & 255
};
} else {
return {
a: 255,
r: color >> 16 & 255,
g: color >> 8 & 255,
b: color & 255
};
}
};
module2.exports = IntegerToRGB;
}
),
/***/
13699: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Linear = __webpack_require__2(28915);
var RGBWithRGB = function(r1, g1, b1, r2, g2, b2, length, index) {
if (length === void 0) {
length = 100;
}
if (index === void 0) {
index = 0;
}
var t = index / length;
return {
r: Linear(r1, r2, t),
g: Linear(g1, g2, t),
b: Linear(b1, b2, t)
};
};
var ColorWithColor = function(color1, color2, length, index) {
if (length === void 0) {
length = 100;
}
if (index === void 0) {
index = 0;
}
return RGBWithRGB(color1.r, color1.g, color1.b, color2.r, color2.g, color2.b, length, index);
};
var ColorWithRGB = function(color, r, g, b, length, index) {
if (length === void 0) {
length = 100;
}
if (index === void 0) {
index = 0;
}
return RGBWithRGB(color.r, color.g, color.b, r, g, b, length, index);
};
module2.exports = {
RGBWithRGB,
ColorWithRGB,
ColorWithColor
};
}
),
/***/
68957: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Color = __webpack_require__2(40987);
var ObjectToColor = function(input) {
return new Color(input.r, input.g, input.b, input.a);
};
module2.exports = ObjectToColor;
}
),
/***/
87388: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Color = __webpack_require__2(40987);
var RGBStringToColor = function(rgb) {
var color = new Color();
var result = /^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d+(?:\.\d+)?))?\s*\)$/.exec(rgb.toLowerCase());
if (result) {
var r = parseInt(result[1], 10);
var g = parseInt(result[2], 10);
var b = parseInt(result[3], 10);
var a = result[4] !== void 0 ? parseFloat(result[4]) : 1;
color.setTo(r, g, b, a * 255);
}
return color;
};
module2.exports = RGBStringToColor;
}
),
/***/
87837: (
/***/
(module2) => {
var RGBToHSV = function(r, g, b, out) {
if (out === void 0) {
out = { h: 0, s: 0, v: 0 };
}
r /= 255;
g /= 255;
b /= 255;
var min = Math.min(r, g, b);
var max = Math.max(r, g, b);
var d = max - min;
var h = 0;
var s = max === 0 ? 0 : d / max;
var v = max;
if (max !== min) {
if (max === r) {
h = (g - b) / d + (g < b ? 6 : 0);
} else if (max === g) {
h = (b - r) / d + 2;
} else if (max === b) {
h = (r - g) / d + 4;
}
h /= 6;
}
if (out.hasOwnProperty("_h")) {
out._h = h;
out._s = s;
out._v = v;
} else {
out.h = h;
out.s = s;
out.v = v;
}
return out;
};
module2.exports = RGBToHSV;
}
),
/***/
75723: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var ComponentToHex = __webpack_require__2(62957);
var RGBToString = function(r, g, b, a, prefix) {
if (a === void 0) {
a = 255;
}
if (prefix === void 0) {
prefix = "#";
}
if (prefix === "#") {
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1, 7);
} else {
return "0x" + ComponentToHex(a) + ComponentToHex(r) + ComponentToHex(g) + ComponentToHex(b);
}
};
module2.exports = RGBToString;
}
),
/***/
85386: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Between = __webpack_require__2(30976);
var Color = __webpack_require__2(40987);
var RandomRGB = function(min, max) {
if (min === void 0) {
min = 0;
}
if (max === void 0) {
max = 255;
}
return new Color(Between(min, max), Between(min, max), Between(min, max));
};
module2.exports = RandomRGB;
}
),
/***/
80333: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var HexStringToColor = __webpack_require__2(70238);
var IntegerToColor = __webpack_require__2(30100);
var ObjectToColor = __webpack_require__2(68957);
var RGBStringToColor = __webpack_require__2(87388);
var ValueToColor = function(input) {
var t = typeof input;
switch (t) {
case "string":
if (input.substr(0, 3).toLowerCase() === "rgb") {
return RGBStringToColor(input);
} else {
return HexStringToColor(input);
}
case "number":
return IntegerToColor(input);
case "object":
return ObjectToColor(input);
}
};
module2.exports = ValueToColor;
}
),
/***/
3956: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Color = __webpack_require__2(40987);
Color.ColorSpectrum = __webpack_require__2(92728);
Color.ColorToRGBA = __webpack_require__2(91588);
Color.ComponentToHex = __webpack_require__2(62957);
Color.GetColor = __webpack_require__2(37589);
Color.GetColor32 = __webpack_require__2(1e3);
Color.HexStringToColor = __webpack_require__2(70238);
Color.HSLToColor = __webpack_require__2(62183);
Color.HSVColorWheel = __webpack_require__2(27939);
Color.HSVToRGB = __webpack_require__2(7537);
Color.HueToComponent = __webpack_require__2(89528);
Color.IntegerToColor = __webpack_require__2(30100);
Color.IntegerToRGB = __webpack_require__2(90664);
Color.Interpolate = __webpack_require__2(13699);
Color.ObjectToColor = __webpack_require__2(68957);
Color.RandomRGB = __webpack_require__2(85386);
Color.RGBStringToColor = __webpack_require__2(87388);
Color.RGBToHSV = __webpack_require__2(87837);
Color.RGBToString = __webpack_require__2(75723);
Color.ValueToColor = __webpack_require__2(80333);
module2.exports = Color;
}
),
/***/
27460: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Align: __webpack_require__2(71926),
BaseShader: __webpack_require__2(73894),
Bounds: __webpack_require__2(58724),
Canvas: __webpack_require__2(26253),
Color: __webpack_require__2(3956),
ColorMatrix: __webpack_require__2(89422),
Masks: __webpack_require__2(69781),
RGB: __webpack_require__2(51767)
};
}
),
/***/
6858: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var GameObjectFactory = __webpack_require__2(39429);
var BitmapMask = new Class({
initialize: function BitmapMask2(scene, maskObject, x, y, texture, frame) {
if (!maskObject) {
maskObject = scene.sys.make.image({ x, y, key: texture, frame, add: false });
}
this.bitmapMask = maskObject;
this.invertAlpha = false;
this.isStencil = false;
},
/**
* Sets a new Game Object or Dynamic Texture for this Bitmap Mask to use.
*
* If a Game Object it must have a texture, such as a Sprite.
*
* You can update the source of the mask as often as you like.
*
* @method Phaser.Display.Masks.BitmapMask#setBitmap
* @since 3.0.0
*
* @param {(Phaser.GameObjects.GameObject|Phaser.Textures.DynamicTexture)} maskObject - The Game Object or Dynamic Texture that will be used as the mask. If a Game Object, it must have a texture, such as a Sprite.
*/
setBitmap: function(maskObject) {
this.bitmapMask = maskObject;
},
/**
* Prepares the WebGL Renderer to render a Game Object with this mask applied.
*
* This renders the masking Game Object to the mask framebuffer and switches to the main framebuffer so that the masked Game Object will be rendered to it instead of being rendered directly to the frame.
*
* @method Phaser.Display.Masks.BitmapMask#preRenderWebGL
* @since 3.0.0
*
* @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The WebGL Renderer to prepare.
* @param {Phaser.GameObjects.GameObject} maskedObject - The masked Game Object which will be drawn.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to render to.
*/
preRenderWebGL: function(renderer, maskedObject, camera) {
renderer.pipelines.BITMAPMASK_PIPELINE.beginMask(this, maskedObject, camera);
},
/**
* Finalizes rendering of a masked Game Object.
*
* This resets the previously bound framebuffer and switches the WebGL Renderer to the Bitmap Mask Pipeline, which uses a special fragment shader to apply the masking effect.
*
* @method Phaser.Display.Masks.BitmapMask#postRenderWebGL
* @since 3.0.0
*
* @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The WebGL Renderer to clean up.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to render to.
* @param {Phaser.Renderer.WebGL.RenderTarget} [renderTarget] - Optional WebGL RenderTarget.
*/
postRenderWebGL: function(renderer, camera, renderTarget) {
renderer.pipelines.BITMAPMASK_PIPELINE.endMask(this, camera, renderTarget);
},
/**
* This is a NOOP method. Bitmap Masks are not supported by the Canvas Renderer.
*
* @method Phaser.Display.Masks.BitmapMask#preRenderCanvas
* @since 3.0.0
*
* @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The Canvas Renderer which would be rendered to.
* @param {Phaser.GameObjects.GameObject} mask - The masked Game Object which would be rendered.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to render to.
*/
preRenderCanvas: function() {
},
/**
* This is a NOOP method. Bitmap Masks are not supported by the Canvas Renderer.
*
* @method Phaser.Display.Masks.BitmapMask#postRenderCanvas
* @since 3.0.0
*
* @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The Canvas Renderer which would be rendered to.
*/
postRenderCanvas: function() {
},
/**
* Destroys this BitmapMask and nulls any references it holds.
*
* Note that if a Game Object is currently using this mask it will _not_ automatically detect you have destroyed it,
* so be sure to call `clearMask` on any Game Object using it, before destroying it.
*
* @method Phaser.Display.Masks.BitmapMask#destroy
* @since 3.7.0
*/
destroy: function() {
this.bitmapMask = null;
}
});
GameObjectFactory.register("bitmapMask", function(maskObject, x, y, key, frame) {
return new BitmapMask(this.scene, maskObject, x, y, key, frame);
});
module2.exports = BitmapMask;
}
),
/***/
80661: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var GeometryMask = new Class({
initialize: function GeometryMask2(scene, graphicsGeometry) {
this.geometryMask = graphicsGeometry;
this.invertAlpha = false;
this.isStencil = true;
this.level = 0;
},
/**
* Sets a new Graphics object for the Geometry Mask.
*
* @method Phaser.Display.Masks.GeometryMask#setShape
* @since 3.0.0
*
* @param {Phaser.GameObjects.Graphics} graphicsGeometry - The Graphics object which will be used for the Geometry Mask.
*
* @return {this} This Geometry Mask
*/
setShape: function(graphicsGeometry) {
this.geometryMask = graphicsGeometry;
return this;
},
/**
* Sets the `invertAlpha` property of this Geometry Mask.
*
* Inverting the alpha essentially flips the way the mask works.
*
* This is a WebGL only feature.
*
* @method Phaser.Display.Masks.GeometryMask#setInvertAlpha
* @since 3.17.0
*
* @param {boolean} [value=true] - Invert the alpha of this mask?
*
* @return {this} This Geometry Mask
*/
setInvertAlpha: function(value) {
if (value === void 0) {
value = true;
}
this.invertAlpha = value;
return this;
},
/**
* Renders the Geometry Mask's underlying Graphics object to the OpenGL stencil buffer and enables the stencil test, which clips rendered pixels according to the mask.
*
* @method Phaser.Display.Masks.GeometryMask#preRenderWebGL
* @since 3.0.0
*
* @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - The WebGL Renderer instance to draw to.
* @param {Phaser.GameObjects.GameObject} child - The Game Object being rendered.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The camera the Game Object is being rendered through.
*/
preRenderWebGL: function(renderer, child, camera) {
var gl = renderer.gl;
renderer.flush();
if (renderer.maskStack.length === 0) {
gl.enable(gl.STENCIL_TEST);
gl.clear(gl.STENCIL_BUFFER_BIT);
renderer.maskCount = 0;
}
if (renderer.currentCameraMask.mask !== this) {
renderer.currentMask.mask = this;
}
renderer.maskStack.push({ mask: this, camera });
this.applyStencil(renderer, camera, true);
renderer.maskCount++;
},
/**
* Applies the current stencil mask to the renderer.
*
* @method Phaser.Display.Masks.GeometryMask#applyStencil
* @since 3.17.0
*
* @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - The WebGL Renderer instance to draw to.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The camera the Game Object is being rendered through.
* @param {boolean} inc - Is this an INCR stencil or a DECR stencil?
*/
applyStencil: function(renderer, camera, inc) {
var gl = renderer.gl;
var geometryMask = this.geometryMask;
var level = renderer.maskCount;
var mask = 255;
gl.colorMask(false, false, false, false);
if (inc) {
gl.stencilFunc(gl.EQUAL, level, mask);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.INCR);
level++;
} else {
gl.stencilFunc(gl.EQUAL, level + 1, mask);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.DECR);
}
this.level = level;
geometryMask.renderWebGL(renderer, geometryMask, camera);
renderer.flush();
gl.colorMask(true, true, true, true);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
if (this.invertAlpha) {
gl.stencilFunc(gl.NOTEQUAL, level, mask);
} else {
gl.stencilFunc(gl.EQUAL, level, mask);
}
},
/**
* Flushes all rendered pixels and disables the stencil test of a WebGL context, thus disabling the mask for it.
*
* @method Phaser.Display.Masks.GeometryMask#postRenderWebGL
* @since 3.0.0
*
* @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - The WebGL Renderer instance to draw flush.
*/
postRenderWebGL: function(renderer) {
var gl = renderer.gl;
renderer.maskStack.pop();
renderer.maskCount--;
renderer.flush();
var current = renderer.currentMask;
if (renderer.maskStack.length === 0) {
current.mask = null;
gl.disable(gl.STENCIL_TEST);
} else {
var prev = renderer.maskStack[renderer.maskStack.length - 1];
prev.mask.applyStencil(renderer, prev.camera, false);
if (renderer.currentCameraMask.mask !== prev.mask) {
current.mask = prev.mask;
current.camera = prev.camera;
} else {
current.mask = null;
}
}
},
/**
* Sets the clipping path of a 2D canvas context to the Geometry Mask's underlying Graphics object.
*
* @method Phaser.Display.Masks.GeometryMask#preRenderCanvas
* @since 3.0.0
*
* @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - The Canvas Renderer instance to set the clipping path on.
* @param {Phaser.GameObjects.GameObject} mask - The Game Object being rendered.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The camera the Game Object is being rendered through.
*/
preRenderCanvas: function(renderer, mask, camera) {
var geometryMask = this.geometryMask;
renderer.currentContext.save();
geometryMask.renderCanvas(renderer, geometryMask, camera, null, null, true);
renderer.currentContext.clip();
},
/**
* Restore the canvas context's previous clipping path, thus turning off the mask for it.
*
* @method Phaser.Display.Masks.GeometryMask#postRenderCanvas
* @since 3.0.0
*
* @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - The Canvas Renderer instance being restored.
*/
postRenderCanvas: function(renderer) {
renderer.currentContext.restore();
},
/**
* Destroys this GeometryMask and nulls any references it holds.
*
* Note that if a Game Object is currently using this mask it will _not_ automatically detect you have destroyed it,
* so be sure to call `clearMask` on any Game Object using it, before destroying it.
*
* @method Phaser.Display.Masks.GeometryMask#destroy
* @since 3.7.0
*/
destroy: function() {
this.geometryMask = null;
}
});
module2.exports = GeometryMask;
}
),
/***/
69781: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
BitmapMask: __webpack_require__2(6858),
GeometryMask: __webpack_require__2(80661)
};
}
),
/***/
73894: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var BaseShader = new Class({
initialize: function BaseShader2(key, fragmentSrc, vertexSrc, uniforms) {
if (!fragmentSrc || fragmentSrc === "") {
fragmentSrc = [
"precision mediump float;",
"uniform vec2 resolution;",
"varying vec2 fragCoord;",
"void main () {",
" vec2 uv = fragCoord / resolution.xy;",
" gl_FragColor = vec4(uv.xyx, 1.0);",
"}"
].join("\n");
}
if (!vertexSrc || vertexSrc === "") {
vertexSrc = [
"precision mediump float;",
"uniform mat4 uProjectionMatrix;",
"uniform mat4 uViewMatrix;",
"uniform vec2 uResolution;",
"attribute vec2 inPosition;",
"varying vec2 fragCoord;",
"varying vec2 outTexCoord;",
"void main () {",
" gl_Position = uProjectionMatrix * uViewMatrix * vec4(inPosition, 1.0, 1.0);",
" fragCoord = vec2(inPosition.x, uResolution.y - inPosition.y);",
" outTexCoord = vec2(inPosition.x / uResolution.x, fragCoord.y / uResolution.y);",
"}"
].join("\n");
}
if (uniforms === void 0) {
uniforms = null;
}
this.key = key;
this.fragmentSrc = fragmentSrc;
this.vertexSrc = vertexSrc;
this.uniforms = uniforms;
}
});
module2.exports = BaseShader;
}
),
/***/
40366: (
/***/
(module2) => {
var AddToDOM = function(element, parent) {
var target;
if (parent) {
if (typeof parent === "string") {
target = document.getElementById(parent);
} else if (typeof parent === "object" && parent.nodeType === 1) {
target = parent;
}
} else if (element.parentElement || parent === null) {
return element;
}
if (!target) {
target = document.body;
}
target.appendChild(element);
return element;
};
module2.exports = AddToDOM;
}
),
/***/
83719: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var AddToDOM = __webpack_require__2(40366);
var CreateDOMContainer = function(game) {
var config = game.config;
if (!config.parent || !config.domCreateContainer) {
return;
}
var div = document.createElement("div");
div.style.cssText = [
"display: block;",
"width: " + game.scale.width + "px;",
"height: " + game.scale.height + "px;",
"padding: 0; margin: 0;",
"position: absolute;",
"overflow: hidden;",
"pointer-events: " + config.domPointerEvents + ";",
"transform: scale(1);",
"transform-origin: left top;"
].join(" ");
game.domContainer = div;
AddToDOM(div, config.parent);
};
module2.exports = CreateDOMContainer;
}
),
/***/
57264: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var OS = __webpack_require__2(25892);
var DOMContentLoaded = function(callback) {
if (document.readyState === "complete" || document.readyState === "interactive") {
callback();
return;
}
var check = function() {
document.removeEventListener("deviceready", check, true);
document.removeEventListener("DOMContentLoaded", check, true);
window.removeEventListener("load", check, true);
callback();
};
if (!document.body) {
window.setTimeout(check, 20);
} else if (OS.cordova) {
document.addEventListener("deviceready", check, false);
} else {
document.addEventListener("DOMContentLoaded", check, true);
window.addEventListener("load", check, true);
}
};
module2.exports = DOMContentLoaded;
}
),
/***/
57811: (
/***/
(module2) => {
var GetInnerHeight = function(iOS) {
if (!iOS) {
return window.innerHeight;
}
var axis = Math.abs(window.orientation);
var size = { w: 0, h: 0 };
var ruler = document.createElement("div");
ruler.setAttribute("style", "position: fixed; height: 100vh; width: 0; top: 0");
document.documentElement.appendChild(ruler);
size.w = axis === 90 ? ruler.offsetHeight : window.innerWidth;
size.h = axis === 90 ? window.innerWidth : ruler.offsetHeight;
document.documentElement.removeChild(ruler);
ruler = null;
if (Math.abs(window.orientation) !== 90) {
return size.h;
} else {
return size.w;
}
};
module2.exports = GetInnerHeight;
}
),
/***/
45818: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(13560);
var GetScreenOrientation = function(width, height) {
var screen2 = window.screen;
var orientation = screen2 ? screen2.orientation || screen2.mozOrientation || screen2.msOrientation : false;
if (orientation && typeof orientation.type === "string") {
return orientation.type;
} else if (typeof orientation === "string") {
return orientation;
}
if (typeof window.orientation === "number") {
return window.orientation === 0 || window.orientation === 180 ? CONST.ORIENTATION.PORTRAIT : CONST.ORIENTATION.LANDSCAPE;
} else if (window.matchMedia) {
if (window.matchMedia("(orientation: portrait)").matches) {
return CONST.ORIENTATION.PORTRAIT;
} else if (window.matchMedia("(orientation: landscape)").matches) {
return CONST.ORIENTATION.LANDSCAPE;
}
} else {
return height > width ? CONST.ORIENTATION.PORTRAIT : CONST.ORIENTATION.LANDSCAPE;
}
};
module2.exports = GetScreenOrientation;
}
),
/***/
74403: (
/***/
(module2) => {
var GetTarget = function(element) {
var target;
if (element !== "") {
if (typeof element === "string") {
target = document.getElementById(element);
} else if (element && element.nodeType === 1) {
target = element;
}
}
if (!target) {
target = document.body;
}
return target;
};
module2.exports = GetTarget;
}
),
/***/
56836: (
/***/
(module2) => {
var ParseXML = function(data) {
var xml = "";
try {
if (window["DOMParser"]) {
var domparser = new DOMParser();
xml = domparser.parseFromString(data, "text/xml");
} else {
xml = new ActiveXObject("Microsoft.XMLDOM");
xml.loadXML(data);
}
} catch (e) {
xml = null;
}
if (!xml || !xml.documentElement || xml.getElementsByTagName("parsererror").length) {
return null;
} else {
return xml;
}
};
module2.exports = ParseXML;
}
),
/***/
35846: (
/***/
(module2) => {
var RemoveFromDOM = function(element) {
if (element.parentNode) {
element.parentNode.removeChild(element);
}
};
module2.exports = RemoveFromDOM;
}
),
/***/
43092: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var NOOP = __webpack_require__2(29747);
var RequestAnimationFrame = new Class({
initialize: function RequestAnimationFrame2() {
this.isRunning = false;
this.callback = NOOP;
this.isSetTimeOut = false;
this.timeOutID = null;
this.delay = 0;
var _this = this;
this.step = function step(time) {
_this.callback(time);
if (_this.isRunning) {
_this.timeOutID = window.requestAnimationFrame(step);
}
};
this.stepTimeout = function stepTimeout() {
if (_this.isRunning) {
_this.timeOutID = window.setTimeout(stepTimeout, _this.delay);
}
_this.callback(window.performance.now());
};
},
/**
* Starts the requestAnimationFrame or setTimeout process running.
*
* @method Phaser.DOM.RequestAnimationFrame#start
* @since 3.0.0
*
* @param {FrameRequestCallback} callback - The callback to invoke each step.
* @param {boolean} forceSetTimeOut - Should it use SetTimeout, even if RAF is available?
* @param {number} delay - The setTimeout delay rate in ms.
*/
start: function(callback, forceSetTimeOut, delay) {
if (this.isRunning) {
return;
}
this.callback = callback;
this.isSetTimeOut = forceSetTimeOut;
this.delay = delay;
this.isRunning = true;
this.timeOutID = forceSetTimeOut ? window.setTimeout(this.stepTimeout, 0) : window.requestAnimationFrame(this.step);
},
/**
* Stops the requestAnimationFrame or setTimeout from running.
*
* @method Phaser.DOM.RequestAnimationFrame#stop
* @since 3.0.0
*/
stop: function() {
this.isRunning = false;
if (this.isSetTimeOut) {
clearTimeout(this.timeOutID);
} else {
window.cancelAnimationFrame(this.timeOutID);
}
},
/**
* Stops the step from running and clears the callback reference.
*
* @method Phaser.DOM.RequestAnimationFrame#destroy
* @since 3.0.0
*/
destroy: function() {
this.stop();
this.callback = NOOP;
}
});
module2.exports = RequestAnimationFrame;
}
),
/***/
84902: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Dom = {
AddToDOM: __webpack_require__2(40366),
DOMContentLoaded: __webpack_require__2(57264),
GetInnerHeight: __webpack_require__2(57811),
GetScreenOrientation: __webpack_require__2(45818),
GetTarget: __webpack_require__2(74403),
ParseXML: __webpack_require__2(56836),
RemoveFromDOM: __webpack_require__2(35846),
RequestAnimationFrame: __webpack_require__2(43092)
};
module2.exports = Dom;
}
),
/***/
47565: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var EE = __webpack_require__2(50792);
var PluginCache = __webpack_require__2(37277);
var EventEmitter = new Class({
Extends: EE,
initialize: function EventEmitter2() {
EE.call(this);
},
/**
* Removes all listeners.
*
* @method Phaser.Events.EventEmitter#shutdown
* @since 3.0.0
*/
shutdown: function() {
this.removeAllListeners();
},
/**
* Removes all listeners.
*
* @method Phaser.Events.EventEmitter#destroy
* @since 3.0.0
*/
destroy: function() {
this.removeAllListeners();
}
});
PluginCache.register("EventEmitter", EventEmitter, "events");
module2.exports = EventEmitter;
}
),
/***/
93055: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = { EventEmitter: __webpack_require__2(47565) };
}
),
/***/
20122: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Controller = __webpack_require__2(72898);
var FX_CONST = __webpack_require__2(14811);
var Barrel = new Class({
Extends: Controller,
initialize: function Barrel2(gameObject, amount) {
if (amount === void 0) {
amount = 1;
}
Controller.call(this, FX_CONST.BARREL, gameObject);
this.amount = amount;
}
});
module2.exports = Barrel;
}
),
/***/
32251: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Controller = __webpack_require__2(72898);
var FX_CONST = __webpack_require__2(14811);
var Bloom = new Class({
Extends: Controller,
initialize: function Bloom2(gameObject, color, offsetX, offsetY, blurStrength, strength, steps) {
if (offsetX === void 0) {
offsetX = 1;
}
if (offsetY === void 0) {
offsetY = 1;
}
if (blurStrength === void 0) {
blurStrength = 1;
}
if (strength === void 0) {
strength = 1;
}
if (steps === void 0) {
steps = 4;
}
Controller.call(this, FX_CONST.BLOOM, gameObject);
this.steps = steps;
this.offsetX = offsetX;
this.offsetY = offsetY;
this.blurStrength = blurStrength;
this.strength = strength;
this.glcolor = [1, 1, 1];
if (color !== void 0 && color !== null) {
this.color = color;
}
},
/**
* The color of the bloom as a number value.
*
* @name Phaser.FX.Bloom#color
* @type {number}
* @since 3.60.0
*/
color: {
get: function() {
var color = this.glcolor;
return (color[0] * 255 << 16) + (color[1] * 255 << 8) + (color[2] * 255 | 0);
},
set: function(value) {
var color = this.glcolor;
color[0] = (value >> 16 & 255) / 255;
color[1] = (value >> 8 & 255) / 255;
color[2] = (value & 255) / 255;
}
}
});
module2.exports = Bloom;
}
),
/***/
9047: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Controller = __webpack_require__2(72898);
var FX_CONST = __webpack_require__2(14811);
var Blur = new Class({
Extends: Controller,
initialize: function Blur2(gameObject, quality, x, y, strength, color, steps) {
if (quality === void 0) {
quality = 0;
}
if (x === void 0) {
x = 2;
}
if (y === void 0) {
y = 2;
}
if (strength === void 0) {
strength = 1;
}
if (steps === void 0) {
steps = 4;
}
Controller.call(this, FX_CONST.BLUR, gameObject);
this.quality = quality;
this.x = x;
this.y = y;
this.steps = steps;
this.strength = strength;
this.glcolor = [1, 1, 1];
if (color !== void 0 && color !== null) {
this.color = color;
}
},
/**
* The color of the blur as a number value.
*
* @name Phaser.FX.Blur#color
* @type {number}
* @since 3.60.0
*/
color: {
get: function() {
var color = this.glcolor;
return (color[0] * 255 << 16) + (color[1] * 255 << 8) + (color[2] * 255 | 0);
},
set: function(value) {
var color = this.glcolor;
color[0] = (value >> 16 & 255) / 255;
color[1] = (value >> 8 & 255) / 255;
color[2] = (value & 255) / 255;
}
}
});
module2.exports = Blur;
}
),
/***/
27885: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Controller = __webpack_require__2(72898);
var FX_CONST = __webpack_require__2(14811);
var Bokeh = new Class({
Extends: Controller,
initialize: function Bokeh2(gameObject, radius, amount, contrast, isTiltShift, blurX, blurY, strength) {
if (radius === void 0) {
radius = 0.5;
}
if (amount === void 0) {
amount = 1;
}
if (contrast === void 0) {
contrast = 0.2;
}
if (isTiltShift === void 0) {
isTiltShift = false;
}
if (blurX === void 0) {
blurX = 1;
}
if (blurY === void 0) {
blurY = 1;
}
if (strength === void 0) {
strength = 1;
}
Controller.call(this, FX_CONST.BOKEH, gameObject);
this.radius = radius;
this.amount = amount;
this.contrast = contrast;
this.isTiltShift = isTiltShift;
this.strength = strength;
this.blurX = blurX;
this.blurY = blurY;
}
});
module2.exports = Bokeh;
}
),
/***/
12578: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Controller = __webpack_require__2(72898);
var FX_CONST = __webpack_require__2(14811);
var Circle = new Class({
Extends: Controller,
initialize: function Circle2(gameObject, thickness, color, backgroundColor, scale, feather) {
if (thickness === void 0) {
thickness = 8;
}
if (scale === void 0) {
scale = 1;
}
if (feather === void 0) {
feather = 5e-3;
}
Controller.call(this, FX_CONST.CIRCLE, gameObject);
this.scale = scale;
this.feather = feather;
this.thickness = thickness;
this.glcolor = [1, 0.2, 0.7];
this.glcolor2 = [1, 0, 0, 0.4];
if (color !== void 0 && color !== null) {
this.color = color;
}
if (backgroundColor !== void 0 && backgroundColor !== null) {
this.backgroundColor = backgroundColor;
}
},
/**
* The color of the circular ring, given as a number value.
*
* @name Phaser.FX.Circle#color
* @type {number}
* @since 3.60.0
*/
color: {
get: function() {
var color = this.glcolor;
return (color[0] * 255 << 16) + (color[1] * 255 << 8) + (color[2] * 255 | 0);
},
set: function(value) {
var color = this.glcolor;
color[0] = (value >> 16 & 255) / 255;
color[1] = (value >> 8 & 255) / 255;
color[2] = (value & 255) / 255;
}
},
/**
* The color of the background, behind the texture, given as a number value.
*
* @name Phaser.FX.Circle#backgroundColor
* @type {number}
* @since 3.60.0
*/
backgroundColor: {
get: function() {
var color = this.glcolor2;
return (color[0] * 255 << 16) + (color[1] * 255 << 8) + (color[2] * 255 | 0);
},
set: function(value) {
var color = this.glcolor2;
color[0] = (value >> 16 & 255) / 255;
color[1] = (value >> 8 & 255) / 255;
color[2] = (value & 255) / 255;
}
},
/**
* The alpha of the background, behind the texture, given as a number value.
*
* @name Phaser.FX.Circle#backgroundAlpha
* @type {number}
* @since 3.70.0
*/
backgroundAlpha: {
get: function() {
return this.glcolor2[3];
},
set: function(value) {
this.glcolor2[3] = value;
}
}
});
module2.exports = Circle;
}
),
/***/
15802: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var BaseColorMatrix = __webpack_require__2(89422);
var FX_CONST = __webpack_require__2(14811);
var ColorMatrix = new Class({
Extends: BaseColorMatrix,
initialize: function ColorMatrix2(gameObject) {
BaseColorMatrix.call(this);
this.type = FX_CONST.COLOR_MATRIX;
this.gameObject = gameObject;
this.active = true;
},
destroy: function() {
this.gameObject = null;
this._matrix = null;
this._data = null;
}
});
module2.exports = ColorMatrix;
}
),
/***/
72898: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Controller = new Class({
initialize: function Controller2(type, gameObject) {
this.type = type;
this.gameObject = gameObject;
this.active = true;
},
/**
* Sets the active state of this FX Controller.
*
* A disabled FX Controller will not be updated.
*
* @method Phaser.FX.Controller#setActive
* @since 3.60.0
*
* @param {boolean} value - `true` to enable this FX Controller, or `false` to disable it.
*
* @return {this} This FX Controller instance.
*/
setActive: function(value) {
this.active = value;
return this;
},
/**
* Destroys this FX Controller.
*
* @method Phaser.FX.Controller#destroy
* @since 3.60.0
*/
destroy: function() {
this.gameObject = null;
this.active = false;
}
});
module2.exports = Controller;
}
),
/***/
44553: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Controller = __webpack_require__2(72898);
var FX_CONST = __webpack_require__2(14811);
var Displacement = new Class({
Extends: Controller,
initialize: function Displacement2(gameObject, texture, x, y) {
if (texture === void 0) {
texture = "__WHITE";
}
if (x === void 0) {
x = 5e-3;
}
if (y === void 0) {
y = 5e-3;
}
Controller.call(this, FX_CONST.DISPLACEMENT, gameObject);
this.x = x;
this.y = y;
this.glTexture;
this.setTexture(texture);
},
/**
* Sets the Texture to be used for the displacement effect.
*
* You can only use a whole texture, not a frame from a texture atlas or sprite sheet.
*
* @method Phaser.FX.Displacement#setTexture
* @since 3.60.0
*
* @param {string} [texture='__WHITE'] - The unique string-based key of the texture to use for displacement, which must exist in the Texture Manager.
*
* @return {this} This FX Controller.
*/
setTexture: function(texture) {
var phaserTexture = this.gameObject.scene.sys.textures.getFrame(texture);
if (phaserTexture) {
this.glTexture = phaserTexture.glTexture;
}
return this;
}
});
module2.exports = Displacement;
}
),
/***/
68531: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Controller = __webpack_require__2(72898);
var FX_CONST = __webpack_require__2(14811);
var Glow = new Class({
Extends: Controller,
initialize: function Glow2(gameObject, color, outerStrength, innerStrength, knockout) {
if (outerStrength === void 0) {
outerStrength = 4;
}
if (innerStrength === void 0) {
innerStrength = 0;
}
if (knockout === void 0) {
knockout = false;
}
Controller.call(this, FX_CONST.GLOW, gameObject);
this.outerStrength = outerStrength;
this.innerStrength = innerStrength;
this.knockout = knockout;
this.glcolor = [1, 1, 1, 1];
if (color !== void 0) {
this.color = color;
}
},
/**
* The color of the glow as a number value.
*
* @name Phaser.FX.Glow#color
* @type {number}
* @since 3.60.0
*/
color: {
get: function() {
var color = this.glcolor;
return (color[0] * 255 << 16) + (color[1] * 255 << 8) + (color[2] * 255 | 0);
},
set: function(value) {
var color = this.glcolor;
color[0] = (value >> 16 & 255) / 255;
color[1] = (value >> 8 & 255) / 255;
color[2] = (value & 255) / 255;
}
}
});
module2.exports = Glow;
}
),
/***/
37102: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Controller = __webpack_require__2(72898);
var FX_CONST = __webpack_require__2(14811);
var Gradient = new Class({
Extends: Controller,
initialize: function Gradient2(gameObject, color1, color2, alpha, fromX, fromY, toX, toY, size) {
if (alpha === void 0) {
alpha = 0.2;
}
if (fromX === void 0) {
fromX = 0;
}
if (fromY === void 0) {
fromY = 0;
}
if (toX === void 0) {
toX = 0;
}
if (toY === void 0) {
toY = 1;
}
if (size === void 0) {
size = 0;
}
Controller.call(this, FX_CONST.GRADIENT, gameObject);
this.alpha = alpha;
this.size = size;
this.fromX = fromX;
this.fromY = fromY;
this.toX = toX;
this.toY = toY;
this.glcolor1 = [255, 0, 0];
this.glcolor2 = [0, 255, 0];
if (color1 !== void 0 && color1 !== null) {
this.color1 = color1;
}
if (color2 !== void 0 && color2 !== null) {
this.color2 = color2;
}
},
/**
* The first gradient color, given as a number value.
*
* @name Phaser.FX.Gradient#color1
* @type {number}
* @since 3.60.0
*/
color1: {
get: function() {
var color = this.glcolor1;
return (color[0] << 16) + (color[1] << 8) + (color[2] | 0);
},
set: function(value) {
var color = this.glcolor1;
color[0] = value >> 16 & 255;
color[1] = value >> 8 & 255;
color[2] = value & 255;
}
},
/**
* The second gradient color, given as a number value.
*
* @name Phaser.FX.Gradient#color2
* @type {number}
* @since 3.60.0
*/
color2: {
get: function() {
var color = this.glcolor2;
return (color[0] << 16) + (color[1] << 8) + (color[2] | 0);
},
set: function(value) {
var color = this.glcolor2;
color[0] = value >> 16 & 255;
color[1] = value >> 8 & 255;
color[2] = value & 255;
}
}
});
module2.exports = Gradient;
}
),
/***/
86886: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Controller = __webpack_require__2(72898);
var FX_CONST = __webpack_require__2(14811);
var Pixelate = new Class({
Extends: Controller,
initialize: function Pixelate2(gameObject, amount) {
if (amount === void 0) {
amount = 1;
}
Controller.call(this, FX_CONST.PIXELATE, gameObject);
this.amount = amount;
}
});
module2.exports = Pixelate;
}
),
/***/
92322: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Controller = __webpack_require__2(72898);
var FX_CONST = __webpack_require__2(14811);
var Shadow = new Class({
Extends: Controller,
initialize: function Shadow2(gameObject, x, y, decay, power, color, samples, intensity) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (decay === void 0) {
decay = 0.1;
}
if (power === void 0) {
power = 1;
}
if (samples === void 0) {
samples = 6;
}
if (intensity === void 0) {
intensity = 1;
}
Controller.call(this, FX_CONST.SHADOW, gameObject);
this.x = x;
this.y = y;
this.decay = decay;
this.power = power;
this.glcolor = [0, 0, 0, 1];
this.samples = samples;
this.intensity = intensity;
if (color !== void 0) {
this.color = color;
}
},
/**
* The color of the shadow.
*
* @name Phaser.FX.Shadow#color
* @type {number}
* @since 3.60.0
*/
color: {
get: function() {
var color = this.glcolor;
return (color[0] * 255 << 16) + (color[1] * 255 << 8) + (color[2] * 255 | 0);
},
set: function(value) {
var color = this.glcolor;
color[0] = (value >> 16 & 255) / 255;
color[1] = (value >> 8 & 255) / 255;
color[2] = (value & 255) / 255;
}
}
});
module2.exports = Shadow;
}
),
/***/
39563: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Controller = __webpack_require__2(72898);
var FX_CONST = __webpack_require__2(14811);
var Shine = new Class({
Extends: Controller,
initialize: function Shine2(gameObject, speed, lineWidth, gradient, reveal) {
if (speed === void 0) {
speed = 0.5;
}
if (lineWidth === void 0) {
lineWidth = 0.5;
}
if (gradient === void 0) {
gradient = 3;
}
if (reveal === void 0) {
reveal = false;
}
Controller.call(this, FX_CONST.SHINE, gameObject);
this.speed = speed;
this.lineWidth = lineWidth;
this.gradient = gradient;
this.reveal = reveal;
}
});
module2.exports = Shine;
}
),
/***/
56448: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Controller = __webpack_require__2(72898);
var FX_CONST = __webpack_require__2(14811);
var Vignette = new Class({
Extends: Controller,
initialize: function Vignette2(gameObject, x, y, radius, strength) {
if (x === void 0) {
x = 0.5;
}
if (y === void 0) {
y = 0.5;
}
if (radius === void 0) {
radius = 0.5;
}
if (strength === void 0) {
strength = 0.5;
}
Controller.call(this, FX_CONST.VIGNETTE, gameObject);
this.x = x;
this.y = y;
this.radius = radius;
this.strength = strength;
}
});
module2.exports = Vignette;
}
),
/***/
38433: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Controller = __webpack_require__2(72898);
var FX_CONST = __webpack_require__2(14811);
var Wipe = new Class({
Extends: Controller,
initialize: function Wipe2(gameObject, wipeWidth, direction, axis, reveal) {
if (wipeWidth === void 0) {
wipeWidth = 0.1;
}
if (direction === void 0) {
direction = 0;
}
if (axis === void 0) {
axis = 0;
}
if (reveal === void 0) {
reveal = false;
}
Controller.call(this, FX_CONST.WIPE, gameObject);
this.progress = 0;
this.wipeWidth = wipeWidth;
this.direction = direction;
this.axis = axis;
this.reveal = reveal;
}
});
module2.exports = Wipe;
}
),
/***/
14811: (
/***/
(module2) => {
var FX_CONST = {
/**
* The Glow FX.
*
* @name Phaser.FX.GLOW
* @type {number}
* @const
* @since 3.60.0
*/
GLOW: 4,
/**
* The Shadow FX.
*
* @name Phaser.FX.SHADOW
* @type {number}
* @const
* @since 3.60.0
*/
SHADOW: 5,
/**
* The Pixelate FX.
*
* @name Phaser.FX.PIXELATE
* @type {number}
* @const
* @since 3.60.0
*/
PIXELATE: 6,
/**
* The Vignette FX.
*
* @name Phaser.FX.VIGNETTE
* @type {number}
* @const
* @since 3.60.0
*/
VIGNETTE: 7,
/**
* The Shine FX.
*
* @name Phaser.FX.SHINE
* @type {number}
* @const
* @since 3.60.0
*/
SHINE: 8,
/**
* The Blur FX.
*
* @name Phaser.FX.BLUR
* @type {number}
* @const
* @since 3.60.0
*/
BLUR: 9,
// uses 3 shaders, slots 9, 10 and 11
/**
* The Gradient FX.
*
* @name Phaser.FX.GRADIENT
* @type {number}
* @const
* @since 3.60.0
*/
GRADIENT: 12,
/**
* The Bloom FX.
*
* @name Phaser.FX.BLOOM
* @type {number}
* @const
* @since 3.60.0
*/
BLOOM: 13,
/**
* The Color Matrix FX.
*
* @name Phaser.FX.COLOR_MATRIX
* @type {number}
* @const
* @since 3.60.0
*/
COLOR_MATRIX: 14,
/**
* The Circle FX.
*
* @name Phaser.FX.CIRCLE
* @type {number}
* @const
* @since 3.60.0
*/
CIRCLE: 15,
/**
* The Barrel FX.
*
* @name Phaser.FX.BARREL
* @type {number}
* @const
* @since 3.60.0
*/
BARREL: 16,
/**
* The Displacement FX.
*
* @name Phaser.FX.DISPLACEMENT
* @type {number}
* @const
* @since 3.60.0
*/
DISPLACEMENT: 17,
/**
* The Wipe FX.
*
* @name Phaser.FX.WIPE
* @type {number}
* @const
* @since 3.60.0
*/
WIPE: 18,
/**
* The Bokeh and Tilt Shift FX.
*
* @name Phaser.FX.BOKEH
* @type {number}
* @const
* @since 3.60.0
*/
BOKEH: 19
};
module2.exports = FX_CONST;
}
),
/***/
66064: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Extend = __webpack_require__2(79291);
var FX_CONST = __webpack_require__2(14811);
var FX = {
Barrel: __webpack_require__2(20122),
Controller: __webpack_require__2(72898),
Bloom: __webpack_require__2(32251),
Blur: __webpack_require__2(9047),
Bokeh: __webpack_require__2(27885),
Circle: __webpack_require__2(12578),
ColorMatrix: __webpack_require__2(15802),
Displacement: __webpack_require__2(44553),
Glow: __webpack_require__2(68531),
Gradient: __webpack_require__2(37102),
Pixelate: __webpack_require__2(86886),
Shadow: __webpack_require__2(92322),
Shine: __webpack_require__2(39563),
Vignette: __webpack_require__2(56448),
Wipe: __webpack_require__2(38433)
};
FX = Extend(false, FX, FX_CONST);
module2.exports = FX;
}
),
/***/
25305: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BlendModes = __webpack_require__2(10312);
var GetAdvancedValue = __webpack_require__2(23568);
var BuildGameObject = function(scene, gameObject, config) {
gameObject.x = GetAdvancedValue(config, "x", 0);
gameObject.y = GetAdvancedValue(config, "y", 0);
gameObject.depth = GetAdvancedValue(config, "depth", 0);
gameObject.flipX = GetAdvancedValue(config, "flipX", false);
gameObject.flipY = GetAdvancedValue(config, "flipY", false);
var scale = GetAdvancedValue(config, "scale", null);
if (typeof scale === "number") {
gameObject.setScale(scale);
} else if (scale !== null) {
gameObject.scaleX = GetAdvancedValue(scale, "x", 1);
gameObject.scaleY = GetAdvancedValue(scale, "y", 1);
}
var scrollFactor = GetAdvancedValue(config, "scrollFactor", null);
if (typeof scrollFactor === "number") {
gameObject.setScrollFactor(scrollFactor);
} else if (scrollFactor !== null) {
gameObject.scrollFactorX = GetAdvancedValue(scrollFactor, "x", 1);
gameObject.scrollFactorY = GetAdvancedValue(scrollFactor, "y", 1);
}
gameObject.rotation = GetAdvancedValue(config, "rotation", 0);
var angle = GetAdvancedValue(config, "angle", null);
if (angle !== null) {
gameObject.angle = angle;
}
gameObject.alpha = GetAdvancedValue(config, "alpha", 1);
var origin = GetAdvancedValue(config, "origin", null);
if (typeof origin === "number") {
gameObject.setOrigin(origin);
} else if (origin !== null) {
var ox = GetAdvancedValue(origin, "x", 0.5);
var oy = GetAdvancedValue(origin, "y", 0.5);
gameObject.setOrigin(ox, oy);
}
gameObject.blendMode = GetAdvancedValue(config, "blendMode", BlendModes.NORMAL);
gameObject.visible = GetAdvancedValue(config, "visible", true);
var add = GetAdvancedValue(config, "add", true);
if (add) {
scene.sys.displayList.add(gameObject);
}
if (gameObject.preUpdate) {
scene.sys.updateList.add(gameObject);
}
return gameObject;
};
module2.exports = BuildGameObject;
}
),
/***/
13059: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetAdvancedValue = __webpack_require__2(23568);
var BuildGameObjectAnimation = function(sprite, config) {
var animConfig = GetAdvancedValue(config, "anims", null);
if (animConfig === null) {
return sprite;
}
if (typeof animConfig === "string") {
sprite.anims.play(animConfig);
} else if (typeof animConfig === "object") {
var anims = sprite.anims;
var key = GetAdvancedValue(animConfig, "key", void 0);
if (key) {
var startFrame = GetAdvancedValue(animConfig, "startFrame", void 0);
var delay = GetAdvancedValue(animConfig, "delay", 0);
var repeat = GetAdvancedValue(animConfig, "repeat", 0);
var repeatDelay = GetAdvancedValue(animConfig, "repeatDelay", 0);
var yoyo = GetAdvancedValue(animConfig, "yoyo", false);
var play = GetAdvancedValue(animConfig, "play", false);
var delayedPlay = GetAdvancedValue(animConfig, "delayedPlay", 0);
var playConfig = {
key,
delay,
repeat,
repeatDelay,
yoyo,
startFrame
};
if (play) {
anims.play(playConfig);
} else if (delayedPlay > 0) {
anims.playAfterDelay(playConfig, delayedPlay);
} else {
anims.load(playConfig);
}
}
}
return sprite;
};
module2.exports = BuildGameObjectAnimation;
}
),
/***/
8050: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var List = __webpack_require__2(73162);
var PluginCache = __webpack_require__2(37277);
var GameObjectEvents = __webpack_require__2(51708);
var SceneEvents = __webpack_require__2(44594);
var StableSort = __webpack_require__2(19186);
var DisplayList = new Class({
Extends: List,
initialize: function DisplayList2(scene) {
List.call(this, scene);
this.sortChildrenFlag = false;
this.scene = scene;
this.systems = scene.sys;
this.events = scene.sys.events;
this.addCallback = this.addChildCallback;
this.removeCallback = this.removeChildCallback;
this.events.once(SceneEvents.BOOT, this.boot, this);
this.events.on(SceneEvents.START, this.start, this);
},
/**
* This method is called automatically, only once, when the Scene is first created.
* Do not invoke it directly.
*
* @method Phaser.GameObjects.DisplayList#boot
* @private
* @since 3.5.1
*/
boot: function() {
this.events.once(SceneEvents.DESTROY, this.destroy, this);
},
/**
* Internal method called from `List.addCallback`.
*
* @method Phaser.GameObjects.DisplayList#addChildCallback
* @private
* @fires Phaser.Scenes.Events#ADDED_TO_SCENE
* @fires Phaser.GameObjects.Events#ADDED_TO_SCENE
* @since 3.50.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was added to the list.
*/
addChildCallback: function(gameObject) {
if (gameObject.displayList && gameObject.displayList !== this) {
gameObject.removeFromDisplayList();
}
if (gameObject.parentContainer) {
gameObject.parentContainer.remove(gameObject);
}
if (!gameObject.displayList) {
this.queueDepthSort();
gameObject.displayList = this;
gameObject.emit(GameObjectEvents.ADDED_TO_SCENE, gameObject, this.scene);
this.events.emit(SceneEvents.ADDED_TO_SCENE, gameObject, this.scene);
}
},
/**
* Internal method called from `List.removeCallback`.
*
* @method Phaser.GameObjects.DisplayList#removeChildCallback
* @private
* @fires Phaser.Scenes.Events#REMOVED_FROM_SCENE
* @fires Phaser.GameObjects.Events#REMOVED_FROM_SCENE
* @since 3.50.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was removed from the list.
*/
removeChildCallback: function(gameObject) {
this.queueDepthSort();
gameObject.displayList = null;
gameObject.emit(GameObjectEvents.REMOVED_FROM_SCENE, gameObject, this.scene);
this.events.emit(SceneEvents.REMOVED_FROM_SCENE, gameObject, this.scene);
},
/**
* This method is called automatically by the Scene when it is starting up.
* It is responsible for creating local systems, properties and listening for Scene events.
* Do not invoke it directly.
*
* @method Phaser.GameObjects.DisplayList#start
* @private
* @since 3.5.0
*/
start: function() {
this.events.once(SceneEvents.SHUTDOWN, this.shutdown, this);
},
/**
* Force a sort of the display list on the next call to depthSort.
*
* @method Phaser.GameObjects.DisplayList#queueDepthSort
* @since 3.0.0
*/
queueDepthSort: function() {
this.sortChildrenFlag = true;
},
/**
* Immediately sorts the display list if the flag is set.
*
* @method Phaser.GameObjects.DisplayList#depthSort
* @since 3.0.0
*/
depthSort: function() {
if (this.sortChildrenFlag) {
StableSort(this.list, this.sortByDepth);
this.sortChildrenFlag = false;
}
},
/**
* Compare the depth of two Game Objects.
*
* @method Phaser.GameObjects.DisplayList#sortByDepth
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} childA - The first Game Object.
* @param {Phaser.GameObjects.GameObject} childB - The second Game Object.
*
* @return {number} The difference between the depths of each Game Object.
*/
sortByDepth: function(childA, childB) {
return childA._depth - childB._depth;
},
/**
* Returns an array which contains all objects currently on the Display List.
* This is a reference to the main list array, not a copy of it, so be careful not to modify it.
*
* @method Phaser.GameObjects.DisplayList#getChildren
* @since 3.12.0
*
* @return {Phaser.GameObjects.GameObject[]} The group members.
*/
getChildren: function() {
return this.list;
},
/**
* The Scene that owns this plugin is shutting down.
*
* We need to kill and reset all internal properties as well as stop listening to Scene events.
*
* @method Phaser.GameObjects.DisplayList#shutdown
* @private
* @since 3.0.0
*/
shutdown: function() {
var list = this.list;
while (list.length) {
list[0].destroy(true);
}
this.events.off(SceneEvents.SHUTDOWN, this.shutdown, this);
},
/**
* The Scene that owns this plugin is being destroyed.
* We need to shutdown and then kill off all external references.
*
* @method Phaser.GameObjects.DisplayList#destroy
* @private
* @since 3.0.0
*/
destroy: function() {
this.shutdown();
this.events.off(SceneEvents.START, this.start, this);
this.scene = null;
this.systems = null;
this.events = null;
}
});
PluginCache.register("DisplayList", DisplayList, "displayList");
module2.exports = DisplayList;
}
),
/***/
95643: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var ComponentsToJSON = __webpack_require__2(53774);
var DataManager = __webpack_require__2(45893);
var EventEmitter = __webpack_require__2(50792);
var Events = __webpack_require__2(51708);
var SceneEvents = __webpack_require__2(44594);
var GameObject = new Class({
Extends: EventEmitter,
initialize: function GameObject2(scene, type) {
EventEmitter.call(this);
this.scene = scene;
this.displayList = null;
this.type = type;
this.state = 0;
this.parentContainer = null;
this.name = "";
this.active = true;
this.tabIndex = -1;
this.data = null;
this.renderFlags = 15;
this.cameraFilter = 0;
this.input = null;
this.body = null;
this.ignoreDestroy = false;
this.on(Events.ADDED_TO_SCENE, this.addedToScene, this);
this.on(Events.REMOVED_FROM_SCENE, this.removedFromScene, this);
scene.sys.queueDepthSort();
},
/**
* Sets the `active` property of this Game Object and returns this Game Object for further chaining.
* A Game Object with its `active` property set to `true` will be updated by the Scenes UpdateList.
*
* @method Phaser.GameObjects.GameObject#setActive
* @since 3.0.0
*
* @param {boolean} value - True if this Game Object should be set as active, false if not.
*
* @return {this} This GameObject.
*/
setActive: function(value) {
this.active = value;
return this;
},
/**
* Sets the `name` property of this Game Object and returns this Game Object for further chaining.
* The `name` property is not populated by Phaser and is presented for your own use.
*
* @method Phaser.GameObjects.GameObject#setName
* @since 3.0.0
*
* @param {string} value - The name to be given to this Game Object.
*
* @return {this} This GameObject.
*/
setName: function(value) {
this.name = value;
return this;
},
/**
* Sets the current state of this Game Object.
*
* Phaser itself will never modify the State of a Game Object, although plugins may do so.
*
* For example, a Game Object could change from a state of 'moving', to 'attacking', to 'dead'.
* The state value should typically be an integer (ideally mapped to a constant
* in your game code), but could also be a string. It is recommended to keep it light and simple.
* If you need to store complex data about your Game Object, look at using the Data Component instead.
*
* @method Phaser.GameObjects.GameObject#setState
* @since 3.16.0
*
* @param {(number|string)} value - The state of the Game Object.
*
* @return {this} This GameObject.
*/
setState: function(value) {
this.state = value;
return this;
},
/**
* Adds a Data Manager component to this Game Object.
*
* @method Phaser.GameObjects.GameObject#setDataEnabled
* @since 3.0.0
* @see Phaser.Data.DataManager
*
* @return {this} This GameObject.
*/
setDataEnabled: function() {
if (!this.data) {
this.data = new DataManager(this);
}
return this;
},
/**
* Allows you to store a key value pair within this Game Objects Data Manager.
*
* If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled
* before setting the value.
*
* If the key doesn't already exist in the Data Manager then it is created.
*
* ```javascript
* sprite.setData('name', 'Red Gem Stone');
* ```
*
* You can also pass in an object of key value pairs as the first argument:
*
* ```javascript
* sprite.setData({ name: 'Red Gem Stone', level: 2, owner: 'Link', gold: 50 });
* ```
*
* To get a value back again you can call `getData`:
*
* ```javascript
* sprite.getData('gold');
* ```
*
* Or you can access the value directly via the `values` property, where it works like any other variable:
*
* ```javascript
* sprite.data.values.gold += 50;
* ```
*
* When the value is first set, a `setdata` event is emitted from this Game Object.
*
* If the key already exists, a `changedata` event is emitted instead, along an event named after the key.
* For example, if you updated an existing key called `PlayerLives` then it would emit the event `changedata-PlayerLives`.
* These events will be emitted regardless if you use this method to set the value, or the direct `values` setter.
*
* Please note that the data keys are case-sensitive and must be valid JavaScript Object property strings.
* This means the keys `gold` and `Gold` are treated as two unique values within the Data Manager.
*
* @method Phaser.GameObjects.GameObject#setData
* @since 3.0.0
*
* @generic {any} T
* @genericUse {(string|T)} - [key]
*
* @param {(string|object)} key - The key to set the value for. Or an object of key value pairs. If an object the `data` argument is ignored.
* @param {*} [data] - The value to set for the given key. If an object is provided as the key this argument is ignored.
*
* @return {this} This GameObject.
*/
setData: function(key, value) {
if (!this.data) {
this.data = new DataManager(this);
}
this.data.set(key, value);
return this;
},
/**
* Increase a value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is increased from 0.
*
* If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled
* before setting the value.
*
* If the key doesn't already exist in the Data Manager then it is created.
*
* When the value is first set, a `setdata` event is emitted from this Game Object.
*
* @method Phaser.GameObjects.GameObject#incData
* @since 3.23.0
*
* @param {string} key - The key to change the value for.
* @param {number} [amount=1] - The amount to increase the given key by. Pass a negative value to decrease the key.
*
* @return {this} This GameObject.
*/
incData: function(key, amount) {
if (!this.data) {
this.data = new DataManager(this);
}
this.data.inc(key, amount);
return this;
},
/**
* Toggle a boolean value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is toggled from false.
*
* If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled
* before setting the value.
*
* If the key doesn't already exist in the Data Manager then it is created.
*
* When the value is first set, a `setdata` event is emitted from this Game Object.
*
* @method Phaser.GameObjects.GameObject#toggleData
* @since 3.23.0
*
* @param {string} key - The key to toggle the value for.
*
* @return {this} This GameObject.
*/
toggleData: function(key) {
if (!this.data) {
this.data = new DataManager(this);
}
this.data.toggle(key);
return this;
},
/**
* Retrieves the value for the given key in this Game Objects Data Manager, or undefined if it doesn't exist.
*
* You can also access values via the `values` object. For example, if you had a key called `gold` you can do either:
*
* ```javascript
* sprite.getData('gold');
* ```
*
* Or access the value directly:
*
* ```javascript
* sprite.data.values.gold;
* ```
*
* You can also pass in an array of keys, in which case an array of values will be returned:
*
* ```javascript
* sprite.getData([ 'gold', 'armor', 'health' ]);
* ```
*
* This approach is useful for destructuring arrays in ES6.
*
* @method Phaser.GameObjects.GameObject#getData
* @since 3.0.0
*
* @param {(string|string[])} key - The key of the value to retrieve, or an array of keys.
*
* @return {*} The value belonging to the given key, or an array of values, the order of which will match the input array.
*/
getData: function(key) {
if (!this.data) {
this.data = new DataManager(this);
}
return this.data.get(key);
},
/**
* Pass this Game Object to the Input Manager to enable it for Input.
*
* Input works by using hit areas, these are nearly always geometric shapes, such as rectangles or circles, that act as the hit area
* for the Game Object. However, you can provide your own hit area shape and callback, should you wish to handle some more advanced
* input detection.
*
* If no arguments are provided it will try and create a rectangle hit area based on the texture frame the Game Object is using. If
* this isn't a texture-bound object, such as a Graphics or BitmapText object, this will fail, and you'll need to provide a specific
* shape for it to use.
*
* You can also provide an Input Configuration Object as the only argument to this method.
*
* @example
* sprite.setInteractive();
*
* @example
* sprite.setInteractive(new Phaser.Geom.Circle(45, 46, 45), Phaser.Geom.Circle.Contains);
*
* @example
* graphics.setInteractive(new Phaser.Geom.Rectangle(0, 0, 128, 128), Phaser.Geom.Rectangle.Contains);
*
* @method Phaser.GameObjects.GameObject#setInteractive
* @since 3.0.0
*
* @param {(Phaser.Types.Input.InputConfiguration|any)} [hitArea] - Either an input configuration object, or a geometric shape that defines the hit area for the Game Object. If not given it will try to create a Rectangle based on the texture frame.
* @param {Phaser.Types.Input.HitAreaCallback} [callback] - The callback that determines if the pointer is within the Hit Area shape or not. If you provide a shape you must also provide a callback.
* @param {boolean} [dropZone=false] - Should this Game Object be treated as a drop zone target?
*
* @return {this} This GameObject.
*/
setInteractive: function(hitArea, hitAreaCallback, dropZone) {
this.scene.sys.input.enable(this, hitArea, hitAreaCallback, dropZone);
return this;
},
/**
* If this Game Object has previously been enabled for input, this will disable it.
*
* An object that is disabled for input stops processing or being considered for
* input events, but can be turned back on again at any time by simply calling
* `setInteractive()` with no arguments provided.
*
* If want to completely remove interaction from this Game Object then use `removeInteractive` instead.
*
* @method Phaser.GameObjects.GameObject#disableInteractive
* @since 3.7.0
*
* @param {boolean} [resetCursor=false] - Should the currently active Input cursor, if any, be reset to the default cursor?
*
* @return {this} This GameObject.
*/
disableInteractive: function(resetCursor) {
if (resetCursor === void 0) {
resetCursor = false;
}
this.scene.sys.input.disable(this, resetCursor);
return this;
},
/**
* If this Game Object has previously been enabled for input, this will queue it
* for removal, causing it to no longer be interactive. The removal happens on
* the next game step, it is not immediate.
*
* The Interactive Object that was assigned to this Game Object will be destroyed,
* removed from the Input Manager and cleared from this Game Object.
*
* If you wish to re-enable this Game Object at a later date you will need to
* re-create its InteractiveObject by calling `setInteractive` again.
*
* If you wish to only temporarily stop an object from receiving input then use
* `disableInteractive` instead, as that toggles the interactive state, where-as
* this erases it completely.
*
* If you wish to resize a hit area, don't remove and then set it as being
* interactive. Instead, access the hitarea object directly and resize the shape
* being used. I.e.: `sprite.input.hitArea.setSize(width, height)` (assuming the
* shape is a Rectangle, which it is by default.)
*
* @method Phaser.GameObjects.GameObject#removeInteractive
* @since 3.7.0
*
* @param {boolean} [resetCursor=false] - Should the currently active Input cursor, if any, be reset to the default cursor?
*
* @return {this} This GameObject.
*/
removeInteractive: function(resetCursor) {
if (resetCursor === void 0) {
resetCursor = false;
}
this.scene.sys.input.clear(this);
if (resetCursor) {
this.scene.sys.input.resetCursor();
}
this.input = void 0;
return this;
},
/**
* This callback is invoked when this Game Object is added to a Scene.
*
* Can be overriden by custom Game Objects, but be aware of some Game Objects that
* will use this, such as Sprites, to add themselves into the Update List.
*
* You can also listen for the `ADDED_TO_SCENE` event from this Game Object.
*
* @method Phaser.GameObjects.GameObject#addedToScene
* @since 3.50.0
*/
addedToScene: function() {
},
/**
* This callback is invoked when this Game Object is removed from a Scene.
*
* Can be overriden by custom Game Objects, but be aware of some Game Objects that
* will use this, such as Sprites, to removed themselves from the Update List.
*
* You can also listen for the `REMOVED_FROM_SCENE` event from this Game Object.
*
* @method Phaser.GameObjects.GameObject#removedFromScene
* @since 3.50.0
*/
removedFromScene: function() {
},
/**
* To be overridden by custom GameObjects. Allows base objects to be used in a Pool.
*
* @method Phaser.GameObjects.GameObject#update
* @since 3.0.0
*
* @param {...*} [args] - args
*/
update: function() {
},
/**
* Returns a JSON representation of the Game Object.
*
* @method Phaser.GameObjects.GameObject#toJSON
* @since 3.0.0
*
* @return {Phaser.Types.GameObjects.JSONGameObject} A JSON representation of the Game Object.
*/
toJSON: function() {
return ComponentsToJSON(this);
},
/**
* Compares the renderMask with the renderFlags to see if this Game Object will render or not.
* Also checks the Game Object against the given Cameras exclusion list.
*
* @method Phaser.GameObjects.GameObject#willRender
* @since 3.0.0
*
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to check against this Game Object.
*
* @return {boolean} True if the Game Object should be rendered, otherwise false.
*/
willRender: function(camera) {
var listWillRender = this.displayList && this.displayList.active ? this.displayList.willRender(camera) : true;
return !(!listWillRender || GameObject.RENDER_MASK !== this.renderFlags || this.cameraFilter !== 0 && this.cameraFilter & camera.id);
},
/**
* Returns an array containing the display list index of either this Game Object, or if it has one,
* its parent Container. It then iterates up through all of the parent containers until it hits the
* root of the display list (which is index 0 in the returned array).
*
* Used internally by the InputPlugin but also useful if you wish to find out the display depth of
* this Game Object and all of its ancestors.
*
* @method Phaser.GameObjects.GameObject#getIndexList
* @since 3.4.0
*
* @return {number[]} An array of display list position indexes.
*/
getIndexList: function() {
var child = this;
var parent = this.parentContainer;
var indexes = [];
while (parent) {
indexes.unshift(parent.getIndex(child));
child = parent;
if (!parent.parentContainer) {
break;
} else {
parent = parent.parentContainer;
}
}
if (this.displayList) {
indexes.unshift(this.displayList.getIndex(child));
} else {
indexes.unshift(this.scene.sys.displayList.getIndex(child));
}
return indexes;
},
/**
* Adds this Game Object to the given Display List.
*
* If no Display List is specified, it will default to the Display List owned by the Scene to which
* this Game Object belongs.
*
* A Game Object can only exist on one Display List at any given time, but may move freely between them.
*
* If this Game Object is already on another Display List when this method is called, it will first
* be removed from it, before being added to the new list.
*
* You can query which list it is on by looking at the `Phaser.GameObjects.GameObject#displayList` property.
*
* If a Game Object isn't on any display list, it will not be rendered. If you just wish to temporarly
* disable it from rendering, consider using the `setVisible` method, instead.
*
* @method Phaser.GameObjects.GameObject#addToDisplayList
* @fires Phaser.Scenes.Events#ADDED_TO_SCENE
* @fires Phaser.GameObjects.Events#ADDED_TO_SCENE
* @since 3.53.0
*
* @param {(Phaser.GameObjects.DisplayList|Phaser.GameObjects.Layer)} [displayList] - The Display List to add to. Defaults to the Scene Display List.
*
* @return {this} This Game Object.
*/
addToDisplayList: function(displayList) {
if (displayList === void 0) {
displayList = this.scene.sys.displayList;
}
if (this.displayList && this.displayList !== displayList) {
this.removeFromDisplayList();
}
if (!displayList.exists(this)) {
this.displayList = displayList;
displayList.add(this, true);
displayList.queueDepthSort();
this.emit(Events.ADDED_TO_SCENE, this, this.scene);
displayList.events.emit(SceneEvents.ADDED_TO_SCENE, this, this.scene);
}
return this;
},
/**
* Adds this Game Object to the Update List belonging to the Scene.
*
* When a Game Object is added to the Update List it will have its `preUpdate` method called
* every game frame. This method is passed two parameters: `delta` and `time`.
*
* If you wish to run your own logic within `preUpdate` then you should always call
* `super.preUpdate(delta, time)` within it, or it may fail to process required operations,
* such as Sprite animations.
*
* @method Phaser.GameObjects.GameObject#addToUpdateList
* @since 3.53.0
*
* @return {this} This Game Object.
*/
addToUpdateList: function() {
if (this.scene && this.preUpdate) {
this.scene.sys.updateList.add(this);
}
return this;
},
/**
* Removes this Game Object from the Display List it is currently on.
*
* A Game Object can only exist on one Display List at any given time, but may move freely removed
* and added back at a later stage.
*
* You can query which list it is on by looking at the `Phaser.GameObjects.GameObject#displayList` property.
*
* If a Game Object isn't on any Display List, it will not be rendered. If you just wish to temporarly
* disable it from rendering, consider using the `setVisible` method, instead.
*
* @method Phaser.GameObjects.GameObject#removeFromDisplayList
* @fires Phaser.Scenes.Events#REMOVED_FROM_SCENE
* @fires Phaser.GameObjects.Events#REMOVED_FROM_SCENE
* @since 3.53.0
*
* @return {this} This Game Object.
*/
removeFromDisplayList: function() {
var displayList = this.displayList || this.scene.sys.displayList;
if (displayList && displayList.exists(this)) {
displayList.remove(this, true);
displayList.queueDepthSort();
this.displayList = null;
this.emit(Events.REMOVED_FROM_SCENE, this, this.scene);
displayList.events.emit(SceneEvents.REMOVED_FROM_SCENE, this, this.scene);
}
return this;
},
/**
* Removes this Game Object from the Scene's Update List.
*
* When a Game Object is on the Update List, it will have its `preUpdate` method called
* every game frame. Calling this method will remove it from the list, preventing this.
*
* Removing a Game Object from the Update List will stop most internal functions working.
* For example, removing a Sprite from the Update List will prevent it from being able to
* run animations.
*
* @method Phaser.GameObjects.GameObject#removeFromUpdateList
* @since 3.53.0
*
* @return {this} This Game Object.
*/
removeFromUpdateList: function() {
if (this.scene && this.preUpdate) {
this.scene.sys.updateList.remove(this);
}
return this;
},
/**
* Returns a reference to the underlying display list _array_ that contains this Game Object,
* which will be either the Scene's Display List or the internal list belonging
* to its parent Container, if it has one.
*
* If this Game Object is not on a display list or in a container, it will return `null`.
*
* You should be very careful with this method, and understand that it returns a direct reference to the
* internal array used by the Display List. Mutating this array directly can cause all kinds of subtle
* and difficult to debug issues in your game.
*
* @method Phaser.GameObjects.GameObject#getDisplayList
* @since 3.85.0
*
* @return {?Phaser.GameObjects.GameObject[]} The internal Display List array of Game Objects, or `null`.
*/
getDisplayList: function() {
var list = null;
if (this.parentContainer) {
list = this.parentContainer.list;
} else if (this.displayList) {
list = this.displayList.list;
}
return list;
},
/**
* Destroys this Game Object removing it from the Display List and Update List and
* severing all ties to parent resources.
*
* Also removes itself from the Input Manager and Physics Manager if previously enabled.
*
* Use this to remove a Game Object from your game if you don't ever plan to use it again.
* As long as no reference to it exists within your own code it should become free for
* garbage collection by the browser.
*
* If you just want to temporarily disable an object then look at using the
* Game Object Pool instead of destroying it, as destroyed objects cannot be resurrected.
*
* @method Phaser.GameObjects.GameObject#destroy
* @fires Phaser.GameObjects.Events#DESTROY
* @since 3.0.0
*
* @param {boolean} [fromScene=false] - `True` if this Game Object is being destroyed by the Scene, `false` if not.
*/
destroy: function(fromScene) {
if (!this.scene || this.ignoreDestroy) {
return;
}
if (fromScene === void 0) {
fromScene = false;
}
if (this.preDestroy) {
this.preDestroy.call(this);
}
this.emit(Events.DESTROY, this, fromScene);
this.removeAllListeners();
if (this.postPipelines) {
this.resetPostPipeline(true);
}
this.removeFromDisplayList();
this.removeFromUpdateList();
if (this.input) {
this.scene.sys.input.clear(this);
this.input = void 0;
}
if (this.data) {
this.data.destroy();
this.data = void 0;
}
if (this.body) {
this.body.destroy();
this.body = void 0;
}
if (this.preFX) {
this.preFX.destroy();
this.preFX = void 0;
}
if (this.postFX) {
this.postFX.destroy();
this.postFX = void 0;
}
this.active = false;
this.visible = false;
this.scene = void 0;
this.parentContainer = void 0;
}
});
GameObject.RENDER_MASK = 15;
module2.exports = GameObject;
}
),
/***/
44603: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var PluginCache = __webpack_require__2(37277);
var SceneEvents = __webpack_require__2(44594);
var GameObjectCreator = new Class({
initialize: function GameObjectCreator2(scene) {
this.scene = scene;
this.systems = scene.sys;
this.events = scene.sys.events;
this.displayList;
this.updateList;
this.events.once(SceneEvents.BOOT, this.boot, this);
this.events.on(SceneEvents.START, this.start, this);
},
/**
* This method is called automatically, only once, when the Scene is first created.
* Do not invoke it directly.
*
* @method Phaser.GameObjects.GameObjectCreator#boot
* @private
* @since 3.5.1
*/
boot: function() {
this.displayList = this.systems.displayList;
this.updateList = this.systems.updateList;
this.events.once(SceneEvents.DESTROY, this.destroy, this);
},
/**
* This method is called automatically by the Scene when it is starting up.
* It is responsible for creating local systems, properties and listening for Scene events.
* Do not invoke it directly.
*
* @method Phaser.GameObjects.GameObjectCreator#start
* @private
* @since 3.5.0
*/
start: function() {
this.events.once(SceneEvents.SHUTDOWN, this.shutdown, this);
},
/**
* The Scene that owns this plugin is shutting down.
* We need to kill and reset all internal properties as well as stop listening to Scene events.
*
* @method Phaser.GameObjects.GameObjectCreator#shutdown
* @private
* @since 3.0.0
*/
shutdown: function() {
this.events.off(SceneEvents.SHUTDOWN, this.shutdown, this);
},
/**
* The Scene that owns this plugin is being destroyed.
* We need to shutdown and then kill off all external references.
*
* @method Phaser.GameObjects.GameObjectCreator#destroy
* @private
* @since 3.0.0
*/
destroy: function() {
this.shutdown();
this.events.off(SceneEvents.START, this.start, this);
this.scene = null;
this.systems = null;
this.events = null;
this.displayList = null;
this.updateList = null;
}
});
GameObjectCreator.register = function(factoryType, factoryFunction) {
if (!GameObjectCreator.prototype.hasOwnProperty(factoryType)) {
GameObjectCreator.prototype[factoryType] = factoryFunction;
}
};
GameObjectCreator.remove = function(factoryType) {
if (GameObjectCreator.prototype.hasOwnProperty(factoryType)) {
delete GameObjectCreator.prototype[factoryType];
}
};
PluginCache.register("GameObjectCreator", GameObjectCreator, "make");
module2.exports = GameObjectCreator;
}
),
/***/
39429: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var PluginCache = __webpack_require__2(37277);
var SceneEvents = __webpack_require__2(44594);
var GameObjectFactory = new Class({
initialize: function GameObjectFactory2(scene) {
this.scene = scene;
this.systems = scene.sys;
this.events = scene.sys.events;
this.displayList;
this.updateList;
this.events.once(SceneEvents.BOOT, this.boot, this);
this.events.on(SceneEvents.START, this.start, this);
},
/**
* This method is called automatically, only once, when the Scene is first created.
* Do not invoke it directly.
*
* @method Phaser.GameObjects.GameObjectFactory#boot
* @private
* @since 3.5.1
*/
boot: function() {
this.displayList = this.systems.displayList;
this.updateList = this.systems.updateList;
this.events.once(SceneEvents.DESTROY, this.destroy, this);
},
/**
* This method is called automatically by the Scene when it is starting up.
* It is responsible for creating local systems, properties and listening for Scene events.
* Do not invoke it directly.
*
* @method Phaser.GameObjects.GameObjectFactory#start
* @private
* @since 3.5.0
*/
start: function() {
this.events.once(SceneEvents.SHUTDOWN, this.shutdown, this);
},
/**
* Adds an existing Game Object to this Scene.
*
* If the Game Object renders, it will be added to the Display List.
* If it has a `preUpdate` method, it will be added to the Update List.
*
* @method Phaser.GameObjects.GameObjectFactory#existing
* @since 3.0.0
*
* @generic {(Phaser.GameObjects.GameObject|Phaser.GameObjects.Group|Phaser.GameObjects.Layer)} G - [child,$return]
*
* @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.Group|Phaser.GameObjects.Layer)} child - The child to be added to this Scene.
*
* @return {Phaser.GameObjects.GameObject} The Game Object that was added.
*/
existing: function(child) {
if (child.renderCanvas || child.renderWebGL) {
this.displayList.add(child);
}
if (child.preUpdate) {
this.updateList.add(child);
}
return child;
},
/**
* The Scene that owns this plugin is shutting down.
* We need to kill and reset all internal properties as well as stop listening to Scene events.
*
* @method Phaser.GameObjects.GameObjectFactory#shutdown
* @private
* @since 3.0.0
*/
shutdown: function() {
this.events.off(SceneEvents.SHUTDOWN, this.shutdown, this);
},
/**
* The Scene that owns this plugin is being destroyed.
* We need to shutdown and then kill off all external references.
*
* @method Phaser.GameObjects.GameObjectFactory#destroy
* @private
* @since 3.0.0
*/
destroy: function() {
this.shutdown();
this.events.off(SceneEvents.START, this.start, this);
this.scene = null;
this.systems = null;
this.events = null;
this.displayList = null;
this.updateList = null;
}
});
GameObjectFactory.register = function(factoryType, factoryFunction) {
if (!GameObjectFactory.prototype.hasOwnProperty(factoryType)) {
GameObjectFactory.prototype[factoryType] = factoryFunction;
}
};
GameObjectFactory.remove = function(factoryType) {
if (GameObjectFactory.prototype.hasOwnProperty(factoryType)) {
delete GameObjectFactory.prototype[factoryType];
}
};
PluginCache.register("GameObjectFactory", GameObjectFactory, "add");
module2.exports = GameObjectFactory;
}
),
/***/
91296: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var TransformMatrix = __webpack_require__2(61340);
var tempMatrix1 = new TransformMatrix();
var tempMatrix2 = new TransformMatrix();
var tempMatrix3 = new TransformMatrix();
var result = { camera: tempMatrix1, sprite: tempMatrix2, calc: tempMatrix3 };
var GetCalcMatrix = function(src, camera, parentMatrix) {
var camMatrix = tempMatrix1;
var spriteMatrix = tempMatrix2;
var calcMatrix = tempMatrix3;
spriteMatrix.applyITRS(src.x, src.y, src.rotation, src.scaleX, src.scaleY);
camMatrix.copyFrom(camera.matrix);
if (parentMatrix) {
camMatrix.multiplyWithOffset(parentMatrix, -camera.scrollX * src.scrollFactorX, -camera.scrollY * src.scrollFactorY);
spriteMatrix.e = src.x;
spriteMatrix.f = src.y;
} else {
spriteMatrix.e -= camera.scrollX * src.scrollFactorX;
spriteMatrix.f -= camera.scrollY * src.scrollFactorY;
}
camMatrix.multiply(spriteMatrix, calcMatrix);
return result;
};
module2.exports = GetCalcMatrix;
}
),
/***/
45027: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var ProcessQueue = __webpack_require__2(25774);
var PluginCache = __webpack_require__2(37277);
var SceneEvents = __webpack_require__2(44594);
var UpdateList = new Class({
Extends: ProcessQueue,
initialize: function UpdateList2(scene) {
ProcessQueue.call(this);
this.checkQueue = true;
this.scene = scene;
this.systems = scene.sys;
scene.sys.events.once(SceneEvents.BOOT, this.boot, this);
scene.sys.events.on(SceneEvents.START, this.start, this);
},
/**
* This method is called automatically, only once, when the Scene is first created.
* Do not invoke it directly.
*
* @method Phaser.GameObjects.UpdateList#boot
* @private
* @since 3.5.1
*/
boot: function() {
this.systems.events.once(SceneEvents.DESTROY, this.destroy, this);
},
/**
* This method is called automatically by the Scene when it is starting up.
* It is responsible for creating local systems, properties and listening for Scene events.
* Do not invoke it directly.
*
* @method Phaser.GameObjects.UpdateList#start
* @private
* @since 3.5.0
*/
start: function() {
var eventEmitter = this.systems.events;
eventEmitter.on(SceneEvents.PRE_UPDATE, this.update, this);
eventEmitter.on(SceneEvents.UPDATE, this.sceneUpdate, this);
eventEmitter.once(SceneEvents.SHUTDOWN, this.shutdown, this);
},
/**
* The update step.
*
* Pre-updates every active Game Object in the list.
*
* @method Phaser.GameObjects.UpdateList#sceneUpdate
* @since 3.20.0
*
* @param {number} time - The current timestamp.
* @param {number} delta - The delta time elapsed since the last frame.
*/
sceneUpdate: function(time, delta) {
var list = this._active;
var length = list.length;
for (var i = 0; i < length; i++) {
var gameObject = list[i];
if (gameObject.active) {
gameObject.preUpdate.call(gameObject, time, delta);
}
}
},
/**
* The Scene that owns this plugin is shutting down.
*
* We need to kill and reset all internal properties as well as stop listening to Scene events.
*
* @method Phaser.GameObjects.UpdateList#shutdown
* @since 3.0.0
*/
shutdown: function() {
var i = this._active.length;
while (i--) {
this._active[i].destroy(true);
}
i = this._pending.length;
while (i--) {
this._pending[i].destroy(true);
}
i = this._destroy.length;
while (i--) {
this._destroy[i].destroy(true);
}
this._toProcess = 0;
this._pending = [];
this._active = [];
this._destroy = [];
this.removeAllListeners();
var eventEmitter = this.systems.events;
eventEmitter.off(SceneEvents.PRE_UPDATE, this.update, this);
eventEmitter.off(SceneEvents.UPDATE, this.sceneUpdate, this);
eventEmitter.off(SceneEvents.SHUTDOWN, this.shutdown, this);
},
/**
* The Scene that owns this plugin is being destroyed.
*
* We need to shutdown and then kill off all external references.
*
* @method Phaser.GameObjects.UpdateList#destroy
* @since 3.0.0
*/
destroy: function() {
this.shutdown();
this.systems.events.off(SceneEvents.START, this.start, this);
this.scene = null;
this.systems = null;
}
/**
* Adds a new item to the Update List.
*
* The item is added to the pending list and made active in the next update.
*
* @method Phaser.GameObjects.UpdateList#add
* @since 3.0.0
*
* @param {*} item - The item to add to the queue.
*
* @return {*} The item that was added.
*/
/**
* Removes an item from the Update List.
*
* The item is added to the pending destroy and fully removed in the next update.
*
* @method Phaser.GameObjects.UpdateList#remove
* @since 3.0.0
*
* @param {*} item - The item to be removed from the queue.
*
* @return {*} The item that was removed.
*/
/**
* Removes all active items from this Update List.
*
* All the items are marked as 'pending destroy' and fully removed in the next update.
*
* @method Phaser.GameObjects.UpdateList#removeAll
* @since 3.20.0
*
* @return {this} This Update List object.
*/
/**
* Update this queue. First it will process any items awaiting destruction, and remove them.
*
* Then it will check to see if there are any items pending insertion, and move them to an
* active state. Finally, it will return a list of active items for further processing.
*
* @method Phaser.GameObjects.UpdateList#update
* @since 3.0.0
*
* @return {Array.<*>} A list of active items.
*/
/**
* Returns the current list of active items.
*
* This method returns a reference to the active list array, not a copy of it.
* Therefore, be careful to not modify this array outside of the ProcessQueue.
*
* @method Phaser.GameObjects.UpdateList#getActive
* @since 3.0.0
*
* @return {Array.<*>} A list of active items.
*/
/**
* The number of entries in the active list.
*
* @name Phaser.GameObjects.UpdateList#length
* @type {number}
* @readonly
* @since 3.20.0
*/
});
PluginCache.register("UpdateList", UpdateList, "updateList");
module2.exports = UpdateList;
}
),
/***/
3217: (
/***/
(module2) => {
var BatchChar = function(pipeline, src, char, glyph, offsetX, offsetY, calcMatrix, roundPixels, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, textureUnit) {
var x = char.x - src.displayOriginX + offsetX;
var y = char.y - src.displayOriginY + offsetY;
var xw = x + char.w;
var yh = y + char.h;
var a = calcMatrix.a;
var b = calcMatrix.b;
var c = calcMatrix.c;
var d = calcMatrix.d;
var e = calcMatrix.e;
var f = calcMatrix.f;
var tx0 = x * a + y * c + e;
var ty0 = x * b + y * d + f;
var tx1 = x * a + yh * c + e;
var ty1 = x * b + yh * d + f;
var tx2 = xw * a + yh * c + e;
var ty2 = xw * b + yh * d + f;
var tx3 = xw * a + y * c + e;
var ty3 = xw * b + y * d + f;
if (roundPixels) {
tx0 = Math.round(tx0);
ty0 = Math.round(ty0);
tx1 = Math.round(tx1);
ty1 = Math.round(ty1);
tx2 = Math.round(tx2);
ty2 = Math.round(ty2);
tx3 = Math.round(tx3);
ty3 = Math.round(ty3);
}
pipeline.batchQuad(src, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, glyph.u0, glyph.v0, glyph.u1, glyph.v1, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, textureUnit);
};
module2.exports = BatchChar;
}
),
/***/
53048: (
/***/
(module2) => {
var GetBitmapTextSize = function(src, round, updateOrigin, out) {
if (updateOrigin === void 0) {
updateOrigin = false;
}
if (out === void 0) {
out = {
local: {
x: 0,
y: 0,
width: 0,
height: 0
},
global: {
x: 0,
y: 0,
width: 0,
height: 0
},
lines: {
shortest: 0,
longest: 0,
lengths: null,
height: 0
},
wrappedText: "",
words: [],
characters: [],
scaleX: 0,
scaleY: 0
};
return out;
}
var text = src.text;
var textLength = text.length;
var maxWidth = src.maxWidth;
var wordWrapCharCode = src.wordWrapCharCode;
var bx = Number.MAX_VALUE;
var by = Number.MAX_VALUE;
var bw = 0;
var bh = 0;
var chars = src.fontData.chars;
var lineHeight = src.fontData.lineHeight;
var letterSpacing = src.letterSpacing;
var lineSpacing = src.lineSpacing;
var xAdvance = 0;
var yAdvance = 0;
var charCode = 0;
var glyph = null;
var align = src._align;
var x = 0;
var y = 0;
var scale = src.fontSize / src.fontData.size;
var sx = scale * src.scaleX;
var sy = scale * src.scaleY;
var lastGlyph = null;
var lastCharCode = 0;
var lineWidths = [];
var shortestLine = Number.MAX_VALUE;
var longestLine = 0;
var currentLine = 0;
var currentLineWidth = 0;
var i;
var j;
var lines;
var words = [];
var characters = [];
var current = null;
var measureTextWidth = function(text2, fontData) {
var width = 0;
for (var i2 = 0; i2 < text2.length; i2++) {
var charCode2 = text2.charCodeAt(i2);
var glyph2 = fontData.chars[charCode2];
if (glyph2) {
width += glyph2.xAdvance;
}
}
return width * sx;
};
if (maxWidth > 0) {
lines = text.split("\n");
var wrappedLines = [];
for (i = 0; i < lines.length; i++) {
var line = lines[i];
var word = "";
var wrappedLine = "";
var lineToCheck = "";
var lineWithWord = "";
for (j = 0; j < line.length; j++) {
charCode = line.charCodeAt(j);
word += line[j];
if (charCode === wordWrapCharCode || j === line.length - 1) {
lineWithWord = lineToCheck + word;
var textWidth = measureTextWidth(lineWithWord, src.fontData);
if (textWidth <= maxWidth) {
lineToCheck = lineWithWord;
} else {
wrappedLine += (wrappedLine ? "\n" : "") + lineToCheck;
lineToCheck = word;
}
word = "";
}
}
wrappedLine += (wrappedLine ? "\n" : "") + lineToCheck;
wrappedLines.push(wrappedLine);
}
text = wrappedLines.join("\n");
var prev;
var offset = 0;
var crs = [];
for (i = 0; i < words.length; i++) {
var entry = words[i];
var left = entry.x;
var right = entry.x + entry.w;
if (left === 0) {
offset = 0;
prev = null;
}
if (prev) {
var diff = left - (prev.x + prev.w);
offset = left - (diff + prev.w);
prev = null;
}
var checkLeft = left - offset;
var checkRight = right - offset;
if (checkLeft > maxWidth || checkRight > maxWidth) {
crs.push(entry.i - 1);
if (entry.cr) {
crs.push(entry.i + entry.word.length);
offset = 0;
prev = null;
} else {
prev = entry;
}
} else if (entry.cr) {
crs.push(entry.i + entry.word.length);
offset = 0;
prev = null;
}
}
var stringInsert = function(str, index, value) {
return str.substr(0, index) + value + str.substr(index + 1);
};
for (i = crs.length - 1; i >= 0; i--) {
if (crs[i] > -1) {
text = stringInsert(text, crs[i], "\n");
}
}
out.wrappedText = text;
textLength = text.length;
words = [];
current = null;
}
var charIndex = 0;
for (i = 0; i < textLength; i++) {
charCode = text.charCodeAt(i);
if (charCode === 10) {
if (current !== null) {
words.push({
word: current.word,
i: current.i,
x: current.x * sx,
y: current.y * sy,
w: current.w * sx,
h: current.h * sy
});
current = null;
}
lastGlyph = null;
lineWidths[currentLine] = currentLineWidth;
if (currentLineWidth > longestLine) {
longestLine = currentLineWidth;
}
if (currentLineWidth < shortestLine) {
shortestLine = currentLineWidth;
}
currentLine++;
currentLineWidth = 0;
xAdvance = 0;
yAdvance = (lineHeight + lineSpacing) * currentLine;
continue;
}
glyph = chars[charCode];
if (!glyph) {
continue;
}
x = xAdvance;
y = yAdvance;
if (lastGlyph !== null) {
var kerningOffset = glyph.kerning[lastCharCode];
x += kerningOffset !== void 0 ? kerningOffset : 0;
}
if (bx > x) {
bx = x;
}
if (by > y) {
by = y;
}
var gw = x + glyph.xAdvance;
var gh = y + lineHeight;
if (bw < gw) {
bw = gw;
}
if (bh < gh) {
bh = gh;
}
var charWidth = glyph.xOffset + glyph.xAdvance + (kerningOffset !== void 0 ? kerningOffset : 0);
if (charCode === wordWrapCharCode) {
if (current !== null) {
words.push({
word: current.word,
i: current.i,
x: current.x * sx,
y: current.y * sy,
w: current.w * sx,
h: current.h * sy
});
current = null;
}
} else {
if (current === null) {
current = { word: "", i: charIndex, x: xAdvance, y: yAdvance, w: 0, h: lineHeight };
}
current.word = current.word.concat(text[i]);
current.w += charWidth;
}
characters.push({
i: charIndex,
idx: i,
char: text[i],
code: charCode,
x: (glyph.xOffset + x) * scale,
y: (glyph.yOffset + yAdvance) * scale,
w: glyph.width * scale,
h: glyph.height * scale,
t: yAdvance * scale,
r: gw * scale,
b: lineHeight * scale,
line: currentLine,
glyph
});
xAdvance += glyph.xAdvance + letterSpacing + (kerningOffset !== void 0 ? kerningOffset : 0);
lastGlyph = glyph;
lastCharCode = charCode;
currentLineWidth = gw * scale;
charIndex++;
}
if (current !== null) {
words.push({
word: current.word,
i: current.i,
x: current.x * sx,
y: current.y * sy,
w: current.w * sx,
h: current.h * sy
});
}
lineWidths[currentLine] = currentLineWidth;
if (currentLineWidth > longestLine) {
longestLine = currentLineWidth;
}
if (currentLineWidth < shortestLine) {
shortestLine = currentLineWidth;
}
if (align > 0) {
for (var c = 0; c < characters.length; c++) {
var currentChar = characters[c];
if (align === 1) {
var ax1 = (longestLine - lineWidths[currentChar.line]) / 2;
currentChar.x += ax1;
currentChar.r += ax1;
} else if (align === 2) {
var ax2 = longestLine - lineWidths[currentChar.line];
currentChar.x += ax2;
currentChar.r += ax2;
}
}
}
var local = out.local;
var global = out.global;
lines = out.lines;
local.x = bx * scale;
local.y = by * scale;
local.width = bw * scale;
local.height = bh * scale;
global.x = src.x - src._displayOriginX + bx * sx;
global.y = src.y - src._displayOriginY + by * sy;
global.width = bw * sx;
global.height = bh * sy;
lines.shortest = shortestLine;
lines.longest = longestLine;
lines.lengths = lineWidths;
if (round) {
local.x = Math.ceil(local.x);
local.y = Math.ceil(local.y);
local.width = Math.ceil(local.width);
local.height = Math.ceil(local.height);
global.x = Math.ceil(global.x);
global.y = Math.ceil(global.y);
global.width = Math.ceil(global.width);
global.height = Math.ceil(global.height);
lines.shortest = Math.ceil(shortestLine);
lines.longest = Math.ceil(longestLine);
}
if (updateOrigin) {
src._displayOriginX = src.originX * local.width;
src._displayOriginY = src.originY * local.height;
global.x = src.x - src._displayOriginX * src.scaleX;
global.y = src.y - src._displayOriginY * src.scaleY;
if (round) {
global.x = Math.ceil(global.x);
global.y = Math.ceil(global.y);
}
}
out.words = words;
out.characters = characters;
out.lines.height = lineHeight;
out.scale = scale;
out.scaleX = src.scaleX;
out.scaleY = src.scaleY;
return out;
};
module2.exports = GetBitmapTextSize;
}
),
/***/
61327: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var ParseXMLBitmapFont = __webpack_require__2(21859);
var ParseFromAtlas = function(scene, fontName, textureKey, frameKey, xmlKey, xSpacing, ySpacing) {
var texture = scene.sys.textures.get(textureKey);
var frame = texture.get(frameKey);
var xml = scene.sys.cache.xml.get(xmlKey);
if (frame && xml) {
var data = ParseXMLBitmapFont(xml, frame, xSpacing, ySpacing, texture);
scene.sys.cache.bitmapFont.add(fontName, { data, texture: textureKey, frame: frameKey, fromAtlas: true });
return true;
} else {
return false;
}
};
module2.exports = ParseFromAtlas;
}
),
/***/
6925: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetValue = __webpack_require__2(35154);
var ParseRetroFont = function(scene, config) {
var w = config.width;
var h = config.height;
var cx = Math.floor(w / 2);
var cy = Math.floor(h / 2);
var letters = GetValue(config, "chars", "");
if (letters === "") {
return;
}
var key = GetValue(config, "image", "");
var frame = scene.sys.textures.getFrame(key);
var textureX = frame.cutX;
var textureY = frame.cutY;
var textureWidth = frame.source.width;
var textureHeight = frame.source.height;
var offsetX = GetValue(config, "offset.x", 0);
var offsetY = GetValue(config, "offset.y", 0);
var spacingX = GetValue(config, "spacing.x", 0);
var spacingY = GetValue(config, "spacing.y", 0);
var lineSpacing = GetValue(config, "lineSpacing", 0);
var charsPerRow = GetValue(config, "charsPerRow", null);
if (charsPerRow === null) {
charsPerRow = textureWidth / w;
if (charsPerRow > letters.length) {
charsPerRow = letters.length;
}
}
var x = offsetX;
var y = offsetY;
var data = {
retroFont: true,
font: key,
size: w,
lineHeight: h + lineSpacing,
chars: {}
};
var r = 0;
for (var i = 0; i < letters.length; i++) {
var charCode = letters.charCodeAt(i);
var u0 = (textureX + x) / textureWidth;
var v0 = (textureY + y) / textureHeight;
var u1 = (textureX + x + w) / textureWidth;
var v1 = (textureY + y + h) / textureHeight;
data.chars[charCode] = {
x,
y,
width: w,
height: h,
centerX: cx,
centerY: cy,
xOffset: 0,
yOffset: 0,
xAdvance: w,
data: {},
kerning: {},
u0,
v0,
u1,
v1
};
r++;
if (r === charsPerRow) {
r = 0;
x = offsetX;
y += h + spacingY;
} else {
x += w + spacingX;
}
}
var entry = {
data,
frame: null,
texture: key
};
return entry;
};
module2.exports = ParseRetroFont;
}
),
/***/
21859: (
/***/
(module2) => {
function getValue(node, attribute) {
return parseInt(node.getAttribute(attribute), 10);
}
var ParseXMLBitmapFont = function(xml, frame, xSpacing, ySpacing, texture) {
if (xSpacing === void 0) {
xSpacing = 0;
}
if (ySpacing === void 0) {
ySpacing = 0;
}
var textureX = frame.cutX;
var textureY = frame.cutY;
var textureWidth = frame.source.width;
var textureHeight = frame.source.height;
var sourceIndex = frame.sourceIndex;
var data = {};
var info = xml.getElementsByTagName("info")[0];
var common = xml.getElementsByTagName("common")[0];
data.font = info.getAttribute("face");
data.size = getValue(info, "size");
data.lineHeight = getValue(common, "lineHeight") + ySpacing;
data.chars = {};
var letters = xml.getElementsByTagName("char");
var adjustForTrim = frame !== void 0 && frame.trimmed;
if (adjustForTrim) {
var top = frame.height;
var left = frame.width;
}
for (var i = 0; i < letters.length; i++) {
var node = letters[i];
var charCode = getValue(node, "id");
var letter = String.fromCharCode(charCode);
var gx = getValue(node, "x");
var gy = getValue(node, "y");
var gw = getValue(node, "width");
var gh = getValue(node, "height");
if (adjustForTrim) {
if (gx < left) {
left = gx;
}
if (gy < top) {
top = gy;
}
}
if (adjustForTrim && top !== 0 && left !== 0) {
gx -= frame.x;
gy -= frame.y;
}
var u0 = (textureX + gx) / textureWidth;
var v0 = (textureY + gy) / textureHeight;
var u1 = (textureX + gx + gw) / textureWidth;
var v1 = (textureY + gy + gh) / textureHeight;
data.chars[charCode] = {
x: gx,
y: gy,
width: gw,
height: gh,
centerX: Math.floor(gw / 2),
centerY: Math.floor(gh / 2),
xOffset: getValue(node, "xoffset"),
yOffset: getValue(node, "yoffset"),
xAdvance: getValue(node, "xadvance") + xSpacing,
data: {},
kerning: {},
u0,
v0,
u1,
v1
};
if (texture && gw !== 0 && gh !== 0) {
var charFrame = texture.add(letter, sourceIndex, gx, gy, gw, gh);
if (charFrame) {
charFrame.setUVs(gw, gh, u0, v0, u1, v1);
}
}
}
var kernings = xml.getElementsByTagName("kerning");
for (i = 0; i < kernings.length; i++) {
var kern = kernings[i];
var first = getValue(kern, "first");
var second = getValue(kern, "second");
var amount = getValue(kern, "amount");
data.chars[second].kerning[first] = amount;
}
return data;
};
module2.exports = ParseXMLBitmapFont;
}
),
/***/
196: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var RETRO_FONT_CONST = __webpack_require__2(87662);
var Extend = __webpack_require__2(79291);
var RetroFont = { Parse: __webpack_require__2(6925) };
RetroFont = Extend(false, RetroFont, RETRO_FONT_CONST);
module2.exports = RetroFont;
}
),
/***/
87662: (
/***/
(module2) => {
var RETRO_FONT_CONST = {
/**
* Text Set 1 = !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~
*
* @name Phaser.GameObjects.RetroFont.TEXT_SET1
* @type {string}
* @since 3.6.0
*/
TEXT_SET1: " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~",
/**
* Text Set 2 = !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ
*
* @name Phaser.GameObjects.RetroFont.TEXT_SET2
* @type {string}
* @since 3.6.0
*/
TEXT_SET2: ` !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ`,
/**
* Text Set 3 = ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
*
* @name Phaser.GameObjects.RetroFont.TEXT_SET3
* @type {string}
* @since 3.6.0
*/
TEXT_SET3: "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ",
/**
* Text Set 4 = ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789
*
* @name Phaser.GameObjects.RetroFont.TEXT_SET4
* @type {string}
* @since 3.6.0
*/
TEXT_SET4: "ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789",
/**
* Text Set 5 = ABCDEFGHIJKLMNOPQRSTUVWXYZ.,/() '!?-*:0123456789
*
* @name Phaser.GameObjects.RetroFont.TEXT_SET5
* @type {string}
* @since 3.6.0
*/
TEXT_SET5: "ABCDEFGHIJKLMNOPQRSTUVWXYZ.,/() '!?-*:0123456789",
/**
* Text Set 6 = ABCDEFGHIJKLMNOPQRSTUVWXYZ!?:;0123456789"(),-.'
*
* @name Phaser.GameObjects.RetroFont.TEXT_SET6
* @type {string}
* @since 3.6.0
*/
TEXT_SET6: `ABCDEFGHIJKLMNOPQRSTUVWXYZ!?:;0123456789"(),-.' `,
/**
* Text Set 7 = AGMSY+:4BHNTZ!;5CIOU.?06DJPV,(17EKQW")28FLRX-'39
*
* @name Phaser.GameObjects.RetroFont.TEXT_SET7
* @type {string}
* @since 3.6.0
*/
TEXT_SET7: `AGMSY+:4BHNTZ!;5CIOU.?06DJPV,(17EKQW")28FLRX-'39`,
/**
* Text Set 8 = 0123456789 .ABCDEFGHIJKLMNOPQRSTUVWXYZ
*
* @name Phaser.GameObjects.RetroFont.TEXT_SET8
* @type {string}
* @since 3.6.0
*/
TEXT_SET8: "0123456789 .ABCDEFGHIJKLMNOPQRSTUVWXYZ",
/**
* Text Set 9 = ABCDEFGHIJKLMNOPQRSTUVWXYZ()-0123456789.:,'"?!
*
* @name Phaser.GameObjects.RetroFont.TEXT_SET9
* @type {string}
* @since 3.6.0
*/
TEXT_SET9: `ABCDEFGHIJKLMNOPQRSTUVWXYZ()-0123456789.:,'"?!`,
/**
* Text Set 10 = ABCDEFGHIJKLMNOPQRSTUVWXYZ
*
* @name Phaser.GameObjects.RetroFont.TEXT_SET10
* @type {string}
* @since 3.6.0
*/
TEXT_SET10: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
/**
* Text Set 11 = ABCDEFGHIJKLMNOPQRSTUVWXYZ.,"-+!?()':;0123456789
*
* @name Phaser.GameObjects.RetroFont.TEXT_SET11
* @since 3.6.0
* @type {string}
*/
TEXT_SET11: `ABCDEFGHIJKLMNOPQRSTUVWXYZ.,"-+!?()':;0123456789`
};
module2.exports = RETRO_FONT_CONST;
}
),
/***/
2638: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BitmapText = __webpack_require__2(22186);
var Class = __webpack_require__2(83419);
var Render = __webpack_require__2(12310);
var DynamicBitmapText = new Class({
Extends: BitmapText,
Mixins: [
Render
],
initialize: function DynamicBitmapText2(scene, x, y, font, text, size, align) {
BitmapText.call(this, scene, x, y, font, text, size, align);
this.type = "DynamicBitmapText";
this.scrollX = 0;
this.scrollY = 0;
this.cropWidth = 0;
this.cropHeight = 0;
this.displayCallback;
this.callbackData = {
parent: this,
color: 0,
tint: {
topLeft: 0,
topRight: 0,
bottomLeft: 0,
bottomRight: 0
},
index: 0,
charCode: 0,
x: 0,
y: 0,
scale: 0,
rotation: 0,
data: 0
};
},
/**
* Set the crop size of this Bitmap Text.
*
* @method Phaser.GameObjects.DynamicBitmapText#setSize
* @since 3.0.0
*
* @param {number} width - The width of the crop.
* @param {number} height - The height of the crop.
*
* @return {this} This Game Object.
*/
setSize: function(width, height) {
this.cropWidth = width;
this.cropHeight = height;
return this;
},
/**
* Set a callback that alters how each character of the Bitmap Text is rendered.
*
* The callback receives a {@link Phaser.Types.GameObjects.BitmapText.DisplayCallbackConfig} object that contains information about the character that's
* about to be rendered.
*
* It should return an object with `x`, `y`, `scale` and `rotation` properties that will be used instead of the
* usual values when rendering.
*
* @method Phaser.GameObjects.DynamicBitmapText#setDisplayCallback
* @since 3.0.0
*
* @param {Phaser.Types.GameObjects.BitmapText.DisplayCallback} callback - The display callback to set.
*
* @return {this} This Game Object.
*/
setDisplayCallback: function(callback) {
this.displayCallback = callback;
return this;
},
/**
* Set the horizontal scroll position of this Bitmap Text.
*
* @method Phaser.GameObjects.DynamicBitmapText#setScrollX
* @since 3.0.0
*
* @param {number} value - The horizontal scroll position to set.
*
* @return {this} This Game Object.
*/
setScrollX: function(value) {
this.scrollX = value;
return this;
},
/**
* Set the vertical scroll position of this Bitmap Text.
*
* @method Phaser.GameObjects.DynamicBitmapText#setScrollY
* @since 3.0.0
*
* @param {number} value - The vertical scroll position to set.
*
* @return {this} This Game Object.
*/
setScrollY: function(value) {
this.scrollY = value;
return this;
}
});
module2.exports = DynamicBitmapText;
}
),
/***/
86741: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var SetTransform = __webpack_require__2(20926);
var DynamicBitmapTextCanvasRenderer = function(renderer, src, camera, parentMatrix) {
var text = src._text;
var textLength = text.length;
var ctx = renderer.currentContext;
if (textLength === 0 || !SetTransform(renderer, ctx, src, camera, parentMatrix)) {
return;
}
camera.addToRenderList(src);
var textureFrame = src.fromAtlas ? src.frame : src.texture.frames["__BASE"];
var displayCallback = src.displayCallback;
var callbackData = src.callbackData;
var chars = src.fontData.chars;
var lineHeight = src.fontData.lineHeight;
var letterSpacing = src._letterSpacing;
var xAdvance = 0;
var yAdvance = 0;
var charCode = 0;
var glyph = null;
var glyphX = 0;
var glyphY = 0;
var glyphW = 0;
var glyphH = 0;
var x = 0;
var y = 0;
var lastGlyph = null;
var lastCharCode = 0;
var image = src.frame.source.image;
var textureX = textureFrame.cutX;
var textureY = textureFrame.cutY;
var rotation = 0;
var scale = 0;
var baseScale = src._fontSize / src.fontData.size;
var align = src._align;
var currentLine = 0;
var lineOffsetX = 0;
src.getTextBounds(false);
var lineData = src._bounds.lines;
if (align === 1) {
lineOffsetX = (lineData.longest - lineData.lengths[0]) / 2;
} else if (align === 2) {
lineOffsetX = lineData.longest - lineData.lengths[0];
}
ctx.translate(-src.displayOriginX, -src.displayOriginY);
var roundPixels = camera.roundPixels;
if (src.cropWidth > 0 && src.cropHeight > 0) {
ctx.beginPath();
ctx.rect(0, 0, src.cropWidth, src.cropHeight);
ctx.clip();
}
for (var i = 0; i < textLength; i++) {
scale = baseScale;
rotation = 0;
charCode = text.charCodeAt(i);
if (charCode === 10) {
currentLine++;
if (align === 1) {
lineOffsetX = (lineData.longest - lineData.lengths[currentLine]) / 2;
} else if (align === 2) {
lineOffsetX = lineData.longest - lineData.lengths[currentLine];
}
xAdvance = 0;
yAdvance += lineHeight;
lastGlyph = null;
continue;
}
glyph = chars[charCode];
if (!glyph) {
continue;
}
glyphX = textureX + glyph.x;
glyphY = textureY + glyph.y;
glyphW = glyph.width;
glyphH = glyph.height;
x = glyph.xOffset + xAdvance - src.scrollX;
y = glyph.yOffset + yAdvance - src.scrollY;
if (lastGlyph !== null) {
var kerningOffset = glyph.kerning[lastCharCode];
x += kerningOffset !== void 0 ? kerningOffset : 0;
}
if (displayCallback) {
callbackData.index = i;
callbackData.charCode = charCode;
callbackData.x = x;
callbackData.y = y;
callbackData.scale = scale;
callbackData.rotation = rotation;
callbackData.data = glyph.data;
var output = displayCallback(callbackData);
x = output.x;
y = output.y;
scale = output.scale;
rotation = output.rotation;
}
x *= scale;
y *= scale;
x += lineOffsetX;
xAdvance += glyph.xAdvance + letterSpacing + (kerningOffset !== void 0 ? kerningOffset : 0);
lastGlyph = glyph;
lastCharCode = charCode;
if (glyphW === 0 || glyphH === 0 || charCode === 32) {
continue;
}
if (roundPixels) {
x = Math.round(x);
y = Math.round(y);
}
ctx.save();
ctx.translate(x, y);
ctx.rotate(rotation);
ctx.scale(scale, scale);
ctx.drawImage(image, glyphX, glyphY, glyphW, glyphH, 0, 0, glyphW, glyphH);
ctx.restore();
}
ctx.restore();
};
module2.exports = DynamicBitmapTextCanvasRenderer;
}
),
/***/
11164: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var BitmapText = __webpack_require__2(2638);
var BuildGameObject = __webpack_require__2(25305);
var GameObjectCreator = __webpack_require__2(44603);
var GetAdvancedValue = __webpack_require__2(23568);
GameObjectCreator.register("dynamicBitmapText", function(config, addToScene) {
if (config === void 0) {
config = {};
}
var font = GetAdvancedValue(config, "font", "");
var text = GetAdvancedValue(config, "text", "");
var size = GetAdvancedValue(config, "size", false);
var bitmapText = new BitmapText(this.scene, 0, 0, font, text, size);
if (addToScene !== void 0) {
config.add = addToScene;
}
BuildGameObject(this.scene, bitmapText, config);
return bitmapText;
});
}
),
/***/
72566: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var DynamicBitmapText = __webpack_require__2(2638);
var GameObjectFactory = __webpack_require__2(39429);
GameObjectFactory.register("dynamicBitmapText", function(x, y, font, text, size) {
return this.displayList.add(new DynamicBitmapText(this.scene, x, y, font, text, size));
});
}
),
/***/
12310: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(73482);
}
if (true) {
renderCanvas = __webpack_require__2(86741);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
73482: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetCalcMatrix = __webpack_require__2(91296);
var TransformMatrix = __webpack_require__2(61340);
var Utils = __webpack_require__2(70554);
var tempMatrix = new TransformMatrix();
var DynamicBitmapTextWebGLRenderer = function(renderer, src, camera, parentMatrix) {
var text = src.text;
var textLength = text.length;
if (textLength === 0) {
return;
}
camera.addToRenderList(src);
var pipeline = renderer.pipelines.set(src.pipeline, src);
var result = GetCalcMatrix(src, camera, parentMatrix);
renderer.pipelines.preBatch(src);
var spriteMatrix = result.sprite;
var calcMatrix = result.calc;
var fontMatrix = tempMatrix;
var crop = src.cropWidth > 0 || src.cropHeight > 0;
if (crop) {
pipeline.flush();
renderer.pushScissor(
calcMatrix.tx,
calcMatrix.ty,
src.cropWidth * calcMatrix.scaleX,
src.cropHeight * calcMatrix.scaleY
);
}
var frame = src.frame;
var texture = frame.glTexture;
var tintEffect = src.tintFill;
var tintTL = Utils.getTintAppendFloatAlpha(src.tintTopLeft, camera.alpha * src._alphaTL);
var tintTR = Utils.getTintAppendFloatAlpha(src.tintTopRight, camera.alpha * src._alphaTR);
var tintBL = Utils.getTintAppendFloatAlpha(src.tintBottomLeft, camera.alpha * src._alphaBL);
var tintBR = Utils.getTintAppendFloatAlpha(src.tintBottomRight, camera.alpha * src._alphaBR);
var textureUnit = pipeline.setGameObject(src);
var xAdvance = 0;
var yAdvance = 0;
var charCode = 0;
var lastCharCode = 0;
var letterSpacing = src.letterSpacing;
var glyph;
var glyphW = 0;
var glyphH = 0;
var lastGlyph;
var scrollX = src.scrollX;
var scrollY = src.scrollY;
var fontData = src.fontData;
var chars = fontData.chars;
var lineHeight = fontData.lineHeight;
var scale = src.fontSize / fontData.size;
var rotation = 0;
var align = src._align;
var currentLine = 0;
var lineOffsetX = 0;
var bounds = src.getTextBounds(false);
if (src.maxWidth > 0) {
text = bounds.wrappedText;
textLength = text.length;
}
var lineData = src._bounds.lines;
if (align === 1) {
lineOffsetX = (lineData.longest - lineData.lengths[0]) / 2;
} else if (align === 2) {
lineOffsetX = lineData.longest - lineData.lengths[0];
}
var roundPixels = camera.roundPixels;
var displayCallback = src.displayCallback;
var callbackData = src.callbackData;
for (var i = 0; i < textLength; i++) {
charCode = text.charCodeAt(i);
if (charCode === 10) {
currentLine++;
if (align === 1) {
lineOffsetX = (lineData.longest - lineData.lengths[currentLine]) / 2;
} else if (align === 2) {
lineOffsetX = lineData.longest - lineData.lengths[currentLine];
}
xAdvance = 0;
yAdvance += lineHeight;
lastGlyph = null;
continue;
}
glyph = chars[charCode];
if (!glyph) {
continue;
}
glyphW = glyph.width;
glyphH = glyph.height;
var x = glyph.xOffset + xAdvance - scrollX;
var y = glyph.yOffset + yAdvance - scrollY;
if (lastGlyph !== null) {
var kerningOffset = glyph.kerning[lastCharCode] || 0;
x += kerningOffset;
xAdvance += kerningOffset;
}
xAdvance += glyph.xAdvance + letterSpacing;
lastGlyph = glyph;
lastCharCode = charCode;
if (glyphW === 0 || glyphH === 0 || charCode === 32) {
continue;
}
scale = src.fontSize / src.fontData.size;
rotation = 0;
if (displayCallback) {
callbackData.color = 0;
callbackData.tint.topLeft = tintTL;
callbackData.tint.topRight = tintTR;
callbackData.tint.bottomLeft = tintBL;
callbackData.tint.bottomRight = tintBR;
callbackData.index = i;
callbackData.charCode = charCode;
callbackData.x = x;
callbackData.y = y;
callbackData.scale = scale;
callbackData.rotation = rotation;
callbackData.data = glyph.data;
var output = displayCallback(callbackData);
x = output.x;
y = output.y;
scale = output.scale;
rotation = output.rotation;
if (output.color) {
tintTL = output.color;
tintTR = output.color;
tintBL = output.color;
tintBR = output.color;
} else {
tintTL = output.tint.topLeft;
tintTR = output.tint.topRight;
tintBL = output.tint.bottomLeft;
tintBR = output.tint.bottomRight;
}
tintTL = Utils.getTintAppendFloatAlpha(tintTL, camera.alpha * src._alphaTL);
tintTR = Utils.getTintAppendFloatAlpha(tintTR, camera.alpha * src._alphaTR);
tintBL = Utils.getTintAppendFloatAlpha(tintBL, camera.alpha * src._alphaBL);
tintBR = Utils.getTintAppendFloatAlpha(tintBR, camera.alpha * src._alphaBR);
}
x *= scale;
y *= scale;
x -= src.displayOriginX;
y -= src.displayOriginY;
x += lineOffsetX;
fontMatrix.applyITRS(x, y, rotation, scale, scale);
calcMatrix.multiply(fontMatrix, spriteMatrix);
var u0 = glyph.u0;
var v0 = glyph.v0;
var u1 = glyph.u1;
var v1 = glyph.v1;
var xw = glyphW;
var yh = glyphH;
var tx0 = spriteMatrix.e;
var ty0 = spriteMatrix.f;
var tx1 = yh * spriteMatrix.c + spriteMatrix.e;
var ty1 = yh * spriteMatrix.d + spriteMatrix.f;
var tx2 = xw * spriteMatrix.a + yh * spriteMatrix.c + spriteMatrix.e;
var ty2 = xw * spriteMatrix.b + yh * spriteMatrix.d + spriteMatrix.f;
var tx3 = xw * spriteMatrix.a + spriteMatrix.e;
var ty3 = xw * spriteMatrix.b + spriteMatrix.f;
if (roundPixels) {
tx0 = Math.round(tx0);
ty0 = Math.round(ty0);
tx1 = Math.round(tx1);
ty1 = Math.round(ty1);
tx2 = Math.round(tx2);
ty2 = Math.round(ty2);
tx3 = Math.round(tx3);
ty3 = Math.round(ty3);
}
if (pipeline.shouldFlush(6)) {
pipeline.flush();
textureUnit = pipeline.setGameObject(src);
}
pipeline.batchQuad(src, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, textureUnit);
}
if (crop) {
pipeline.flush();
renderer.popScissor();
}
renderer.pipelines.postBatch(src);
};
module2.exports = DynamicBitmapTextWebGLRenderer;
}
),
/***/
22186: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Clamp = __webpack_require__2(45319);
var Components = __webpack_require__2(31401);
var GameObject = __webpack_require__2(95643);
var GetBitmapTextSize = __webpack_require__2(53048);
var ParseFromAtlas = __webpack_require__2(61327);
var ParseXMLBitmapFont = __webpack_require__2(21859);
var Rectangle = __webpack_require__2(87841);
var Render = __webpack_require__2(18658);
var BitmapText = new Class({
Extends: GameObject,
Mixins: [
Components.Alpha,
Components.BlendMode,
Components.Depth,
Components.GetBounds,
Components.Mask,
Components.Origin,
Components.Pipeline,
Components.PostPipeline,
Components.ScrollFactor,
Components.Texture,
Components.Tint,
Components.Transform,
Components.Visible,
Render
],
initialize: function BitmapText2(scene, x, y, font, text, size, align) {
if (text === void 0) {
text = "";
}
if (align === void 0) {
align = 0;
}
GameObject.call(this, scene, "BitmapText");
this.font = font;
var entry = this.scene.sys.cache.bitmapFont.get(font);
if (!entry) {
throw new Error("Invalid BitmapText key: " + font);
}
this.fontData = entry.data;
this._text = "";
this._fontSize = size || this.fontData.size;
this._letterSpacing = 0;
this._lineSpacing = 0;
this._align = align;
this._bounds = GetBitmapTextSize();
this._dirty = true;
this._maxWidth = 0;
this.wordWrapCharCode = 32;
this.charColors = [];
this.dropShadowX = 0;
this.dropShadowY = 0;
this.dropShadowColor = 0;
this.dropShadowAlpha = 0.5;
this.fromAtlas = entry.fromAtlas;
this.setTexture(entry.texture, entry.frame);
this.setPosition(x, y);
this.setOrigin(0, 0);
this.initPipeline();
this.initPostPipeline();
this.setText(text);
},
/**
* Set the lines of text in this BitmapText to be left-aligned.
* This only has any effect if this BitmapText contains more than one line of text.
*
* @method Phaser.GameObjects.BitmapText#setLeftAlign
* @since 3.11.0
*
* @return {this} This BitmapText Object.
*/
setLeftAlign: function() {
this._align = BitmapText.ALIGN_LEFT;
this._dirty = true;
return this;
},
/**
* Set the lines of text in this BitmapText to be center-aligned.
* This only has any effect if this BitmapText contains more than one line of text.
*
* @method Phaser.GameObjects.BitmapText#setCenterAlign
* @since 3.11.0
*
* @return {this} This BitmapText Object.
*/
setCenterAlign: function() {
this._align = BitmapText.ALIGN_CENTER;
this._dirty = true;
return this;
},
/**
* Set the lines of text in this BitmapText to be right-aligned.
* This only has any effect if this BitmapText contains more than one line of text.
*
* @method Phaser.GameObjects.BitmapText#setRightAlign
* @since 3.11.0
*
* @return {this} This BitmapText Object.
*/
setRightAlign: function() {
this._align = BitmapText.ALIGN_RIGHT;
this._dirty = true;
return this;
},
/**
* Set the font size of this Bitmap Text.
*
* @method Phaser.GameObjects.BitmapText#setFontSize
* @since 3.0.0
*
* @param {number} size - The font size to set.
*
* @return {this} This BitmapText Object.
*/
setFontSize: function(size) {
this._fontSize = size;
this._dirty = true;
return this;
},
/**
* Sets the letter spacing between each character of this Bitmap Text.
* Can be a positive value to increase the space, or negative to reduce it.
* Spacing is applied after the kerning values have been set.
*
* @method Phaser.GameObjects.BitmapText#setLetterSpacing
* @since 3.4.0
*
* @param {number} [spacing=0] - The amount of horizontal space to add between each character.
*
* @return {this} This BitmapText Object.
*/
setLetterSpacing: function(spacing) {
if (spacing === void 0) {
spacing = 0;
}
this._letterSpacing = spacing;
this._dirty = true;
return this;
},
/**
* Sets the line spacing value. This value is added to the font height to
* calculate the overall line height.
*
* Spacing can be a negative or positive number.
*
* Only has an effect if this BitmapText object contains multiple lines of text.
*
* @method Phaser.GameObjects.BitmapText#setLineSpacing
* @since 3.60.0
*
* @param {number} [spacing=0] - The amount of space to add between each line in multi-line text.
*
* @return {this} This BitmapText Object.
*/
setLineSpacing: function(spacing) {
if (spacing === void 0) {
spacing = 0;
}
this.lineSpacing = spacing;
return this;
},
/**
* Set the textual content of this BitmapText.
*
* An array of strings will be converted into multi-line text. Use the align methods to change multi-line alignment.
*
* @method Phaser.GameObjects.BitmapText#setText
* @since 3.0.0
*
* @param {(string|string[])} value - The string, or array of strings, to be set as the content of this BitmapText.
*
* @return {this} This BitmapText Object.
*/
setText: function(value) {
if (!value && value !== 0) {
value = "";
}
if (Array.isArray(value)) {
value = value.join("\n");
}
if (value !== this.text) {
this._text = value.toString();
this._dirty = true;
this.updateDisplayOrigin();
}
return this;
},
/**
* Sets a drop shadow effect on this Bitmap Text.
*
* This is a WebGL only feature and only works with Static Bitmap Text, not Dynamic.
*
* You can set the vertical and horizontal offset of the shadow, as well as the color and alpha.
*
* Once a shadow has been enabled you can modify the `dropShadowX` and `dropShadowY` properties of this
* Bitmap Text directly to adjust the position of the shadow in real-time.
*
* If you wish to clear the shadow, call this method with no parameters specified.
*
* @method Phaser.GameObjects.BitmapText#setDropShadow
* @webglOnly
* @since 3.50.0
*
* @param {number} [x=0] - The horizontal offset of the drop shadow.
* @param {number} [y=0] - The vertical offset of the drop shadow.
* @param {number} [color=0x000000] - The color of the drop shadow, given as a hex value, i.e. `0x000000` for black.
* @param {number} [alpha=0.5] - The alpha of the drop shadow, given as a float between 0 and 1. This is combined with the Bitmap Text alpha as well.
*
* @return {this} This BitmapText Object.
*/
setDropShadow: function(x, y, color, alpha) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (color === void 0) {
color = 0;
}
if (alpha === void 0) {
alpha = 0.5;
}
this.dropShadowX = x;
this.dropShadowY = y;
this.dropShadowColor = color;
this.dropShadowAlpha = alpha;
return this;
},
/**
* Sets a tint on a range of characters in this Bitmap Text, starting from the `start` parameter index
* and running for `length` quantity of characters.
*
* The `start` parameter can be negative. In this case, it starts at the end of the text and counts
* backwards `start` places.
*
* You can also pass in -1 as the `length` and it will tint all characters from `start`
* up until the end of the string.
* Remember that spaces and punctuation count as characters.
*
* This is a WebGL only feature and only works with Static Bitmap Text, not Dynamic.
*
* The tint works by taking the pixel color values from the Bitmap Text texture, and then
* multiplying it by the color value of the tint. You can provide either one color value,
* in which case the whole character will be tinted in that color. Or you can provide a color
* per corner. The colors are blended together across the extent of the character range.
*
* To swap this from being an additive tint to a fill based tint, set the `tintFill` parameter to `true`.
*
* To modify the tint color once set, call this method again with new color values.
*
* Using `setWordTint` can override tints set by this function, and vice versa.
*
* To remove a tint call this method with just the `start`, and optionally, the `length` parameters defined.
*
* @method Phaser.GameObjects.BitmapText#setCharacterTint
* @webglOnly
* @since 3.50.0
*
* @param {number} [start=0] - The starting character to begin the tint at. If negative, it counts back from the end of the text.
* @param {number} [length=1] - The number of characters to tint. Remember that spaces count as a character too. Pass -1 to tint all characters from `start` onwards.
* @param {boolean} [tintFill=false] - Use a fill-based tint (true), or an additive tint (false)
* @param {number} [topLeft=0xffffff] - The tint being applied to the top-left of the character. If not other values are given this value is applied evenly, tinting the whole character.
* @param {number} [topRight] - The tint being applied to the top-right of the character.
* @param {number} [bottomLeft] - The tint being applied to the bottom-left of the character.
* @param {number} [bottomRight] - The tint being applied to the bottom-right of the character.
*
* @return {this} This BitmapText Object.
*/
setCharacterTint: function(start, length, tintFill, topLeft, topRight, bottomLeft, bottomRight) {
if (start === void 0) {
start = 0;
}
if (length === void 0) {
length = 1;
}
if (tintFill === void 0) {
tintFill = false;
}
if (topLeft === void 0) {
topLeft = -1;
}
if (topRight === void 0) {
topRight = topLeft;
bottomLeft = topLeft;
bottomRight = topLeft;
}
var len = this.text.length;
if (length === -1) {
length = len;
}
if (start < 0) {
start = len + start;
}
start = Clamp(start, 0, len - 1);
var end = Clamp(start + length, start, len);
var charColors = this.charColors;
for (var i = start; i < end; i++) {
var color = charColors[i];
if (topLeft === -1) {
charColors[i] = null;
} else {
var tintEffect = tintFill ? 1 : 0;
if (color) {
color.tintEffect = tintEffect;
color.tintTL = topLeft;
color.tintTR = topRight;
color.tintBL = bottomLeft;
color.tintBR = bottomRight;
} else {
charColors[i] = {
tintEffect,
tintTL: topLeft,
tintTR: topRight,
tintBL: bottomLeft,
tintBR: bottomRight
};
}
}
}
return this;
},
/**
* Sets a tint on a matching word within this Bitmap Text.
*
* The `word` parameter can be either a string or a number.
*
* If a string, it will run a string comparison against the text contents, and if matching,
* it will tint the whole word.
*
* If a number, if till that word, based on its offset within the text contents.
*
* The `count` parameter controls how many words are replaced. Pass in -1 to replace them all.
*
* This parameter is ignored if you pass a number as the `word` to be searched for.
*
* This is a WebGL only feature and only works with Static Bitmap Text, not Dynamic.
*
* The tint works by taking the pixel color values from the Bitmap Text texture, and then
* multiplying it by the color value of the tint. You can provide either one color value,
* in which case the whole character will be tinted in that color. Or you can provide a color
* per corner. The colors are blended together across the extent of the character range.
*
* To swap this from being an additive tint to a fill based tint, set the `tintFill` parameter to `true`.
*
* To modify the tint color once set, call this method again with new color values.
*
* Using `setCharacterTint` can override tints set by this function, and vice versa.
*
* @method Phaser.GameObjects.BitmapText#setWordTint
* @webglOnly
* @since 3.50.0
*
* @param {(string|number)} word - The word to search for. Either a string, or an index of the word in the words array.
* @param {number} [count=1] - The number of matching words to tint. Pass -1 to tint all matching words.
* @param {boolean} [tintFill=false] - Use a fill-based tint (true), or an additive tint (false)
* @param {number} [topLeft=0xffffff] - The tint being applied to the top-left of the word. If not other values are given this value is applied evenly, tinting the whole word.
* @param {number} [topRight] - The tint being applied to the top-right of the word.
* @param {number} [bottomLeft] - The tint being applied to the bottom-left of the word.
* @param {number} [bottomRight] - The tint being applied to the bottom-right of the word.
*
* @return {this} This BitmapText Object.
*/
setWordTint: function(word, count, tintFill, topLeft, topRight, bottomLeft, bottomRight) {
if (count === void 0) {
count = 1;
}
var bounds = this.getTextBounds();
var words = bounds.words;
var wordIsNumber = typeof word === "number";
var total = 0;
for (var i = 0; i < words.length; i++) {
var lineword = words[i];
if (wordIsNumber && i === word || !wordIsNumber && lineword.word === word) {
this.setCharacterTint(lineword.i, lineword.word.length, tintFill, topLeft, topRight, bottomLeft, bottomRight);
total++;
if (total === count) {
return this;
}
}
}
return this;
},
/**
* Calculate the bounds of this Bitmap Text.
*
* An object is returned that contains the position, width and height of the Bitmap Text in local and global
* contexts.
*
* Local size is based on just the font size and a [0, 0] position.
*
* Global size takes into account the Game Object's scale, world position and display origin.
*
* Also in the object is data regarding the length of each line, should this be a multi-line BitmapText.
*
* @method Phaser.GameObjects.BitmapText#getTextBounds
* @since 3.0.0
*
* @param {boolean} [round=false] - Whether to round the results up to the nearest integer.
*
* @return {Phaser.Types.GameObjects.BitmapText.BitmapTextSize} An object that describes the size of this Bitmap Text.
*/
getTextBounds: function(round) {
var bounds = this._bounds;
if (this._dirty || round || this.scaleX !== bounds.scaleX || this.scaleY !== bounds.scaleY) {
GetBitmapTextSize(this, round, true, bounds);
this._dirty = false;
}
return bounds;
},
/**
* Gets the character located at the given x/y coordinate within this Bitmap Text.
*
* The coordinates you pass in are translated into the local space of the
* Bitmap Text, however, it is up to you to first translate the input coordinates to world space.
*
* If you wish to use this in combination with an input event, be sure
* to pass in `Pointer.worldX` and `worldY` so they are in world space.
*
* In some cases, based on kerning, characters can overlap. When this happens,
* the first character in the word is returned.
*
* Note that this does not work for DynamicBitmapText if you have changed the
* character positions during render. It will only scan characters in their un-translated state.
*
* @method Phaser.GameObjects.BitmapText#getCharacterAt
* @since 3.50.0
*
* @param {number} x - The x position to check.
* @param {number} y - The y position to check.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera which is being tested against. If not given will use the Scene default camera.
*
* @return {Phaser.Types.GameObjects.BitmapText.BitmapTextCharacter} The character object at the given position, or `null`.
*/
getCharacterAt: function(x, y, camera) {
var point = this.getLocalPoint(x, y, null, camera);
var bounds = this.getTextBounds();
var chars = bounds.characters;
var tempRect = new Rectangle();
for (var i = 0; i < chars.length; i++) {
var char = chars[i];
tempRect.setTo(char.x, char.t, char.r - char.x, char.b);
if (tempRect.contains(point.x, point.y)) {
return char;
}
}
return null;
},
/**
* Updates the Display Origin cached values internally stored on this Game Object.
* You don't usually call this directly, but it is exposed for edge-cases where you may.
*
* @method Phaser.GameObjects.BitmapText#updateDisplayOrigin
* @since 3.0.0
*
* @return {this} This Game Object instance.
*/
updateDisplayOrigin: function() {
this._dirty = true;
this.getTextBounds(false);
return this;
},
/**
* Changes the font this BitmapText is using to render.
*
* The new texture is loaded and applied to the BitmapText. The existing text, size and alignment are preserved,
* unless overridden via the arguments.
*
* @method Phaser.GameObjects.BitmapText#setFont
* @since 3.11.0
*
* @param {string} font - The key of the font to use from the Bitmap Font cache.
* @param {number} [size] - The font size of this Bitmap Text. If not specified the current size will be used.
* @param {number} [align=0] - The alignment of the text in a multi-line BitmapText object. If not specified the current alignment will be used.
*
* @return {this} This BitmapText Object.
*/
setFont: function(key, size, align) {
if (size === void 0) {
size = this._fontSize;
}
if (align === void 0) {
align = this._align;
}
var entry = this.scene.sys.cache.bitmapFont.get(key);
if (entry) {
this.font = key;
this.fontData = entry.data;
this._fontSize = size;
this._align = align;
this.fromAtlas = entry.fromAtlas === true;
this.setTexture(entry.texture, entry.frame);
GetBitmapTextSize(this, false, true, this._bounds);
}
return this;
},
/**
* Sets the maximum display width of this BitmapText in pixels.
*
* If `BitmapText.text` is longer than `maxWidth` then the lines will be automatically wrapped
* based on the previous whitespace character found in the line.
*
* If no whitespace was found then no wrapping will take place and consequently the `maxWidth` value will not be honored.
*
* Disable maxWidth by setting the value to 0.
*
* You can set the whitespace character to be searched for by setting the `wordWrapCharCode` parameter or property.
*
* @method Phaser.GameObjects.BitmapText#setMaxWidth
* @since 3.21.0
*
* @param {number} value - The maximum display width of this BitmapText in pixels. Set to zero to disable.
* @param {number} [wordWrapCharCode] - The character code to check for when word wrapping. Defaults to 32 (the space character).
*
* @return {this} This BitmapText Object.
*/
setMaxWidth: function(value, wordWrapCharCode) {
this._maxWidth = value;
this._dirty = true;
if (wordWrapCharCode !== void 0) {
this.wordWrapCharCode = wordWrapCharCode;
}
return this;
},
/**
* Controls the alignment of each line of text in this BitmapText object.
*
* Only has any effect when this BitmapText contains multiple lines of text, split with carriage-returns.
* Has no effect with single-lines of text.
*
* See the methods `setLeftAlign`, `setCenterAlign` and `setRightAlign`.
*
* 0 = Left aligned (default)
* 1 = Middle aligned
* 2 = Right aligned
*
* The alignment position is based on the longest line of text.
*
* @name Phaser.GameObjects.BitmapText#align
* @type {number}
* @since 3.11.0
*/
align: {
set: function(value) {
this._align = value;
this._dirty = true;
},
get: function() {
return this._align;
}
},
/**
* The text that this Bitmap Text object displays.
*
* You can also use the method `setText` if you want a chainable way to change the text content.
*
* @name Phaser.GameObjects.BitmapText#text
* @type {string}
* @since 3.0.0
*/
text: {
set: function(value) {
this.setText(value);
},
get: function() {
return this._text;
}
},
/**
* The font size of this Bitmap Text.
*
* You can also use the method `setFontSize` if you want a chainable way to change the font size.
*
* @name Phaser.GameObjects.BitmapText#fontSize
* @type {number}
* @since 3.0.0
*/
fontSize: {
set: function(value) {
this._fontSize = value;
this._dirty = true;
},
get: function() {
return this._fontSize;
}
},
/**
* Adds / Removes spacing between characters.
*
* Can be a negative or positive number.
*
* You can also use the method `setLetterSpacing` if you want a chainable way to change the letter spacing.
*
* @name Phaser.GameObjects.BitmapText#letterSpacing
* @type {number}
* @since 3.0.0
*/
letterSpacing: {
set: function(value) {
this._letterSpacing = value;
this._dirty = true;
},
get: function() {
return this._letterSpacing;
}
},
/**
* Adds / Removes spacing between lines.
*
* Can be a negative or positive number.
*
* You can also use the method `setLineSpacing` if you want a chainable way to change the line spacing.
*
* @name Phaser.GameObjects.BitmapText#lineSpacing
* @type {number}
* @since 3.60.0
*/
lineSpacing: {
set: function(value) {
this._lineSpacing = value;
this._dirty = true;
},
get: function() {
return this._lineSpacing;
}
},
/**
* The maximum display width of this BitmapText in pixels.
*
* If BitmapText.text is longer than maxWidth then the lines will be automatically wrapped
* based on the last whitespace character found in the line.
*
* If no whitespace was found then no wrapping will take place and consequently the maxWidth value will not be honored.
*
* Disable maxWidth by setting the value to 0.
*
* @name Phaser.GameObjects.BitmapText#maxWidth
* @type {number}
* @since 3.21.0
*/
maxWidth: {
set: function(value) {
this._maxWidth = value;
this._dirty = true;
},
get: function() {
return this._maxWidth;
}
},
/**
* The width of this Bitmap Text.
*
* This property is read-only.
*
* @name Phaser.GameObjects.BitmapText#width
* @type {number}
* @readonly
* @since 3.0.0
*/
width: {
get: function() {
this.getTextBounds(false);
return this._bounds.global.width;
}
},
/**
* The height of this Bitmap text.
*
* This property is read-only.
*
* @name Phaser.GameObjects.BitmapText#height
* @type {number}
* @readonly
* @since 3.0.0
*/
height: {
get: function() {
this.getTextBounds(false);
return this._bounds.global.height;
}
},
/**
* The displayed width of this Bitmap Text.
*
* This value takes into account the scale factor.
*
* This property is read-only.
*
* @name Phaser.GameObjects.BitmapText#displayWidth
* @type {number}
* @readonly
* @since 3.60.0
*/
displayWidth: {
get: function() {
return this.width;
}
},
/**
* The displayed height of this Bitmap Text.
*
* This value takes into account the scale factor.
*
* This property is read-only.
*
* @name Phaser.GameObjects.BitmapText#displayHeight
* @type {number}
* @readonly
* @since 3.60.0
*/
displayHeight: {
get: function() {
return this.height;
}
},
/**
* Build a JSON representation of this Bitmap Text.
*
* @method Phaser.GameObjects.BitmapText#toJSON
* @since 3.0.0
*
* @return {Phaser.Types.GameObjects.BitmapText.JSONBitmapText} A JSON representation of this Bitmap Text.
*/
toJSON: function() {
var out = Components.ToJSON(this);
var data = {
font: this.font,
text: this.text,
fontSize: this.fontSize,
letterSpacing: this.letterSpacing,
lineSpacing: this.lineSpacing,
align: this.align
};
out.data = data;
return out;
},
/**
* Internal destroy handler, called as part of the destroy process.
*
* @method Phaser.GameObjects.BitmapText#preDestroy
* @protected
* @since 3.50.0
*/
preDestroy: function() {
this.charColors.length = 0;
this._bounds = null;
this.fontData = null;
}
});
BitmapText.ALIGN_LEFT = 0;
BitmapText.ALIGN_CENTER = 1;
BitmapText.ALIGN_RIGHT = 2;
BitmapText.ParseFromAtlas = ParseFromAtlas;
BitmapText.ParseXMLBitmapFont = ParseXMLBitmapFont;
module2.exports = BitmapText;
}
),
/***/
37289: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var SetTransform = __webpack_require__2(20926);
var BitmapTextCanvasRenderer = function(renderer, src, camera, parentMatrix) {
var text = src._text;
var textLength = text.length;
var ctx = renderer.currentContext;
if (textLength === 0 || !SetTransform(renderer, ctx, src, camera, parentMatrix)) {
return;
}
camera.addToRenderList(src);
var textureFrame = src.fromAtlas ? src.frame : src.texture.frames["__BASE"];
var chars = src.fontData.chars;
var lineHeight = src.fontData.lineHeight;
var letterSpacing = src._letterSpacing;
var lineSpacing = src._lineSpacing;
var xAdvance = 0;
var yAdvance = 0;
var charCode = 0;
var glyph = null;
var glyphX = 0;
var glyphY = 0;
var glyphW = 0;
var glyphH = 0;
var x = 0;
var y = 0;
var lastGlyph = null;
var lastCharCode = 0;
var image = textureFrame.source.image;
var textureX = textureFrame.cutX;
var textureY = textureFrame.cutY;
var scale = src._fontSize / src.fontData.size;
var align = src._align;
var currentLine = 0;
var lineOffsetX = 0;
var bounds = src.getTextBounds(false);
if (src.maxWidth > 0) {
text = bounds.wrappedText;
textLength = text.length;
}
var lineData = src._bounds.lines;
if (align === 1) {
lineOffsetX = (lineData.longest - lineData.lengths[0]) / 2;
} else if (align === 2) {
lineOffsetX = lineData.longest - lineData.lengths[0];
}
ctx.translate(-src.displayOriginX, -src.displayOriginY);
var roundPixels = camera.roundPixels;
for (var i = 0; i < textLength; i++) {
charCode = text.charCodeAt(i);
if (charCode === 10) {
currentLine++;
if (align === 1) {
lineOffsetX = (lineData.longest - lineData.lengths[currentLine]) / 2;
} else if (align === 2) {
lineOffsetX = lineData.longest - lineData.lengths[currentLine];
}
xAdvance = 0;
yAdvance += lineHeight + lineSpacing;
lastGlyph = null;
continue;
}
glyph = chars[charCode];
if (!glyph) {
continue;
}
glyphX = textureX + glyph.x;
glyphY = textureY + glyph.y;
glyphW = glyph.width;
glyphH = glyph.height;
x = glyph.xOffset + xAdvance;
y = glyph.yOffset + yAdvance;
if (lastGlyph !== null) {
var kerningOffset = glyph.kerning[lastCharCode];
x += kerningOffset !== void 0 ? kerningOffset : 0;
}
x *= scale;
y *= scale;
x += lineOffsetX;
xAdvance += glyph.xAdvance + letterSpacing + (kerningOffset !== void 0 ? kerningOffset : 0);
lastGlyph = glyph;
lastCharCode = charCode;
if (glyphW === 0 || glyphH === 0 || charCode === 32) {
continue;
}
if (roundPixels) {
x = Math.round(x);
y = Math.round(y);
}
ctx.save();
ctx.translate(x, y);
ctx.scale(scale, scale);
ctx.drawImage(image, glyphX, glyphY, glyphW, glyphH, 0, 0, glyphW, glyphH);
ctx.restore();
}
ctx.restore();
};
module2.exports = BitmapTextCanvasRenderer;
}
),
/***/
57336: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var BitmapText = __webpack_require__2(22186);
var BuildGameObject = __webpack_require__2(25305);
var GameObjectCreator = __webpack_require__2(44603);
var GetAdvancedValue = __webpack_require__2(23568);
var GetValue = __webpack_require__2(35154);
GameObjectCreator.register("bitmapText", function(config, addToScene) {
if (config === void 0) {
config = {};
}
var font = GetValue(config, "font", "");
var text = GetAdvancedValue(config, "text", "");
var size = GetAdvancedValue(config, "size", false);
var align = GetValue(config, "align", 0);
var bitmapText = new BitmapText(this.scene, 0, 0, font, text, size, align);
if (addToScene !== void 0) {
config.add = addToScene;
}
BuildGameObject(this.scene, bitmapText, config);
return bitmapText;
});
}
),
/***/
34914: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var BitmapText = __webpack_require__2(22186);
var GameObjectFactory = __webpack_require__2(39429);
GameObjectFactory.register("bitmapText", function(x, y, font, text, size, align) {
return this.displayList.add(new BitmapText(this.scene, x, y, font, text, size, align));
});
}
),
/***/
18658: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(33590);
}
if (true) {
renderCanvas = __webpack_require__2(37289);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
33590: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BatchChar = __webpack_require__2(3217);
var GetCalcMatrix = __webpack_require__2(91296);
var Utils = __webpack_require__2(70554);
var BitmapTextWebGLRenderer = function(renderer, src, camera, parentMatrix) {
var text = src._text;
var textLength = text.length;
if (textLength === 0) {
return;
}
camera.addToRenderList(src);
var pipeline = renderer.pipelines.set(src.pipeline, src);
var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc;
renderer.pipelines.preBatch(src);
var roundPixels = camera.roundPixels;
var cameraAlpha = camera.alpha;
var charColors = src.charColors;
var tintEffect = src.tintFill;
var getTint = Utils.getTintAppendFloatAlpha;
var tintTL = getTint(src.tintTopLeft, cameraAlpha * src._alphaTL);
var tintTR = getTint(src.tintTopRight, cameraAlpha * src._alphaTR);
var tintBL = getTint(src.tintBottomLeft, cameraAlpha * src._alphaBL);
var tintBR = getTint(src.tintBottomRight, cameraAlpha * src._alphaBR);
var texture = src.frame.glTexture;
var textureUnit = pipeline.setGameObject(src);
var bounds = src.getTextBounds(false);
var i;
var char;
var glyph;
var characters = bounds.characters;
var dropShadowX = src.dropShadowX;
var dropShadowY = src.dropShadowY;
var dropShadow = dropShadowX !== 0 || dropShadowY !== 0;
if (dropShadow) {
var srcShadowColor = src.dropShadowColor;
var srcShadowAlpha = src.dropShadowAlpha;
var shadowTL = getTint(srcShadowColor, cameraAlpha * srcShadowAlpha * src._alphaTL);
var shadowTR = getTint(srcShadowColor, cameraAlpha * srcShadowAlpha * src._alphaTR);
var shadowBL = getTint(srcShadowColor, cameraAlpha * srcShadowAlpha * src._alphaBL);
var shadowBR = getTint(srcShadowColor, cameraAlpha * srcShadowAlpha * src._alphaBR);
for (i = 0; i < characters.length; i++) {
char = characters[i];
glyph = char.glyph;
if (char.code === 32 || glyph.width === 0 || glyph.height === 0) {
continue;
}
BatchChar(pipeline, src, char, glyph, dropShadowX, dropShadowY, calcMatrix, roundPixels, shadowTL, shadowTR, shadowBL, shadowBR, 1, texture, textureUnit);
}
}
for (i = 0; i < characters.length; i++) {
char = characters[i];
glyph = char.glyph;
if (char.code === 32 || glyph.width === 0 || glyph.height === 0) {
continue;
}
if (pipeline.shouldFlush(6)) {
pipeline.flush();
textureUnit = pipeline.setGameObject(src);
}
if (charColors[char.i]) {
var color = charColors[char.i];
var charTintEffect = color.tintEffect;
var charTintTL = getTint(color.tintTL, cameraAlpha * src._alphaTL);
var charTintTR = getTint(color.tintTR, cameraAlpha * src._alphaTR);
var charTintBL = getTint(color.tintBL, cameraAlpha * src._alphaBL);
var charTintBR = getTint(color.tintBR, cameraAlpha * src._alphaBR);
BatchChar(pipeline, src, char, glyph, 0, 0, calcMatrix, roundPixels, charTintTL, charTintTR, charTintBL, charTintBR, charTintEffect, texture, textureUnit);
} else {
BatchChar(pipeline, src, char, glyph, 0, 0, calcMatrix, roundPixels, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, textureUnit);
}
}
renderer.pipelines.postBatch(src);
};
module2.exports = BitmapTextWebGLRenderer;
}
),
/***/
6107: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BlitterRender = __webpack_require__2(48011);
var Bob = __webpack_require__2(46590);
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31401);
var Frame = __webpack_require__2(4327);
var GameObject = __webpack_require__2(95643);
var List = __webpack_require__2(73162);
var Blitter = new Class({
Extends: GameObject,
Mixins: [
Components.Alpha,
Components.BlendMode,
Components.Depth,
Components.Mask,
Components.Pipeline,
Components.PostPipeline,
Components.ScrollFactor,
Components.Size,
Components.Texture,
Components.Transform,
Components.Visible,
BlitterRender
],
initialize: function Blitter2(scene, x, y, texture, frame) {
GameObject.call(this, scene, "Blitter");
this.setTexture(texture, frame);
this.setPosition(x, y);
this.initPipeline();
this.initPostPipeline();
this.children = new List();
this.renderList = [];
this.dirty = false;
},
/**
* Creates a new Bob in this Blitter.
*
* The Bob is created at the given coordinates, relative to the Blitter and uses the given frame.
* A Bob can use any frame belonging to the texture bound to the Blitter.
*
* @method Phaser.GameObjects.Blitter#create
* @since 3.0.0
*
* @param {number} x - The x position of the Bob. Bob coordinate are relative to the position of the Blitter object.
* @param {number} y - The y position of the Bob. Bob coordinate are relative to the position of the Blitter object.
* @param {(string|number|Phaser.Textures.Frame)} [frame] - The Frame the Bob will use. It _must_ be part of the Texture the parent Blitter object is using.
* @param {boolean} [visible=true] - Should the created Bob render or not?
* @param {number} [index] - The position in the Blitters Display List to add the new Bob at. Defaults to the top of the list.
*
* @return {Phaser.GameObjects.Bob} The newly created Bob object.
*/
create: function(x, y, frame, visible, index) {
if (visible === void 0) {
visible = true;
}
if (index === void 0) {
index = this.children.length;
}
if (frame === void 0) {
frame = this.frame;
} else if (!(frame instanceof Frame)) {
frame = this.texture.get(frame);
}
var bob = new Bob(this, x, y, frame, visible);
this.children.addAt(bob, index, false);
this.dirty = true;
return bob;
},
/**
* Creates multiple Bob objects within this Blitter and then passes each of them to the specified callback.
*
* @method Phaser.GameObjects.Blitter#createFromCallback
* @since 3.0.0
*
* @param {CreateCallback} callback - The callback to invoke after creating a bob. It will be sent two arguments: The Bob and the index of the Bob.
* @param {number} quantity - The quantity of Bob objects to create.
* @param {(string|number|Phaser.Textures.Frame|string[]|number[]|Phaser.Textures.Frame[])} [frame] - The Frame the Bobs will use. It must be part of the Blitter Texture.
* @param {boolean} [visible=true] - Should the created Bob render or not?
*
* @return {Phaser.GameObjects.Bob[]} An array of Bob objects that were created.
*/
createFromCallback: function(callback, quantity, frame, visible) {
var bobs = this.createMultiple(quantity, frame, visible);
for (var i = 0; i < bobs.length; i++) {
var bob = bobs[i];
callback.call(this, bob, i);
}
return bobs;
},
/**
* Creates multiple Bobs in one call.
*
* The amount created is controlled by a combination of the `quantity` argument and the number of frames provided.
*
* If the quantity is set to 10 and you provide 2 frames, then 20 Bobs will be created. 10 with the first
* frame and 10 with the second.
*
* @method Phaser.GameObjects.Blitter#createMultiple
* @since 3.0.0
*
* @param {number} quantity - The quantity of Bob objects to create.
* @param {(string|number|Phaser.Textures.Frame|string[]|number[]|Phaser.Textures.Frame[])} [frame] - The Frame the Bobs will use. It must be part of the Blitter Texture.
* @param {boolean} [visible=true] - Should the created Bob render or not?
*
* @return {Phaser.GameObjects.Bob[]} An array of Bob objects that were created.
*/
createMultiple: function(quantity, frame, visible) {
if (frame === void 0) {
frame = this.frame.name;
}
if (visible === void 0) {
visible = true;
}
if (!Array.isArray(frame)) {
frame = [frame];
}
var bobs = [];
var _this = this;
frame.forEach(function(singleFrame) {
for (var i = 0; i < quantity; i++) {
bobs.push(_this.create(0, 0, singleFrame, visible));
}
});
return bobs;
},
/**
* Checks if the given child can render or not, by checking its `visible` and `alpha` values.
*
* @method Phaser.GameObjects.Blitter#childCanRender
* @since 3.0.0
*
* @param {Phaser.GameObjects.Bob} child - The Bob to check for rendering.
*
* @return {boolean} Returns `true` if the given child can render, otherwise `false`.
*/
childCanRender: function(child) {
return child.visible && child.alpha > 0;
},
/**
* Returns an array of Bobs to be rendered.
* If the Blitter is dirty then a new list is generated and stored in `renderList`.
*
* @method Phaser.GameObjects.Blitter#getRenderList
* @since 3.0.0
*
* @return {Phaser.GameObjects.Bob[]} An array of Bob objects that will be rendered this frame.
*/
getRenderList: function() {
if (this.dirty) {
this.renderList = this.children.list.filter(this.childCanRender, this);
this.dirty = false;
}
return this.renderList;
},
/**
* Removes all Bobs from the children List and clears the dirty flag.
*
* @method Phaser.GameObjects.Blitter#clear
* @since 3.0.0
*/
clear: function() {
this.children.removeAll();
this.dirty = true;
},
/**
* Internal destroy handler, called as part of the destroy process.
*
* @method Phaser.GameObjects.Blitter#preDestroy
* @protected
* @since 3.9.0
*/
preDestroy: function() {
this.children.destroy();
this.renderList = [];
}
});
module2.exports = Blitter;
}
),
/***/
72396: (
/***/
(module2) => {
var BlitterCanvasRenderer = function(renderer, src, camera, parentMatrix) {
var list = src.getRenderList();
if (list.length === 0) {
return;
}
var ctx = renderer.currentContext;
var alpha = camera.alpha * src.alpha;
if (alpha === 0) {
return;
}
camera.addToRenderList(src);
ctx.globalCompositeOperation = renderer.blendModes[src.blendMode];
ctx.imageSmoothingEnabled = !src.frame.source.scaleMode;
var cameraScrollX = src.x - camera.scrollX * src.scrollFactorX;
var cameraScrollY = src.y - camera.scrollY * src.scrollFactorY;
ctx.save();
if (parentMatrix) {
parentMatrix.copyToContext(ctx);
}
var roundPixels = camera.roundPixels;
for (var i = 0; i < list.length; i++) {
var bob = list[i];
var flip = bob.flipX || bob.flipY;
var frame = bob.frame;
var cd = frame.canvasData;
var dx = frame.x;
var dy = frame.y;
var fx = 1;
var fy = 1;
var bobAlpha = bob.alpha * alpha;
if (bobAlpha === 0) {
continue;
}
ctx.globalAlpha = bobAlpha;
if (!flip) {
if (roundPixels) {
dx = Math.round(dx);
dy = Math.round(dy);
}
if (cd.width > 0 && cd.height > 0) {
ctx.drawImage(
frame.source.image,
cd.x,
cd.y,
cd.width,
cd.height,
dx + bob.x + cameraScrollX,
dy + bob.y + cameraScrollY,
cd.width,
cd.height
);
}
} else {
if (bob.flipX) {
fx = -1;
dx -= cd.width;
}
if (bob.flipY) {
fy = -1;
dy -= cd.height;
}
if (cd.width > 0 && cd.height > 0) {
ctx.save();
ctx.translate(bob.x + cameraScrollX, bob.y + cameraScrollY);
ctx.scale(fx, fy);
ctx.drawImage(frame.source.image, cd.x, cd.y, cd.width, cd.height, dx, dy, cd.width, cd.height);
ctx.restore();
}
}
}
ctx.restore();
};
module2.exports = BlitterCanvasRenderer;
}
),
/***/
9403: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var Blitter = __webpack_require__2(6107);
var BuildGameObject = __webpack_require__2(25305);
var GameObjectCreator = __webpack_require__2(44603);
var GetAdvancedValue = __webpack_require__2(23568);
GameObjectCreator.register("blitter", function(config, addToScene) {
if (config === void 0) {
config = {};
}
var key = GetAdvancedValue(config, "key", null);
var frame = GetAdvancedValue(config, "frame", null);
var blitter = new Blitter(this.scene, 0, 0, key, frame);
if (addToScene !== void 0) {
config.add = addToScene;
}
BuildGameObject(this.scene, blitter, config);
return blitter;
});
}
),
/***/
12709: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var Blitter = __webpack_require__2(6107);
var GameObjectFactory = __webpack_require__2(39429);
GameObjectFactory.register("blitter", function(x, y, texture, frame) {
return this.displayList.add(new Blitter(this.scene, x, y, texture, frame));
});
}
),
/***/
48011: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(99485);
}
if (true) {
renderCanvas = __webpack_require__2(72396);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
99485: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var TransformMatrix = __webpack_require__2(61340);
var Utils = __webpack_require__2(70554);
var tempMatrix = new TransformMatrix();
var BlitterWebGLRenderer = function(renderer, src, camera, parentMatrix) {
var list = src.getRenderList();
var alpha = camera.alpha * src.alpha;
if (list.length === 0 || alpha === 0) {
return;
}
camera.addToRenderList(src);
var pipeline = renderer.pipelines.set(this.pipeline, src);
var cameraScrollX = camera.scrollX * src.scrollFactorX;
var cameraScrollY = camera.scrollY * src.scrollFactorY;
var calcMatrix = tempMatrix.copyFrom(camera.matrix);
if (parentMatrix) {
calcMatrix.multiplyWithOffset(parentMatrix, -cameraScrollX, -cameraScrollY);
cameraScrollX = 0;
cameraScrollY = 0;
}
var blitterX = src.x - cameraScrollX;
var blitterY = src.y - cameraScrollY;
var prevTextureSourceIndex = -1;
var tintEffect = false;
var roundPixels = camera.roundPixels;
renderer.pipelines.preBatch(src);
for (var i = 0; i < list.length; i++) {
var bob = list[i];
var frame = bob.frame;
var bobAlpha = bob.alpha * alpha;
if (bobAlpha === 0) {
continue;
}
var width = frame.width;
var height = frame.height;
var x = blitterX + bob.x + frame.x;
var y = blitterY + bob.y + frame.y;
if (bob.flipX) {
width *= -1;
x += frame.width;
}
if (bob.flipY) {
height *= -1;
y += frame.height;
}
var quad = calcMatrix.setQuad(x, y, x + width, y + height, roundPixels);
var tint = Utils.getTintAppendFloatAlpha(bob.tint, bobAlpha);
if (frame.sourceIndex !== prevTextureSourceIndex) {
var textureUnit = pipeline.setGameObject(src, frame);
prevTextureSourceIndex = frame.sourceIndex;
}
if (pipeline.batchQuad(src, quad[0], quad[1], quad[2], quad[3], quad[4], quad[5], quad[6], quad[7], frame.u0, frame.v0, frame.u1, frame.v1, tint, tint, tint, tint, tintEffect, frame.glTexture, textureUnit)) {
prevTextureSourceIndex = -1;
}
}
renderer.pipelines.postBatch(src);
};
module2.exports = BlitterWebGLRenderer;
}
),
/***/
46590: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Frame = __webpack_require__2(4327);
var Bob = new Class({
initialize: function Bob2(blitter, x, y, frame, visible) {
this.parent = blitter;
this.x = x;
this.y = y;
this.frame = frame;
this.data = {};
this.tint = 16777215;
this._visible = visible;
this._alpha = 1;
this.flipX = false;
this.flipY = false;
this.hasTransformComponent = true;
},
/**
* Changes the Texture Frame being used by this Bob.
* The frame must be part of the Texture the parent Blitter is using.
* If no value is given it will use the default frame of the Blitter parent.
*
* @method Phaser.GameObjects.Bob#setFrame
* @since 3.0.0
*
* @param {(string|number|Phaser.Textures.Frame)} [frame] - The frame to be used during rendering.
*
* @return {this} This Bob Game Object.
*/
setFrame: function(frame) {
if (frame === void 0) {
this.frame = this.parent.frame;
} else if (frame instanceof Frame && frame.texture === this.parent.texture) {
this.frame = frame;
} else {
this.frame = this.parent.texture.get(frame);
}
return this;
},
/**
* Resets the horizontal and vertical flipped state of this Bob back to their default un-flipped state.
*
* @method Phaser.GameObjects.Bob#resetFlip
* @since 3.0.0
*
* @return {this} This Bob Game Object.
*/
resetFlip: function() {
this.flipX = false;
this.flipY = false;
return this;
},
/**
* Resets this Bob.
*
* Changes the position to the values given, and optionally changes the frame.
*
* Also resets the flipX and flipY values, sets alpha back to 1 and visible to true.
*
* @method Phaser.GameObjects.Bob#reset
* @since 3.0.0
*
* @param {number} x - The x position of the Bob. Bob coordinate are relative to the position of the Blitter object.
* @param {number} y - The y position of the Bob. Bob coordinate are relative to the position of the Blitter object.
* @param {(string|number|Phaser.Textures.Frame)} [frame] - The Frame the Bob will use. It _must_ be part of the Texture the parent Blitter object is using.
*
* @return {this} This Bob Game Object.
*/
reset: function(x, y, frame) {
this.x = x;
this.y = y;
this.flipX = false;
this.flipY = false;
this._alpha = 1;
this._visible = true;
this.parent.dirty = true;
if (frame) {
this.setFrame(frame);
}
return this;
},
/**
* Changes the position of this Bob to the values given.
*
* @method Phaser.GameObjects.Bob#setPosition
* @since 3.20.0
*
* @param {number} x - The x position of the Bob. Bob coordinate are relative to the position of the Blitter object.
* @param {number} y - The y position of the Bob. Bob coordinate are relative to the position of the Blitter object.
*
* @return {this} This Bob Game Object.
*/
setPosition: function(x, y) {
this.x = x;
this.y = y;
return this;
},
/**
* Sets the horizontal flipped state of this Bob.
*
* @method Phaser.GameObjects.Bob#setFlipX
* @since 3.0.0
*
* @param {boolean} value - The flipped state. `false` for no flip, or `true` to be flipped.
*
* @return {this} This Bob Game Object.
*/
setFlipX: function(value) {
this.flipX = value;
return this;
},
/**
* Sets the vertical flipped state of this Bob.
*
* @method Phaser.GameObjects.Bob#setFlipY
* @since 3.0.0
*
* @param {boolean} value - The flipped state. `false` for no flip, or `true` to be flipped.
*
* @return {this} This Bob Game Object.
*/
setFlipY: function(value) {
this.flipY = value;
return this;
},
/**
* Sets the horizontal and vertical flipped state of this Bob.
*
* @method Phaser.GameObjects.Bob#setFlip
* @since 3.0.0
*
* @param {boolean} x - The horizontal flipped state. `false` for no flip, or `true` to be flipped.
* @param {boolean} y - The horizontal flipped state. `false` for no flip, or `true` to be flipped.
*
* @return {this} This Bob Game Object.
*/
setFlip: function(x, y) {
this.flipX = x;
this.flipY = y;
return this;
},
/**
* Sets the visibility of this Bob.
*
* An invisible Bob will skip rendering.
*
* @method Phaser.GameObjects.Bob#setVisible
* @since 3.0.0
*
* @param {boolean} value - The visible state of the Game Object.
*
* @return {this} This Bob Game Object.
*/
setVisible: function(value) {
this.visible = value;
return this;
},
/**
* Set the Alpha level of this Bob. The alpha controls the opacity of the Game Object as it renders.
* Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque.
*
* A Bob with alpha 0 will skip rendering.
*
* @method Phaser.GameObjects.Bob#setAlpha
* @since 3.0.0
*
* @param {number} value - The alpha value used for this Bob. Between 0 and 1.
*
* @return {this} This Bob Game Object.
*/
setAlpha: function(value) {
this.alpha = value;
return this;
},
/**
* Sets the tint of this Bob.
*
* @method Phaser.GameObjects.Bob#setTint
* @since 3.20.0
*
* @param {number} value - The tint value used for this Bob. Between 0 and 0xffffff.
*
* @return {this} This Bob Game Object.
*/
setTint: function(value) {
this.tint = value;
return this;
},
/**
* Destroys this Bob instance.
* Removes itself from the Blitter and clears the parent, frame and data properties.
*
* @method Phaser.GameObjects.Bob#destroy
* @since 3.0.0
*/
destroy: function() {
this.parent.dirty = true;
this.parent.children.remove(this);
this.parent = void 0;
this.frame = void 0;
this.data = void 0;
},
/**
* The visible state of the Bob.
*
* An invisible Bob will skip rendering.
*
* @name Phaser.GameObjects.Bob#visible
* @type {boolean}
* @since 3.0.0
*/
visible: {
get: function() {
return this._visible;
},
set: function(value) {
this.parent.dirty |= this._visible !== value;
this._visible = value;
}
},
/**
* The alpha value of the Bob, between 0 and 1.
*
* A Bob with alpha 0 will skip rendering.
*
* @name Phaser.GameObjects.Bob#alpha
* @type {number}
* @since 3.0.0
*/
alpha: {
get: function() {
return this._alpha;
},
set: function(value) {
this.parent.dirty |= this._alpha > 0 !== value > 0;
this._alpha = value;
}
}
});
module2.exports = Bob;
}
),
/***/
16005: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Clamp = __webpack_require__2(45319);
var _FLAG = 2;
var Alpha = {
/**
* Private internal value. Holds the global alpha value.
*
* @name Phaser.GameObjects.Components.Alpha#_alpha
* @type {number}
* @private
* @default 1
* @since 3.0.0
*/
_alpha: 1,
/**
* Private internal value. Holds the top-left alpha value.
*
* @name Phaser.GameObjects.Components.Alpha#_alphaTL
* @type {number}
* @private
* @default 1
* @since 3.0.0
*/
_alphaTL: 1,
/**
* Private internal value. Holds the top-right alpha value.
*
* @name Phaser.GameObjects.Components.Alpha#_alphaTR
* @type {number}
* @private
* @default 1
* @since 3.0.0
*/
_alphaTR: 1,
/**
* Private internal value. Holds the bottom-left alpha value.
*
* @name Phaser.GameObjects.Components.Alpha#_alphaBL
* @type {number}
* @private
* @default 1
* @since 3.0.0
*/
_alphaBL: 1,
/**
* Private internal value. Holds the bottom-right alpha value.
*
* @name Phaser.GameObjects.Components.Alpha#_alphaBR
* @type {number}
* @private
* @default 1
* @since 3.0.0
*/
_alphaBR: 1,
/**
* Clears all alpha values associated with this Game Object.
*
* Immediately sets the alpha levels back to 1 (fully opaque).
*
* @method Phaser.GameObjects.Components.Alpha#clearAlpha
* @since 3.0.0
*
* @return {this} This Game Object instance.
*/
clearAlpha: function() {
return this.setAlpha(1);
},
/**
* Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders.
* Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque.
*
* If your game is running under WebGL you can optionally specify four different alpha values, each of which
* correspond to the four corners of the Game Object. Under Canvas only the `topLeft` value given is used.
*
* @method Phaser.GameObjects.Components.Alpha#setAlpha
* @since 3.0.0
*
* @param {number} [topLeft=1] - The alpha value used for the top-left of the Game Object. If this is the only value given it's applied across the whole Game Object.
* @param {number} [topRight] - The alpha value used for the top-right of the Game Object. WebGL only.
* @param {number} [bottomLeft] - The alpha value used for the bottom-left of the Game Object. WebGL only.
* @param {number} [bottomRight] - The alpha value used for the bottom-right of the Game Object. WebGL only.
*
* @return {this} This Game Object instance.
*/
setAlpha: function(topLeft, topRight, bottomLeft, bottomRight) {
if (topLeft === void 0) {
topLeft = 1;
}
if (topRight === void 0) {
this.alpha = topLeft;
} else {
this._alphaTL = Clamp(topLeft, 0, 1);
this._alphaTR = Clamp(topRight, 0, 1);
this._alphaBL = Clamp(bottomLeft, 0, 1);
this._alphaBR = Clamp(bottomRight, 0, 1);
}
return this;
},
/**
* The alpha value of the Game Object.
*
* This is a global value, impacting the entire Game Object, not just a region of it.
*
* @name Phaser.GameObjects.Components.Alpha#alpha
* @type {number}
* @since 3.0.0
*/
alpha: {
get: function() {
return this._alpha;
},
set: function(value) {
var v = Clamp(value, 0, 1);
this._alpha = v;
this._alphaTL = v;
this._alphaTR = v;
this._alphaBL = v;
this._alphaBR = v;
if (v === 0) {
this.renderFlags &= ~_FLAG;
} else {
this.renderFlags |= _FLAG;
}
}
},
/**
* The alpha value starting from the top-left of the Game Object.
* This value is interpolated from the corner to the center of the Game Object.
*
* @name Phaser.GameObjects.Components.Alpha#alphaTopLeft
* @type {number}
* @webglOnly
* @since 3.0.0
*/
alphaTopLeft: {
get: function() {
return this._alphaTL;
},
set: function(value) {
var v = Clamp(value, 0, 1);
this._alphaTL = v;
if (v !== 0) {
this.renderFlags |= _FLAG;
}
}
},
/**
* The alpha value starting from the top-right of the Game Object.
* This value is interpolated from the corner to the center of the Game Object.
*
* @name Phaser.GameObjects.Components.Alpha#alphaTopRight
* @type {number}
* @webglOnly
* @since 3.0.0
*/
alphaTopRight: {
get: function() {
return this._alphaTR;
},
set: function(value) {
var v = Clamp(value, 0, 1);
this._alphaTR = v;
if (v !== 0) {
this.renderFlags |= _FLAG;
}
}
},
/**
* The alpha value starting from the bottom-left of the Game Object.
* This value is interpolated from the corner to the center of the Game Object.
*
* @name Phaser.GameObjects.Components.Alpha#alphaBottomLeft
* @type {number}
* @webglOnly
* @since 3.0.0
*/
alphaBottomLeft: {
get: function() {
return this._alphaBL;
},
set: function(value) {
var v = Clamp(value, 0, 1);
this._alphaBL = v;
if (v !== 0) {
this.renderFlags |= _FLAG;
}
}
},
/**
* The alpha value starting from the bottom-right of the Game Object.
* This value is interpolated from the corner to the center of the Game Object.
*
* @name Phaser.GameObjects.Components.Alpha#alphaBottomRight
* @type {number}
* @webglOnly
* @since 3.0.0
*/
alphaBottomRight: {
get: function() {
return this._alphaBR;
},
set: function(value) {
var v = Clamp(value, 0, 1);
this._alphaBR = v;
if (v !== 0) {
this.renderFlags |= _FLAG;
}
}
}
};
module2.exports = Alpha;
}
),
/***/
88509: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Clamp = __webpack_require__2(45319);
var _FLAG = 2;
var AlphaSingle = {
/**
* Private internal value. Holds the global alpha value.
*
* @name Phaser.GameObjects.Components.AlphaSingle#_alpha
* @type {number}
* @private
* @default 1
* @since 3.0.0
*/
_alpha: 1,
/**
* Clears all alpha values associated with this Game Object.
*
* Immediately sets the alpha levels back to 1 (fully opaque).
*
* @method Phaser.GameObjects.Components.AlphaSingle#clearAlpha
* @since 3.0.0
*
* @return {this} This Game Object instance.
*/
clearAlpha: function() {
return this.setAlpha(1);
},
/**
* Set the Alpha level of this Game Object. The alpha controls the opacity of the Game Object as it renders.
* Alpha values are provided as a float between 0, fully transparent, and 1, fully opaque.
*
* @method Phaser.GameObjects.Components.AlphaSingle#setAlpha
* @since 3.0.0
*
* @param {number} [value=1] - The alpha value applied across the whole Game Object.
*
* @return {this} This Game Object instance.
*/
setAlpha: function(value) {
if (value === void 0) {
value = 1;
}
this.alpha = value;
return this;
},
/**
* The alpha value of the Game Object.
*
* This is a global value, impacting the entire Game Object, not just a region of it.
*
* @name Phaser.GameObjects.Components.AlphaSingle#alpha
* @type {number}
* @since 3.0.0
*/
alpha: {
get: function() {
return this._alpha;
},
set: function(value) {
var v = Clamp(value, 0, 1);
this._alpha = v;
if (v === 0) {
this.renderFlags &= ~_FLAG;
} else {
this.renderFlags |= _FLAG;
}
}
}
};
module2.exports = AlphaSingle;
}
),
/***/
90065: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BlendModes = __webpack_require__2(10312);
var BlendMode = {
/**
* Private internal value. Holds the current blend mode.
*
* @name Phaser.GameObjects.Components.BlendMode#_blendMode
* @type {number}
* @private
* @default 0
* @since 3.0.0
*/
_blendMode: BlendModes.NORMAL,
/**
* Sets the Blend Mode being used by this Game Object.
*
* This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay)
*
* Under WebGL only the following Blend Modes are available:
*
* * NORMAL
* * ADD
* * MULTIPLY
* * SCREEN
* * ERASE
*
* Canvas has more available depending on browser support.
*
* You can also create your own custom Blend Modes in WebGL.
*
* Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending
* on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these
* reasons try to be careful about the construction of your Scene and the frequency of which blend modes
* are used.
*
* @name Phaser.GameObjects.Components.BlendMode#blendMode
* @type {(Phaser.BlendModes|string|number)}
* @since 3.0.0
*/
blendMode: {
get: function() {
return this._blendMode;
},
set: function(value) {
if (typeof value === "string") {
value = BlendModes[value];
}
value |= 0;
if (value >= -1) {
this._blendMode = value;
}
}
},
/**
* Sets the Blend Mode being used by this Game Object.
*
* This can be a const, such as `Phaser.BlendModes.SCREEN`, or an integer, such as 4 (for Overlay)
*
* Under WebGL only the following Blend Modes are available:
*
* * NORMAL
* * ADD
* * MULTIPLY
* * SCREEN
* * ERASE (only works when rendering to a framebuffer, like a Render Texture)
*
* Canvas has more available depending on browser support.
*
* You can also create your own custom Blend Modes in WebGL.
*
* Blend modes have different effects under Canvas and WebGL, and from browser to browser, depending
* on support. Blend Modes also cause a WebGL batch flush should it encounter a new blend mode. For these
* reasons try to be careful about the construction of your Scene and the frequency in which blend modes
* are used.
*
* @method Phaser.GameObjects.Components.BlendMode#setBlendMode
* @since 3.0.0
*
* @param {(string|Phaser.BlendModes|number)} value - The BlendMode value. Either a string, a CONST or a number.
*
* @return {this} This Game Object instance.
*/
setBlendMode: function(value) {
this.blendMode = value;
return this;
}
};
module2.exports = BlendMode;
}
),
/***/
94215: (
/***/
(module2) => {
var ComputedSize = {
/**
* The native (un-scaled) width of this Game Object.
*
* Changing this value will not change the size that the Game Object is rendered in-game.
* For that you need to either set the scale of the Game Object (`setScale`) or use
* the `displayWidth` property.
*
* @name Phaser.GameObjects.Components.ComputedSize#width
* @type {number}
* @since 3.0.0
*/
width: 0,
/**
* The native (un-scaled) height of this Game Object.
*
* Changing this value will not change the size that the Game Object is rendered in-game.
* For that you need to either set the scale of the Game Object (`setScale`) or use
* the `displayHeight` property.
*
* @name Phaser.GameObjects.Components.ComputedSize#height
* @type {number}
* @since 3.0.0
*/
height: 0,
/**
* The displayed width of this Game Object.
*
* This value takes into account the scale factor.
*
* Setting this value will adjust the Game Object's scale property.
*
* @name Phaser.GameObjects.Components.ComputedSize#displayWidth
* @type {number}
* @since 3.0.0
*/
displayWidth: {
get: function() {
return this.scaleX * this.width;
},
set: function(value) {
this.scaleX = value / this.width;
}
},
/**
* The displayed height of this Game Object.
*
* This value takes into account the scale factor.
*
* Setting this value will adjust the Game Object's scale property.
*
* @name Phaser.GameObjects.Components.ComputedSize#displayHeight
* @type {number}
* @since 3.0.0
*/
displayHeight: {
get: function() {
return this.scaleY * this.height;
},
set: function(value) {
this.scaleY = value / this.height;
}
},
/**
* Sets the internal size of this Game Object, as used for frame or physics body creation.
*
* This will not change the size that the Game Object is rendered in-game.
* For that you need to either set the scale of the Game Object (`setScale`) or call the
* `setDisplaySize` method, which is the same thing as changing the scale but allows you
* to do so by giving pixel values.
*
* If you have enabled this Game Object for input, changing the size will _not_ change the
* size of the hit area. To do this you should adjust the `input.hitArea` object directly.
*
* @method Phaser.GameObjects.Components.ComputedSize#setSize
* @since 3.4.0
*
* @param {number} width - The width of this Game Object.
* @param {number} height - The height of this Game Object.
*
* @return {this} This Game Object instance.
*/
setSize: function(width, height) {
this.width = width;
this.height = height;
return this;
},
/**
* Sets the display size of this Game Object.
*
* Calling this will adjust the scale.
*
* @method Phaser.GameObjects.Components.ComputedSize#setDisplaySize
* @since 3.4.0
*
* @param {number} width - The width of this Game Object.
* @param {number} height - The height of this Game Object.
*
* @return {this} This Game Object instance.
*/
setDisplaySize: function(width, height) {
this.displayWidth = width;
this.displayHeight = height;
return this;
}
};
module2.exports = ComputedSize;
}
),
/***/
61683: (
/***/
(module2) => {
var Crop = {
/**
* The Texture this Game Object is using to render with.
*
* @name Phaser.GameObjects.Components.Crop#texture
* @type {Phaser.Textures.Texture|Phaser.Textures.CanvasTexture}
* @since 3.0.0
*/
texture: null,
/**
* The Texture Frame this Game Object is using to render with.
*
* @name Phaser.GameObjects.Components.Crop#frame
* @type {Phaser.Textures.Frame}
* @since 3.0.0
*/
frame: null,
/**
* A boolean flag indicating if this Game Object is being cropped or not.
* You can toggle this at any time after `setCrop` has been called, to turn cropping on or off.
* Equally, calling `setCrop` with no arguments will reset the crop and disable it.
*
* @name Phaser.GameObjects.Components.Crop#isCropped
* @type {boolean}
* @since 3.11.0
*/
isCropped: false,
/**
* Applies a crop to a texture based Game Object, such as a Sprite or Image.
*
* The crop is a rectangle that limits the area of the texture frame that is visible during rendering.
*
* Cropping a Game Object does not change its size, dimensions, physics body or hit area, it just
* changes what is shown when rendered.
*
* The crop size as well as coordinates can not exceed the the size of the texture frame.
*
* The crop coordinates are relative to the texture frame, not the Game Object, meaning 0 x 0 is the top-left.
*
* Therefore, if you had a Game Object that had an 800x600 sized texture, and you wanted to show only the left
* half of it, you could call `setCrop(0, 0, 400, 600)`.
*
* It is also scaled to match the Game Object scale automatically. Therefore a crop rectangle of 100x50 would crop
* an area of 200x100 when applied to a Game Object that had a scale factor of 2.
*
* You can either pass in numeric values directly, or you can provide a single Rectangle object as the first argument.
*
* Call this method with no arguments at all to reset the crop, or toggle the property `isCropped` to `false`.
*
* You should do this if the crop rectangle becomes the same size as the frame itself, as it will allow
* the renderer to skip several internal calculations.
*
* @method Phaser.GameObjects.Components.Crop#setCrop
* @since 3.11.0
*
* @param {(number|Phaser.Geom.Rectangle)} [x] - The x coordinate to start the crop from. Cannot be negative or exceed the Frame width. Or a Phaser.Geom.Rectangle object, in which case the rest of the arguments are ignored.
* @param {number} [y] - The y coordinate to start the crop from. Cannot be negative or exceed the Frame height.
* @param {number} [width] - The width of the crop rectangle in pixels. Cannot exceed the Frame width.
* @param {number} [height] - The height of the crop rectangle in pixels. Cannot exceed the Frame height.
*
* @return {this} This Game Object instance.
*/
setCrop: function(x, y, width, height) {
if (x === void 0) {
this.isCropped = false;
} else if (this.frame) {
if (typeof x === "number") {
this.frame.setCropUVs(this._crop, x, y, width, height, this.flipX, this.flipY);
} else {
var rect = x;
this.frame.setCropUVs(this._crop, rect.x, rect.y, rect.width, rect.height, this.flipX, this.flipY);
}
this.isCropped = true;
}
return this;
},
/**
* Internal method that returns a blank, well-formed crop object for use by a Game Object.
*
* @method Phaser.GameObjects.Components.Crop#resetCropObject
* @private
* @since 3.12.0
*
* @return {object} The crop object.
*/
resetCropObject: function() {
return { u0: 0, v0: 0, u1: 0, v1: 0, width: 0, height: 0, x: 0, y: 0, flipX: false, flipY: false, cx: 0, cy: 0, cw: 0, ch: 0 };
}
};
module2.exports = Crop;
}
),
/***/
89272: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var ArrayUtils = __webpack_require__2(37105);
var Depth = {
/**
* Private internal value. Holds the depth of the Game Object.
*
* @name Phaser.GameObjects.Components.Depth#_depth
* @type {number}
* @private
* @default 0
* @since 3.0.0
*/
_depth: 0,
/**
* The depth of this Game Object within the Scene. Ensure this value is only ever set to a number data-type.
*
* The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order
* of Game Objects, without actually moving their position in the display list.
*
* The default depth is zero. A Game Object with a higher depth
* value will always render in front of one with a lower value.
*
* Setting the depth will queue a depth sort event within the Scene.
*
* @name Phaser.GameObjects.Components.Depth#depth
* @type {number}
* @since 3.0.0
*/
depth: {
get: function() {
return this._depth;
},
set: function(value) {
if (this.displayList) {
this.displayList.queueDepthSort();
}
this._depth = value;
}
},
/**
* The depth of this Game Object within the Scene.
*
* The depth is also known as the 'z-index' in some environments, and allows you to change the rendering order
* of Game Objects, without actually moving their position in the display list.
*
* The default depth is zero. A Game Object with a higher depth
* value will always render in front of one with a lower value.
*
* Setting the depth will queue a depth sort event within the Scene.
*
* @method Phaser.GameObjects.Components.Depth#setDepth
* @since 3.0.0
*
* @param {number} value - The depth of this Game Object. Ensure this value is only ever a number data-type.
*
* @return {this} This Game Object instance.
*/
setDepth: function(value) {
if (value === void 0) {
value = 0;
}
this.depth = value;
return this;
},
/**
* Sets this Game Object to be at the top of the display list, or the top of its parent container.
*
* Being at the top means it will render on-top of everything else.
*
* This method does not change this Game Objects `depth` value, it simply alters its list position.
*
* @method Phaser.GameObjects.Components.Depth#setToTop
* @since 3.85.0
*
* @return {this} This Game Object instance.
*/
setToTop: function() {
var list = this.getDisplayList();
if (list) {
ArrayUtils.BringToTop(list, this);
}
return this;
},
/**
* Sets this Game Object to the back of the display list, or the back of its parent container.
*
* Being at the back means it will render below everything else.
*
* This method does not change this Game Objects `depth` value, it simply alters its list position.
*
* @method Phaser.GameObjects.Components.Depth#setToBack
* @since 3.85.0
*
* @return {this} This Game Object instance.
*/
setToBack: function() {
var list = this.getDisplayList();
if (list) {
ArrayUtils.SendToBack(list, this);
}
return this;
},
/**
* Move this Game Object so that it appears above the given Game Object.
*
* This means it will render immediately after the other object in the display list.
*
* Both objects must belong to the same display list, or parent container.
*
* This method does not change this Game Objects `depth` value, it simply alters its list position.
*
* @method Phaser.GameObjects.Components.Depth#setAbove
* @since 3.85.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that this Game Object will be moved to be above.
*
* @return {this} This Game Object instance.
*/
setAbove: function(gameObject) {
var list = this.getDisplayList();
if (list && gameObject) {
ArrayUtils.MoveAbove(list, this, gameObject);
}
return this;
},
/**
* Move this Game Object so that it appears below the given Game Object.
*
* This means it will render immediately under the other object in the display list.
*
* Both objects must belong to the same display list, or parent container.
*
* This method does not change this Game Objects `depth` value, it simply alters its list position.
*
* @method Phaser.GameObjects.Components.Depth#setBelow
* @since 3.85.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that this Game Object will be moved to be below.
*
* @return {this} This Game Object instance.
*/
setBelow: function(gameObject) {
var list = this.getDisplayList();
if (list && gameObject) {
ArrayUtils.MoveBelow(list, this, gameObject);
}
return this;
}
};
module2.exports = Depth;
}
),
/***/
47059: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Effects = __webpack_require__2(66064);
var SpliceOne = __webpack_require__2(19133);
var FX = new Class({
initialize: function FX2(gameObject, isPost) {
this.gameObject = gameObject;
this.isPost = isPost;
this.enabled = false;
this.list = [];
this.padding = 0;
},
/**
* Sets the amount of extra padding to be applied to this Game Object
* when it is being rendered by a PreFX Pipeline.
*
* Lots of FX require additional spacing added to the texture the
* Game Object uses, for example a glow or shadow effect, and this
* method allows you to control how much extra padding is included
* in addition to the texture size.
*
* You do not need to set this if you're only using Post FX.
*
* @method Phaser.GameObjects.Components.FX#setPadding
* @webglOnly
* @since 3.60.0
*
* @param {number} [padding=0] - The amount of padding to add to this Game Object.
*
* @return {this} This Game Object instance.
*/
setPadding: function(padding) {
if (padding === void 0) {
padding = 0;
}
this.padding = padding;
return this.gameObject;
},
/**
* This callback is invoked when this Game Object is copied by a PreFX Pipeline.
*
* This happens when the pipeline uses its `copySprite` method.
*
* It's invoked prior to the copy, allowing you to set shader uniforms, etc on the pipeline.
*
* @method Phaser.GameObjects.Components.FX#onFXCopy
* @since 3.60.0
*
* @param {Phaser.Renderer.WebGL.Pipelines.PreFXPipeline} pipeline - The PreFX Pipeline that invoked this callback.
*/
onFXCopy: function() {
},
/**
* This callback is invoked when this Game Object is rendered by a PreFX Pipeline.
*
* This happens when the pipeline uses its `drawSprite` method.
*
* It's invoked prior to the draw, allowing you to set shader uniforms, etc on the pipeline.
*
* @method Phaser.GameObjects.Components.FX#onFX
* @since 3.60.0
*
* @param {Phaser.Renderer.WebGL.Pipelines.PreFXPipeline} pipeline - The PreFX Pipeline that invoked this callback.
*/
onFX: function() {
},
/**
* Enables this FX Component and applies the FXPipeline to the parent Game Object.
*
* This is called automatically whenever you call a method such as `addBloom`, etc.
*
* You can check the `enabled` property to see if the Game Object is already enabled, or not.
*
* This only applies to Pre FX. Post FX are always enabled.
*
* @method Phaser.GameObjects.Components.FX#enable
* @since 3.60.0
*
* @param {number} [padding=0] - The amount of padding to add to this Game Object.
*/
enable: function(padding) {
if (this.isPost) {
return;
}
var renderer = this.gameObject.scene.sys.renderer;
if (renderer && renderer.pipelines) {
this.gameObject.pipeline = renderer.pipelines.FX_PIPELINE;
if (padding !== void 0) {
this.padding = padding;
}
this.enabled = true;
} else {
this.enabled = false;
}
},
/**
* Destroys and removes all FX Controllers that are part of this FX Component,
* then disables it.
*
* If this is a Pre FX Component it will only remove Pre FX.
* If this is a Post FX Component it will only remove Post FX.
*
* To remove both at once use the `GameObject.clearFX` method instead.
*
* @method Phaser.GameObjects.Components.FX#clear
* @since 3.60.0
*
* @return {this} This Game Object instance.
*/
clear: function() {
if (this.isPost) {
this.gameObject.resetPostPipeline(true);
} else {
var list = this.list;
for (var i = 0; i < list.length; i++) {
list[i].destroy();
}
this.list = [];
}
this.enabled = false;
return this.gameObject;
},
/**
* Searches for the given FX Controller within this FX Component.
*
* If found, the controller is removed from this component and then destroyed.
*
* @method Phaser.GameObjects.Components.FX#remove
* @since 3.60.0
*
* @generic {Phaser.FX.Controller} T
* @genericUse {T} - [fx]
*
* @param {Phaser.FX.Controller} fx - The FX Controller to remove from this FX Component.
*
* @return {this} This Game Object instance.
*/
remove: function(fx) {
var i;
if (this.isPost) {
var pipelines = this.gameObject.getPostPipeline(String(fx.type));
if (!Array.isArray(pipelines)) {
pipelines = [pipelines];
}
for (i = 0; i < pipelines.length; i++) {
var pipeline = pipelines[i];
if (pipeline.controller === fx) {
this.gameObject.removePostPipeline(pipeline);
fx.destroy();
break;
}
}
} else {
var list = this.list;
for (i = 0; i < list.length; i++) {
if (list[i] === fx) {
SpliceOne(list, i);
fx.destroy();
}
}
}
return this.gameObject;
},
/**
* Disables this FX Component.
*
* This will reset the pipeline on the Game Object that owns this component back to its
* default and flag this component as disabled.
*
* You can re-enable it again by calling `enable` for Pre FX or by adding an FX for Post FX.
*
* Optionally, set `clear` to destroy all current FX Controllers.
*
* @method Phaser.GameObjects.Components.FX#disable
* @since 3.60.0
*
* @param {boolean} [clear=false] - Destroy and remove all FX Controllers that are part of this component.
*
* @return {this} This Game Object instance.
*/
disable: function(clear) {
if (clear === void 0) {
clear = false;
}
if (!this.isPost) {
this.gameObject.resetPipeline();
}
this.enabled = false;
if (clear) {
this.clear();
}
return this.gameObject;
},
/**
* Adds the given FX Controler to this FX Component.
*
* Note that adding an FX Controller does not remove any existing FX. They all stack-up
* on-top of each other. If you don't want this, make sure to call either `remove` or
* `clear` first.
*
* @method Phaser.GameObjects.Components.FX#add
* @since 3.60.0
*
* @generic {Phaser.FX.Controller} T
* @genericUse {T} - [fx]
*
* @param {Phaser.FX.Controller} fx - The FX Controller to add to this FX Component.
* @param {object} [config] - Optional configuration object that is passed to the pipeline during instantiation.
*
* @return {Phaser.FX.Controller} The FX Controller.
*/
add: function(fx, config) {
if (this.isPost) {
var type = String(fx.type);
this.gameObject.setPostPipeline(type, config);
var pipeline = this.gameObject.getPostPipeline(type);
if (pipeline) {
if (Array.isArray(pipeline)) {
pipeline = pipeline.pop();
}
if (pipeline) {
pipeline.controller = fx;
}
return fx;
}
} else {
if (!this.enabled) {
this.enable();
}
this.list.push(fx);
return fx;
}
},
/**
* Adds a Glow effect.
*
* The glow effect is a visual technique that creates a soft, luminous halo around game objects,
* characters, or UI elements. This effect is used to emphasize importance, enhance visual appeal,
* or convey a sense of energy, magic, or otherworldly presence. The effect can also be set on
* the inside of the Game Object. The color and strength of the glow can be modified.
*
* @method Phaser.GameObjects.Components.FX#addGlow
* @since 3.60.0
*
* @param {number} [color=0xffffff] - The color of the glow effect as a number value.
* @param {number} [outerStrength=4] - The strength of the glow outward from the edge of the Sprite.
* @param {number} [innerStrength=0] - The strength of the glow inward from the edge of the Sprite.
* @param {boolean} [knockout=false] - If `true` only the glow is drawn, not the texture itself.
* @param {number} [quality=0.1] - Only available for PostFX. Sets the quality of this Glow effect. Default is 0.1. Cannot be changed post-creation.
* @param {number} [distance=10] - Only available for PostFX. Sets the distance of this Glow effect. Default is 10. Cannot be changed post-creation.
*
* @return {Phaser.FX.Glow} The Glow FX Controller.
*/
addGlow: function(color, outerStrength, innerStrength, knockout, quality, distance) {
return this.add(new Effects.Glow(this.gameObject, color, outerStrength, innerStrength, knockout), { quality, distance });
},
/**
* Adds a Shadow effect.
*
* The shadow effect is a visual technique used to create the illusion of depth and realism by adding darker,
* offset silhouettes or shapes beneath game objects, characters, or environments. These simulated shadows
* help to enhance the visual appeal and immersion, making the 2D game world appear more dynamic and three-dimensional.
*
* @method Phaser.GameObjects.Components.FX#addShadow
* @since 3.60.0
*
* @param {number} [x=0] - The horizontal offset of the shadow effect.
* @param {number} [y=0] - The vertical offset of the shadow effect.
* @param {number} [decay=0.1] - The amount of decay for shadow effect.
* @param {number} [power=1] - The power of the shadow effect.
* @param {number} [color=0x000000] - The color of the shadow.
* @param {number} [samples=6] - The number of samples that the shadow effect will run for. An integer between 1 and 12.
* @param {number} [intensity=1] - The intensity of the shadow effect.
*
* @return {Phaser.FX.Shadow} The Shadow FX Controller.
*/
addShadow: function(x, y, decay, power, color, samples, intensity) {
return this.add(new Effects.Shadow(this.gameObject, x, y, decay, power, color, samples, intensity));
},
/**
* Adds a Pixelate effect.
*
* The pixelate effect is a visual technique that deliberately reduces the resolution or detail of an image,
* creating a blocky or mosaic appearance composed of large, visible pixels. This effect can be used for stylistic
* purposes, as a homage to retro gaming, or as a means to obscure certain elements within the game, such as
* during a transition or to censor specific content.
*
* @method Phaser.GameObjects.Components.FX#addPixelate
* @since 3.60.0
*
* @param {number} [amount=1] - The amount of pixelation to apply.
*
* @return {Phaser.FX.Pixelate} The Pixelate FX Controller.
*/
addPixelate: function(amount) {
return this.add(new Effects.Pixelate(this.gameObject, amount));
},
/**
* Adds a Vignette effect.
*
* The vignette effect is a visual technique where the edges of the screen, or a Game Object, gradually darken or blur,
* creating a frame-like appearance. This effect is used to draw the player's focus towards the central action or subject,
* enhance immersion, and provide a cinematic or artistic quality to the game's visuals.
*
* @method Phaser.GameObjects.Components.FX#addVignette
* @since 3.60.0
*
* @param {number} [x=0.5] - The horizontal offset of the vignette effect. This value is normalized to the range 0 to 1.
* @param {number} [y=0.5] - The vertical offset of the vignette effect. This value is normalized to the range 0 to 1.
* @param {number} [radius=0.5] - The radius of the vignette effect. This value is normalized to the range 0 to 1.
* @param {number} [strength=0.5] - The strength of the vignette effect.
*
* @return {Phaser.FX.Vignette} The Vignette FX Controller.
*/
addVignette: function(x, y, radius, strength) {
return this.add(new Effects.Vignette(this.gameObject, x, y, radius, strength));
},
/**
* Adds a Shine effect.
*
* The shine effect is a visual technique that simulates the appearance of reflective
* or glossy surfaces by passing a light beam across a Game Object. This effect is used to
* enhance visual appeal, emphasize certain features, and create a sense of depth or
* material properties.
*
* @method Phaser.GameObjects.Components.FX#addShine
* @since 3.60.0
*
* @param {number} [speed=0.5] - The speed of the Shine effect.
* @param {number} [lineWidth=0.5] - The line width of the Shine effect.
* @param {number} [gradient=3] - The gradient of the Shine effect.
* @param {boolean} [reveal=false] - Does this Shine effect reveal or get added to its target?
*
* @return {Phaser.FX.Shine} The Shine FX Controller.
*/
addShine: function(speed, lineWidth, gradient, reveal) {
return this.add(new Effects.Shine(this.gameObject, speed, lineWidth, gradient, reveal));
},
/**
* Adds a Blur effect.
*
* A Gaussian blur is the result of blurring an image by a Gaussian function. It is a widely used effect,
* typically to reduce image noise and reduce detail. The visual effect of this blurring technique is a
* smooth blur resembling that of viewing the image through a translucent screen, distinctly different
* from the bokeh effect produced by an out-of-focus lens or the shadow of an object under usual illumination.
*
* @method Phaser.GameObjects.Components.FX#addBlur
* @since 3.60.0
*
* @param {number} [quality=0] - The quality of the blur effect. Can be either 0 for Low Quality, 1 for Medium Quality or 2 for High Quality.
* @param {number} [x=2] - The horizontal offset of the blur effect.
* @param {number} [y=2] - The vertical offset of the blur effect.
* @param {number} [strength=1] - The strength of the blur effect.
* @param {number} [color=0xffffff] - The color of the blur, as a hex value.
* @param {number} [steps=4] - The number of steps to run the blur effect for. This value should always be an integer.
*
* @return {Phaser.FX.Blur} The Blur FX Controller.
*/
addBlur: function(quality, x, y, strength, color, steps) {
return this.add(new Effects.Blur(this.gameObject, quality, x, y, strength, color, steps));
},
/**
* Adds a Gradient effect.
*
* The gradient overlay effect is a visual technique where a smooth color transition is applied over Game Objects,
* such as sprites or UI components. This effect is used to enhance visual appeal, emphasize depth, or create
* stylistic and atmospheric variations. It can also be utilized to convey information, such as representing
* progress or health status through color changes.
*
* @method Phaser.GameObjects.Components.FX#addGradient
* @since 3.60.0
*
* @param {number} [color1=0xff0000] - The first gradient color, given as a number value.
* @param {number} [color2=0x00ff00] - The second gradient color, given as a number value.
* @param {number} [alpha=0.2] - The alpha value of the gradient effect.
* @param {number} [fromX=0] - The horizontal position the gradient will start from. This value is normalized, between 0 and 1, and is not in pixels.
* @param {number} [fromY=0] - The vertical position the gradient will start from. This value is normalized, between 0 and 1, and is not in pixels.
* @param {number} [toX=0] - The horizontal position the gradient will end at. This value is normalized, between 0 and 1, and is not in pixels.
* @param {number} [toY=1] - The vertical position the gradient will end at. This value is normalized, between 0 and 1, and is not in pixels.
* @param {number} [size=0] - How many 'chunks' the gradient is divided in to, as spread over the entire height of the texture. Leave this at zero for a smooth gradient, or set higher for a more retro chunky effect.
*
* @return {Phaser.FX.Gradient} The Gradient FX Controller.
*/
addGradient: function(color1, color2, alpha, fromX, fromY, toX, toY, size) {
return this.add(new Effects.Gradient(this.gameObject, color1, color2, alpha, fromX, fromY, toX, toY, size));
},
/**
* Adds a Bloom effect.
*
* Bloom is an effect used to reproduce an imaging artifact of real-world cameras.
* The effect produces fringes of light extending from the borders of bright areas in an image,
* contributing to the illusion of an extremely bright light overwhelming the
* camera or eye capturing the scene.
*
* @method Phaser.GameObjects.Components.FX#addBloom
* @since 3.60.0
*
* @param {number} [color] - The color of the Bloom, as a hex value.
* @param {number} [offsetX=1] - The horizontal offset of the bloom effect.
* @param {number} [offsetY=1] - The vertical offset of the bloom effect.
* @param {number} [blurStrength=1] - The strength of the blur process of the bloom effect.
* @param {number} [strength=1] - The strength of the blend process of the bloom effect.
* @param {number} [steps=4] - The number of steps to run the Bloom effect for. This value should always be an integer.
*
* @return {Phaser.FX.Bloom} The Bloom FX Controller.
*/
addBloom: function(color, offsetX, offsetY, blurStrength, strength, steps) {
return this.add(new Effects.Bloom(this.gameObject, color, offsetX, offsetY, blurStrength, strength, steps));
},
/**
* Adds a ColorMatrix effect.
*
* The color matrix effect is a visual technique that involves manipulating the colors of an image
* or scene using a mathematical matrix. This process can adjust hue, saturation, brightness, and contrast,
* allowing developers to create various stylistic appearances or mood settings within the game.
* Common applications include simulating different lighting conditions, applying color filters,
* or achieving a specific visual style.
*
* @method Phaser.GameObjects.Components.FX#addColorMatrix
* @since 3.60.0
*
* @return {Phaser.FX.ColorMatrix} The ColorMatrix FX Controller.
*/
addColorMatrix: function() {
return this.add(new Effects.ColorMatrix(this.gameObject));
},
/**
* Adds a Circle effect.
*
* This effect will draw a circle around the texture of the Game Object, effectively masking off
* any area outside of the circle without the need for an actual mask. You can control the thickness
* of the circle, the color of the circle and the color of the background, should the texture be
* transparent. You can also control the feathering applied to the circle, allowing for a harsh or soft edge.
*
* Please note that adding this effect to a Game Object will not change the input area or physics body of
* the Game Object, should it have one.
*
* @method Phaser.GameObjects.Components.FX#addCircle
* @since 3.60.0
*
* @param {number} [thickness=8] - The width of the circle around the texture, in pixels.
* @param {number} [color=0xfeedb6] - The color of the circular ring, given as a number value.
* @param {number} [backgroundColor=0xff0000] - The color of the background, behind the texture, given as a number value.
* @param {number} [scale=1] - The scale of the circle. The default scale is 1, which is a circle the full size of the underlying texture.
* @param {number} [feather=0.005] - The amount of feathering to apply to the circle from the ring.
*
* @return {Phaser.FX.Circle} The Circle FX Controller.
*/
addCircle: function(thickness, color, backgroundColor, scale, feather) {
return this.add(new Effects.Circle(this.gameObject, thickness, color, backgroundColor, scale, feather));
},
/**
* Adds a Barrel effect.
*
* A barrel effect allows you to apply either a 'pinch' or 'expand' distortion to
* a Game Object. The amount of the effect can be modified in real-time.
*
* @method Phaser.GameObjects.Components.FX#addBarrel
* @since 3.60.0
*
* @param {number} [amount=1] - The amount of distortion applied to the barrel effect. A value of 1 is no distortion. Typically keep this within +- 1.
*
* @return {Phaser.FX.Barrel} The Barrel FX Controller.
*/
addBarrel: function(amount) {
return this.add(new Effects.Barrel(this.gameObject, amount));
},
/**
* Adds a Displacement effect.
*
* The displacement effect is a visual technique that alters the position of pixels in an image
* or texture based on the values of a displacement map. This effect is used to create the illusion
* of depth, surface irregularities, or distortion in otherwise flat elements. It can be applied to
* characters, objects, or backgrounds to enhance realism, convey movement, or achieve various
* stylistic appearances.
*
* @method Phaser.GameObjects.Components.FX#addDisplacement
* @since 3.60.0
*
* @param {string} [texture='__WHITE'] - The unique string-based key of the texture to use for displacement, which must exist in the Texture Manager.
* @param {number} [x=0.005] - The amount of horizontal displacement to apply. A very small float number, such as 0.005.
* @param {number} [y=0.005] - The amount of vertical displacement to apply. A very small float number, such as 0.005.
*
* @return {Phaser.FX.Displacement} The Displacement FX Controller.
*/
addDisplacement: function(texture, x, y) {
return this.add(new Effects.Displacement(this.gameObject, texture, x, y));
},
/**
* Adds a Wipe effect.
*
* The wipe or reveal effect is a visual technique that gradually uncovers or conceals elements
* in the game, such as images, text, or scene transitions. This effect is often used to create
* a sense of progression, reveal hidden content, or provide a smooth and visually appealing transition
* between game states.
*
* You can set both the direction and the axis of the wipe effect. The following combinations are possible:
*
* * left to right: direction 0, axis 0
* * right to left: direction 1, axis 0
* * top to bottom: direction 1, axis 1
* * bottom to top: direction 1, axis 0
*
* It is up to you to set the `progress` value yourself, i.e. via a Tween, in order to transition the effect.
*
* @method Phaser.GameObjects.Components.FX#addWipe
* @since 3.60.0
*
* @param {number} [wipeWidth=0.1] - The width of the wipe effect. This value is normalized in the range 0 to 1.
* @param {number} [direction=0] - The direction of the wipe effect. Either 0 or 1. Set in conjunction with the axis property.
* @param {number} [axis=0] - The axis of the wipe effect. Either 0 or 1. Set in conjunction with the direction property.
*
* @return {Phaser.FX.Wipe} The Wipe FX Controller.
*/
addWipe: function(wipeWidth, direction, axis) {
return this.add(new Effects.Wipe(this.gameObject, wipeWidth, direction, axis));
},
/**
* Adds a Reveal Wipe effect.
*
* The wipe or reveal effect is a visual technique that gradually uncovers or conceals elements
* in the game, such as images, text, or scene transitions. This effect is often used to create
* a sense of progression, reveal hidden content, or provide a smooth and visually appealing transition
* between game states.
*
* You can set both the direction and the axis of the wipe effect. The following combinations are possible:
*
* * left to right: direction 0, axis 0
* * right to left: direction 1, axis 0
* * top to bottom: direction 1, axis 1
* * bottom to top: direction 1, axis 0
*
* It is up to you to set the `progress` value yourself, i.e. via a Tween, in order to transition the effect.
*
* @method Phaser.GameObjects.Components.FX#addReveal
* @since 3.60.0
*
* @param {number} [wipeWidth=0.1] - The width of the wipe effect. This value is normalized in the range 0 to 1.
* @param {number} [direction=0] - The direction of the wipe effect. Either 0 or 1. Set in conjunction with the axis property.
* @param {number} [axis=0] - The axis of the wipe effect. Either 0 or 1. Set in conjunction with the direction property.
*
* @return {Phaser.FX.Wipe} The Wipe FX Controller.
*/
addReveal: function(wipeWidth, direction, axis) {
return this.add(new Effects.Wipe(this.gameObject, wipeWidth, direction, axis, true));
},
/**
* Adds a Bokeh effect.
*
* Bokeh refers to a visual effect that mimics the photographic technique of creating a shallow depth of field.
* This effect is used to emphasize the game's main subject or action, by blurring the background or foreground
* elements, resulting in a more immersive and visually appealing experience. It is achieved through rendering
* techniques that simulate the out-of-focus areas, giving a sense of depth and realism to the game's graphics.
*
* See also Tilt Shift.
*
* @method Phaser.GameObjects.Components.FX#addBokeh
* @since 3.60.0
*
* @param {number} [radius=0.5] - The radius of the bokeh effect.
* @param {number} [amount=1] - The amount of the bokeh effect.
* @param {number} [contrast=0.2] - The color contrast of the bokeh effect.
*
* @return {Phaser.FX.Bokeh} The Bokeh FX Controller.
*/
addBokeh: function(radius, amount, contrast) {
return this.add(new Effects.Bokeh(this.gameObject, radius, amount, contrast));
},
/**
* Adds a Tilt Shift effect.
*
* This Bokeh effect can also be used to generate a Tilt Shift effect, which is a technique used to create a miniature
* effect by blurring everything except a small area of the image. This effect is achieved by blurring the
* top and bottom elements, while keeping the center area in focus.
*
* See also Bokeh.
*
* @method Phaser.GameObjects.Components.FX#addTiltShift
* @since 3.60.0
*
* @param {number} [radius=0.5] - The radius of the bokeh effect.
* @param {number} [amount=1] - The amount of the bokeh effect.
* @param {number} [contrast=0.2] - The color contrast of the bokeh effect.
* @param {number} [blurX=1] - The amount of horizontal blur.
* @param {number} [blurY=1] - The amount of vertical blur.
* @param {number} [strength=1] - The strength of the blur.
*
* @return {Phaser.FX.Bokeh} The Bokeh TiltShift FX Controller.
*/
addTiltShift: function(radius, amount, contrast, blurX, blurY, strength) {
return this.add(new Effects.Bokeh(this.gameObject, radius, amount, contrast, true, blurX, blurY, strength));
},
/**
* Destroys this FX Component.
*
* Called automatically when Game Objects are destroyed.
*
* @method Phaser.GameObjects.Components.FX#destroy
* @since 3.60.0
*/
destroy: function() {
this.clear();
this.gameObject = null;
}
});
module2.exports = FX;
}
),
/***/
54434: (
/***/
(module2) => {
var Flip = {
/**
* The horizontally flipped state of the Game Object.
*
* A Game Object that is flipped horizontally will render inversed on the horizontal axis.
* Flipping always takes place from the middle of the texture and does not impact the scale value.
* If this Game Object has a physics body, it will not change the body. This is a rendering toggle only.
*
* @name Phaser.GameObjects.Components.Flip#flipX
* @type {boolean}
* @default false
* @since 3.0.0
*/
flipX: false,
/**
* The vertically flipped state of the Game Object.
*
* A Game Object that is flipped vertically will render inversed on the vertical axis (i.e. upside down)
* Flipping always takes place from the middle of the texture and does not impact the scale value.
* If this Game Object has a physics body, it will not change the body. This is a rendering toggle only.
*
* @name Phaser.GameObjects.Components.Flip#flipY
* @type {boolean}
* @default false
* @since 3.0.0
*/
flipY: false,
/**
* Toggles the horizontal flipped state of this Game Object.
*
* A Game Object that is flipped horizontally will render inversed on the horizontal axis.
* Flipping always takes place from the middle of the texture and does not impact the scale value.
* If this Game Object has a physics body, it will not change the body. This is a rendering toggle only.
*
* @method Phaser.GameObjects.Components.Flip#toggleFlipX
* @since 3.0.0
*
* @return {this} This Game Object instance.
*/
toggleFlipX: function() {
this.flipX = !this.flipX;
return this;
},
/**
* Toggles the vertical flipped state of this Game Object.
*
* @method Phaser.GameObjects.Components.Flip#toggleFlipY
* @since 3.0.0
*
* @return {this} This Game Object instance.
*/
toggleFlipY: function() {
this.flipY = !this.flipY;
return this;
},
/**
* Sets the horizontal flipped state of this Game Object.
*
* A Game Object that is flipped horizontally will render inversed on the horizontal axis.
* Flipping always takes place from the middle of the texture and does not impact the scale value.
* If this Game Object has a physics body, it will not change the body. This is a rendering toggle only.
*
* @method Phaser.GameObjects.Components.Flip#setFlipX
* @since 3.0.0
*
* @param {boolean} value - The flipped state. `false` for no flip, or `true` to be flipped.
*
* @return {this} This Game Object instance.
*/
setFlipX: function(value) {
this.flipX = value;
return this;
},
/**
* Sets the vertical flipped state of this Game Object.
*
* @method Phaser.GameObjects.Components.Flip#setFlipY
* @since 3.0.0
*
* @param {boolean} value - The flipped state. `false` for no flip, or `true` to be flipped.
*
* @return {this} This Game Object instance.
*/
setFlipY: function(value) {
this.flipY = value;
return this;
},
/**
* Sets the horizontal and vertical flipped state of this Game Object.
*
* A Game Object that is flipped will render inversed on the flipped axis.
* Flipping always takes place from the middle of the texture and does not impact the scale value.
* If this Game Object has a physics body, it will not change the body. This is a rendering toggle only.
*
* @method Phaser.GameObjects.Components.Flip#setFlip
* @since 3.0.0
*
* @param {boolean} x - The horizontal flipped state. `false` for no flip, or `true` to be flipped.
* @param {boolean} y - The horizontal flipped state. `false` for no flip, or `true` to be flipped.
*
* @return {this} This Game Object instance.
*/
setFlip: function(x, y) {
this.flipX = x;
this.flipY = y;
return this;
},
/**
* Resets the horizontal and vertical flipped state of this Game Object back to their default un-flipped state.
*
* @method Phaser.GameObjects.Components.Flip#resetFlip
* @since 3.0.0
*
* @return {this} This Game Object instance.
*/
resetFlip: function() {
this.flipX = false;
this.flipY = false;
return this;
}
};
module2.exports = Flip;
}
),
/***/
8004: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Rectangle = __webpack_require__2(87841);
var RotateAround = __webpack_require__2(11520);
var Vector2 = __webpack_require__2(26099);
var GetBounds = {
/**
* Processes the bounds output vector before returning it.
*
* @method Phaser.GameObjects.Components.GetBounds#prepareBoundsOutput
* @private
* @since 3.18.0
*
* @generic {Phaser.Types.Math.Vector2Like} O - [output,$return]
*
* @param {Phaser.Types.Math.Vector2Like} output - An object to store the values in. If not provided a new Vector2 will be created.
* @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
*
* @return {Phaser.Types.Math.Vector2Like} The values stored in the output object.
*/
prepareBoundsOutput: function(output, includeParent) {
if (includeParent === void 0) {
includeParent = false;
}
if (this.rotation !== 0) {
RotateAround(output, this.x, this.y, this.rotation);
}
if (includeParent && this.parentContainer) {
var parentMatrix = this.parentContainer.getBoundsTransformMatrix();
parentMatrix.transformPoint(output.x, output.y, output);
}
return output;
},
/**
* Gets the center coordinate of this Game Object, regardless of origin.
*
* The returned point is calculated in local space and does not factor in any parent Containers,
* unless the `includeParent` argument is set to `true`.
*
* @method Phaser.GameObjects.Components.GetBounds#getCenter
* @since 3.0.0
*
* @generic {Phaser.Types.Math.Vector2Like} O - [output,$return]
*
* @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created.
* @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
*
* @return {Phaser.Types.Math.Vector2Like} The values stored in the output object.
*/
getCenter: function(output, includeParent) {
if (output === void 0) {
output = new Vector2();
}
output.x = this.x - this.displayWidth * this.originX + this.displayWidth / 2;
output.y = this.y - this.displayHeight * this.originY + this.displayHeight / 2;
return this.prepareBoundsOutput(output, includeParent);
},
/**
* Gets the top-left corner coordinate of this Game Object, regardless of origin.
*
* The returned point is calculated in local space and does not factor in any parent Containers,
* unless the `includeParent` argument is set to `true`.
*
* @method Phaser.GameObjects.Components.GetBounds#getTopLeft
* @since 3.0.0
*
* @generic {Phaser.Types.Math.Vector2Like} O - [output,$return]
*
* @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created.
* @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
*
* @return {Phaser.Types.Math.Vector2Like} The values stored in the output object.
*/
getTopLeft: function(output, includeParent) {
if (!output) {
output = new Vector2();
}
output.x = this.x - this.displayWidth * this.originX;
output.y = this.y - this.displayHeight * this.originY;
return this.prepareBoundsOutput(output, includeParent);
},
/**
* Gets the top-center coordinate of this Game Object, regardless of origin.
*
* The returned point is calculated in local space and does not factor in any parent Containers,
* unless the `includeParent` argument is set to `true`.
*
* @method Phaser.GameObjects.Components.GetBounds#getTopCenter
* @since 3.18.0
*
* @generic {Phaser.Types.Math.Vector2Like} O - [output,$return]
*
* @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created.
* @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
*
* @return {Phaser.Types.Math.Vector2Like} The values stored in the output object.
*/
getTopCenter: function(output, includeParent) {
if (!output) {
output = new Vector2();
}
output.x = this.x - this.displayWidth * this.originX + this.displayWidth / 2;
output.y = this.y - this.displayHeight * this.originY;
return this.prepareBoundsOutput(output, includeParent);
},
/**
* Gets the top-right corner coordinate of this Game Object, regardless of origin.
*
* The returned point is calculated in local space and does not factor in any parent Containers,
* unless the `includeParent` argument is set to `true`.
*
* @method Phaser.GameObjects.Components.GetBounds#getTopRight
* @since 3.0.0
*
* @generic {Phaser.Types.Math.Vector2Like} O - [output,$return]
*
* @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created.
* @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
*
* @return {Phaser.Types.Math.Vector2Like} The values stored in the output object.
*/
getTopRight: function(output, includeParent) {
if (!output) {
output = new Vector2();
}
output.x = this.x - this.displayWidth * this.originX + this.displayWidth;
output.y = this.y - this.displayHeight * this.originY;
return this.prepareBoundsOutput(output, includeParent);
},
/**
* Gets the left-center coordinate of this Game Object, regardless of origin.
*
* The returned point is calculated in local space and does not factor in any parent Containers,
* unless the `includeParent` argument is set to `true`.
*
* @method Phaser.GameObjects.Components.GetBounds#getLeftCenter
* @since 3.18.0
*
* @generic {Phaser.Types.Math.Vector2Like} O - [output,$return]
*
* @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created.
* @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
*
* @return {Phaser.Types.Math.Vector2Like} The values stored in the output object.
*/
getLeftCenter: function(output, includeParent) {
if (!output) {
output = new Vector2();
}
output.x = this.x - this.displayWidth * this.originX;
output.y = this.y - this.displayHeight * this.originY + this.displayHeight / 2;
return this.prepareBoundsOutput(output, includeParent);
},
/**
* Gets the right-center coordinate of this Game Object, regardless of origin.
*
* The returned point is calculated in local space and does not factor in any parent Containers,
* unless the `includeParent` argument is set to `true`.
*
* @method Phaser.GameObjects.Components.GetBounds#getRightCenter
* @since 3.18.0
*
* @generic {Phaser.Types.Math.Vector2Like} O - [output,$return]
*
* @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created.
* @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
*
* @return {Phaser.Types.Math.Vector2Like} The values stored in the output object.
*/
getRightCenter: function(output, includeParent) {
if (!output) {
output = new Vector2();
}
output.x = this.x - this.displayWidth * this.originX + this.displayWidth;
output.y = this.y - this.displayHeight * this.originY + this.displayHeight / 2;
return this.prepareBoundsOutput(output, includeParent);
},
/**
* Gets the bottom-left corner coordinate of this Game Object, regardless of origin.
*
* The returned point is calculated in local space and does not factor in any parent Containers,
* unless the `includeParent` argument is set to `true`.
*
* @method Phaser.GameObjects.Components.GetBounds#getBottomLeft
* @since 3.0.0
*
* @generic {Phaser.Types.Math.Vector2Like} O - [output,$return]
*
* @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created.
* @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
*
* @return {Phaser.Types.Math.Vector2Like} The values stored in the output object.
*/
getBottomLeft: function(output, includeParent) {
if (!output) {
output = new Vector2();
}
output.x = this.x - this.displayWidth * this.originX;
output.y = this.y - this.displayHeight * this.originY + this.displayHeight;
return this.prepareBoundsOutput(output, includeParent);
},
/**
* Gets the bottom-center coordinate of this Game Object, regardless of origin.
*
* The returned point is calculated in local space and does not factor in any parent Containers,
* unless the `includeParent` argument is set to `true`.
*
* @method Phaser.GameObjects.Components.GetBounds#getBottomCenter
* @since 3.18.0
*
* @generic {Phaser.Types.Math.Vector2Like} O - [output,$return]
*
* @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created.
* @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
*
* @return {Phaser.Types.Math.Vector2Like} The values stored in the output object.
*/
getBottomCenter: function(output, includeParent) {
if (!output) {
output = new Vector2();
}
output.x = this.x - this.displayWidth * this.originX + this.displayWidth / 2;
output.y = this.y - this.displayHeight * this.originY + this.displayHeight;
return this.prepareBoundsOutput(output, includeParent);
},
/**
* Gets the bottom-right corner coordinate of this Game Object, regardless of origin.
*
* The returned point is calculated in local space and does not factor in any parent Containers,
* unless the `includeParent` argument is set to `true`.
*
* @method Phaser.GameObjects.Components.GetBounds#getBottomRight
* @since 3.0.0
*
* @generic {Phaser.Types.Math.Vector2Like} O - [output,$return]
*
* @param {Phaser.Types.Math.Vector2Like} [output] - An object to store the values in. If not provided a new Vector2 will be created.
* @param {boolean} [includeParent=false] - If this Game Object has a parent Container, include it (and all other ancestors) in the resulting vector?
*
* @return {Phaser.Types.Math.Vector2Like} The values stored in the output object.
*/
getBottomRight: function(output, includeParent) {
if (!output) {
output = new Vector2();
}
output.x = this.x - this.displayWidth * this.originX + this.displayWidth;
output.y = this.y - this.displayHeight * this.originY + this.displayHeight;
return this.prepareBoundsOutput(output, includeParent);
},
/**
* Gets the bounds of this Game Object, regardless of origin.
*
* The values are stored and returned in a Rectangle, or Rectangle-like, object.
*
* @method Phaser.GameObjects.Components.GetBounds#getBounds
* @since 3.0.0
*
* @generic {Phaser.Geom.Rectangle} O - [output,$return]
*
* @param {(Phaser.Geom.Rectangle|object)} [output] - An object to store the values in. If not provided a new Rectangle will be created.
*
* @return {(Phaser.Geom.Rectangle|object)} The values stored in the output object.
*/
getBounds: function(output) {
if (output === void 0) {
output = new Rectangle();
}
var TLx, TLy, TRx, TRy, BLx, BLy, BRx, BRy;
if (this.parentContainer) {
var parentMatrix = this.parentContainer.getBoundsTransformMatrix();
this.getTopLeft(output);
parentMatrix.transformPoint(output.x, output.y, output);
TLx = output.x;
TLy = output.y;
this.getTopRight(output);
parentMatrix.transformPoint(output.x, output.y, output);
TRx = output.x;
TRy = output.y;
this.getBottomLeft(output);
parentMatrix.transformPoint(output.x, output.y, output);
BLx = output.x;
BLy = output.y;
this.getBottomRight(output);
parentMatrix.transformPoint(output.x, output.y, output);
BRx = output.x;
BRy = output.y;
} else {
this.getTopLeft(output);
TLx = output.x;
TLy = output.y;
this.getTopRight(output);
TRx = output.x;
TRy = output.y;
this.getBottomLeft(output);
BLx = output.x;
BLy = output.y;
this.getBottomRight(output);
BRx = output.x;
BRy = output.y;
}
output.x = Math.min(TLx, TRx, BLx, BRx);
output.y = Math.min(TLy, TRy, BLy, BRy);
output.width = Math.max(TLx, TRx, BLx, BRx) - output.x;
output.height = Math.max(TLy, TRy, BLy, BRy) - output.y;
return output;
}
};
module2.exports = GetBounds;
}
),
/***/
8573: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BitmapMask = __webpack_require__2(6858);
var GeometryMask = __webpack_require__2(80661);
var Mask = {
/**
* The Mask this Game Object is using during render.
*
* @name Phaser.GameObjects.Components.Mask#mask
* @type {Phaser.Display.Masks.BitmapMask|Phaser.Display.Masks.GeometryMask}
* @since 3.0.0
*/
mask: null,
/**
* Sets the mask that this Game Object will use to render with.
*
* The mask must have been previously created and can be either a GeometryMask or a BitmapMask.
* Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas.
*
* If a mask is already set on this Game Object it will be immediately replaced.
*
* Masks are positioned in global space and are not relative to the Game Object to which they
* are applied. The reason for this is that multiple Game Objects can all share the same mask.
*
* Masks have no impact on physics or input detection. They are purely a rendering component
* that allows you to limit what is visible during the render pass.
*
* @method Phaser.GameObjects.Components.Mask#setMask
* @since 3.6.2
*
* @param {Phaser.Display.Masks.BitmapMask|Phaser.Display.Masks.GeometryMask} mask - The mask this Game Object will use when rendering.
*
* @return {this} This Game Object instance.
*/
setMask: function(mask) {
this.mask = mask;
return this;
},
/**
* Clears the mask that this Game Object was using.
*
* @method Phaser.GameObjects.Components.Mask#clearMask
* @since 3.6.2
*
* @param {boolean} [destroyMask=false] - Destroy the mask before clearing it?
*
* @return {this} This Game Object instance.
*/
clearMask: function(destroyMask) {
if (destroyMask === void 0) {
destroyMask = false;
}
if (destroyMask && this.mask) {
this.mask.destroy();
}
this.mask = null;
return this;
},
/**
* Creates and returns a Bitmap Mask. This mask can be used by any Game Object,
* including this one, or a Dynamic Texture.
*
* Note: Bitmap Masks only work on WebGL. Geometry Masks work on both WebGL and Canvas.
*
* To create the mask you need to pass in a reference to a renderable Game Object.
* A renderable Game Object is one that uses a texture to render with, such as an
* Image, Sprite, Render Texture or BitmapText.
*
* If you do not provide a renderable object, and this Game Object has a texture,
* it will use itself as the object. This means you can call this method to create
* a Bitmap Mask from any renderable texture-based Game Object.
*
* @method Phaser.GameObjects.Components.Mask#createBitmapMask
* @since 3.6.2
*
* @generic {Phaser.GameObjects.GameObject} G
* @generic {Phaser.Textures.DynamicTexture} T
* @genericUse {(G|T|null)} [maskObject]
*
* @param {(Phaser.GameObjects.GameObject|Phaser.Textures.DynamicTexture)} [maskObject] - The Game Object or Dynamic Texture that will be used as the mask. If `null` it will generate an Image Game Object using the rest of the arguments.
* @param {number} [x] - If creating a Game Object, the horizontal position in the world.
* @param {number} [y] - If creating a Game Object, the vertical position in the world.
* @param {(string|Phaser.Textures.Texture)} [texture] - If creating a Game Object, the key, or instance of the Texture it will use to render with, as stored in the Texture Manager.
* @param {(string|number|Phaser.Textures.Frame)} [frame] - If creating a Game Object, an optional frame from the Texture this Game Object is rendering with.
*
* @return {Phaser.Display.Masks.BitmapMask} This Bitmap Mask that was created.
*/
createBitmapMask: function(maskObject, x, y, texture, frame) {
if (maskObject === void 0 && (this.texture || this.shader || this.geom)) {
maskObject = this;
}
return new BitmapMask(this.scene, maskObject, x, y, texture, frame);
},
/**
* Creates and returns a Geometry Mask. This mask can be used by any Game Object,
* including this one.
*
* To create the mask you need to pass in a reference to a Graphics Game Object.
*
* If you do not provide a graphics object, and this Game Object is an instance
* of a Graphics object, then it will use itself to create the mask.
*
* This means you can call this method to create a Geometry Mask from any Graphics Game Object.
*
* @method Phaser.GameObjects.Components.Mask#createGeometryMask
* @since 3.6.2
*
* @generic {Phaser.GameObjects.Graphics} G
* @generic {Phaser.GameObjects.Shape} S
* @genericUse {(G|S)} [graphics]
*
* @param {Phaser.GameObjects.Graphics|Phaser.GameObjects.Shape} [graphics] - A Graphics Game Object, or any kind of Shape Game Object. The geometry within it will be used as the mask.
*
* @return {Phaser.Display.Masks.GeometryMask} This Geometry Mask that was created.
*/
createGeometryMask: function(graphics) {
if (graphics === void 0 && (this.type === "Graphics" || this.geom)) {
graphics = this;
}
return new GeometryMask(this.scene, graphics);
}
};
module2.exports = Mask;
}
),
/***/
27387: (
/***/
(module2) => {
var Origin = {
/**
* A property indicating that a Game Object has this component.
*
* @name Phaser.GameObjects.Components.Origin#_originComponent
* @type {boolean}
* @private
* @default true
* @since 3.2.0
*/
_originComponent: true,
/**
* The horizontal origin of this Game Object.
* The origin maps the relationship between the size and position of the Game Object.
* The default value is 0.5, meaning all Game Objects are positioned based on their center.
* Setting the value to 0 means the position now relates to the left of the Game Object.
* Set this value with `setOrigin()`.
*
* @name Phaser.GameObjects.Components.Origin#originX
* @type {number}
* @readonly
* @default 0.5
* @since 3.0.0
*/
originX: 0.5,
/**
* The vertical origin of this Game Object.
* The origin maps the relationship between the size and position of the Game Object.
* The default value is 0.5, meaning all Game Objects are positioned based on their center.
* Setting the value to 0 means the position now relates to the top of the Game Object.
* Set this value with `setOrigin()`.
*
* @name Phaser.GameObjects.Components.Origin#originY
* @type {number}
* @readonly
* @default 0.5
* @since 3.0.0
*/
originY: 0.5,
// private + read only
_displayOriginX: 0,
_displayOriginY: 0,
/**
* The horizontal display origin of this Game Object.
* The origin is a normalized value between 0 and 1.
* The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin.
*
* @name Phaser.GameObjects.Components.Origin#displayOriginX
* @type {number}
* @since 3.0.0
*/
displayOriginX: {
get: function() {
return this._displayOriginX;
},
set: function(value) {
this._displayOriginX = value;
this.originX = value / this.width;
}
},
/**
* The vertical display origin of this Game Object.
* The origin is a normalized value between 0 and 1.
* The displayOrigin is a pixel value, based on the size of the Game Object combined with the origin.
*
* @name Phaser.GameObjects.Components.Origin#displayOriginY
* @type {number}
* @since 3.0.0
*/
displayOriginY: {
get: function() {
return this._displayOriginY;
},
set: function(value) {
this._displayOriginY = value;
this.originY = value / this.height;
}
},
/**
* Sets the origin of this Game Object.
*
* The values are given in the range 0 to 1.
*
* @method Phaser.GameObjects.Components.Origin#setOrigin
* @since 3.0.0
*
* @param {number} [x=0.5] - The horizontal origin value.
* @param {number} [y=x] - The vertical origin value. If not defined it will be set to the value of `x`.
*
* @return {this} This Game Object instance.
*/
setOrigin: function(x, y) {
if (x === void 0) {
x = 0.5;
}
if (y === void 0) {
y = x;
}
this.originX = x;
this.originY = y;
return this.updateDisplayOrigin();
},
/**
* Sets the origin of this Game Object based on the Pivot values in its Frame.
*
* @method Phaser.GameObjects.Components.Origin#setOriginFromFrame
* @since 3.0.0
*
* @return {this} This Game Object instance.
*/
setOriginFromFrame: function() {
if (!this.frame || !this.frame.customPivot) {
return this.setOrigin();
} else {
this.originX = this.frame.pivotX;
this.originY = this.frame.pivotY;
}
return this.updateDisplayOrigin();
},
/**
* Sets the display origin of this Game Object.
* The difference between this and setting the origin is that you can use pixel values for setting the display origin.
*
* @method Phaser.GameObjects.Components.Origin#setDisplayOrigin
* @since 3.0.0
*
* @param {number} [x=0] - The horizontal display origin value.
* @param {number} [y=x] - The vertical display origin value. If not defined it will be set to the value of `x`.
*
* @return {this} This Game Object instance.
*/
setDisplayOrigin: function(x, y) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = x;
}
this.displayOriginX = x;
this.displayOriginY = y;
return this;
},
/**
* Updates the Display Origin cached values internally stored on this Game Object.
* You don't usually call this directly, but it is exposed for edge-cases where you may.
*
* @method Phaser.GameObjects.Components.Origin#updateDisplayOrigin
* @since 3.0.0
*
* @return {this} This Game Object instance.
*/
updateDisplayOrigin: function() {
this._displayOriginX = this.originX * this.width;
this._displayOriginY = this.originY * this.height;
return this;
}
};
module2.exports = Origin;
}
),
/***/
37640: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var DegToRad = __webpack_require__2(39506);
var GetBoolean = __webpack_require__2(57355);
var GetValue = __webpack_require__2(35154);
var TWEEN_CONST = __webpack_require__2(86353);
var Vector2 = __webpack_require__2(26099);
var PathFollower = {
/**
* The Path this PathFollower is following. It can only follow one Path at a time.
*
* @name Phaser.GameObjects.Components.PathFollower#path
* @type {Phaser.Curves.Path}
* @since 3.0.0
*/
path: null,
/**
* Should the PathFollower automatically rotate to point in the direction of the Path?
*
* @name Phaser.GameObjects.Components.PathFollower#rotateToPath
* @type {boolean}
* @default false
* @since 3.0.0
*/
rotateToPath: false,
/**
* If the PathFollower is rotating to match the Path (@see Phaser.GameObjects.PathFollower#rotateToPath)
* this value is added to the rotation value. This allows you to rotate objects to a path but control
* the angle of the rotation as well.
*
* @name Phaser.GameObjects.PathFollower#pathRotationOffset
* @type {number}
* @default 0
* @since 3.0.0
*/
pathRotationOffset: 0,
/**
* An additional vector to add to the PathFollowers position, allowing you to offset it from the
* Path coordinates.
*
* @name Phaser.GameObjects.PathFollower#pathOffset
* @type {Phaser.Math.Vector2}
* @since 3.0.0
*/
pathOffset: null,
/**
* A Vector2 that stores the current point of the path the follower is on.
*
* @name Phaser.GameObjects.PathFollower#pathVector
* @type {Phaser.Math.Vector2}
* @since 3.0.0
*/
pathVector: null,
/**
* The distance the follower has traveled from the previous point to the current one, at the last update.
*
* @name Phaser.GameObjects.PathFollower#pathDelta
* @type {Phaser.Math.Vector2}
* @since 3.23.0
*/
pathDelta: null,
/**
* The Tween used for following the Path.
*
* @name Phaser.GameObjects.PathFollower#pathTween
* @type {Phaser.Tweens.Tween}
* @since 3.0.0
*/
pathTween: null,
/**
* Settings for the PathFollower.
*
* @name Phaser.GameObjects.PathFollower#pathConfig
* @type {?Phaser.Types.GameObjects.PathFollower.PathConfig}
* @default null
* @since 3.0.0
*/
pathConfig: null,
/**
* Records the direction of the follower so it can change direction.
*
* @name Phaser.GameObjects.PathFollower#_prevDirection
* @type {number}
* @private
* @since 3.0.0
*/
_prevDirection: TWEEN_CONST.PLAYING_FORWARD,
/**
* Set the Path that this PathFollower should follow.
*
* Optionally accepts {@link Phaser.Types.GameObjects.PathFollower.PathConfig} settings.
*
* @method Phaser.GameObjects.Components.PathFollower#setPath
* @since 3.0.0
*
* @param {Phaser.Curves.Path} path - The Path this PathFollower is following. It can only follow one Path at a time.
* @param {(number|Phaser.Types.GameObjects.PathFollower.PathConfig|Phaser.Types.Tweens.NumberTweenBuilderConfig)} [config] - Settings for the PathFollower.
*
* @return {this} This Game Object.
*/
setPath: function(path, config) {
if (config === void 0) {
config = this.pathConfig;
}
var tween = this.pathTween;
if (tween && tween.isPlaying()) {
tween.stop();
}
this.path = path;
if (config) {
this.startFollow(config);
}
return this;
},
/**
* Set whether the PathFollower should automatically rotate to point in the direction of the Path.
*
* @method Phaser.GameObjects.Components.PathFollower#setRotateToPath
* @since 3.0.0
*
* @param {boolean} value - Whether the PathFollower should automatically rotate to point in the direction of the Path.
* @param {number} [offset=0] - Rotation offset in degrees.
*
* @return {this} This Game Object.
*/
setRotateToPath: function(value, offset) {
if (offset === void 0) {
offset = 0;
}
this.rotateToPath = value;
this.pathRotationOffset = offset;
return this;
},
/**
* Is this PathFollower actively following a Path or not?
*
* To be considered as `isFollowing` it must be currently moving on a Path, and not paused.
*
* @method Phaser.GameObjects.Components.PathFollower#isFollowing
* @since 3.0.0
*
* @return {boolean} `true` is this PathFollower is actively following a Path, otherwise `false`.
*/
isFollowing: function() {
var tween = this.pathTween;
return tween && tween.isPlaying();
},
/**
* Starts this PathFollower following its given Path.
*
* @method Phaser.GameObjects.Components.PathFollower#startFollow
* @since 3.3.0
*
* @param {(number|Phaser.Types.GameObjects.PathFollower.PathConfig|Phaser.Types.Tweens.NumberTweenBuilderConfig)} [config={}] - The duration of the follow, or a PathFollower config object.
* @param {number} [startAt=0] - Optional start position of the follow, between 0 and 1.
*
* @return {this} This Game Object.
*/
startFollow: function(config, startAt) {
if (config === void 0) {
config = {};
}
if (startAt === void 0) {
startAt = 0;
}
var tween = this.pathTween;
if (tween && tween.isPlaying()) {
tween.stop();
}
if (typeof config === "number") {
config = { duration: config };
}
config.from = GetValue(config, "from", 0);
config.to = GetValue(config, "to", 1);
var positionOnPath = GetBoolean(config, "positionOnPath", false);
this.rotateToPath = GetBoolean(config, "rotateToPath", false);
this.pathRotationOffset = GetValue(config, "rotationOffset", 0);
var seek = GetValue(config, "startAt", startAt);
if (seek) {
config.onStart = function(tween2) {
var tweenData = tween2.data[0];
tweenData.progress = seek;
tweenData.elapsed = tweenData.duration * seek;
var v = tweenData.ease(tweenData.progress);
tweenData.current = tweenData.start + (tweenData.end - tweenData.start) * v;
tweenData.setTargetValue();
};
}
if (!this.pathOffset) {
this.pathOffset = new Vector2(this.x, this.y);
}
if (!this.pathVector) {
this.pathVector = new Vector2();
}
if (!this.pathDelta) {
this.pathDelta = new Vector2();
}
this.pathDelta.reset();
config.persist = true;
this.pathTween = this.scene.sys.tweens.addCounter(config);
this.path.getStartPoint(this.pathOffset);
if (positionOnPath) {
this.x = this.pathOffset.x;
this.y = this.pathOffset.y;
}
this.pathOffset.x = this.x - this.pathOffset.x;
this.pathOffset.y = this.y - this.pathOffset.y;
this._prevDirection = TWEEN_CONST.PLAYING_FORWARD;
if (this.rotateToPath) {
var nextPoint = this.path.getPoint(0.1);
this.rotation = Math.atan2(nextPoint.y - this.y, nextPoint.x - this.x) + DegToRad(this.pathRotationOffset);
}
this.pathConfig = config;
return this;
},
/**
* Pauses this PathFollower. It will still continue to render, but it will remain motionless at the
* point on the Path at which you paused it.
*
* @method Phaser.GameObjects.Components.PathFollower#pauseFollow
* @since 3.3.0
*
* @return {this} This Game Object.
*/
pauseFollow: function() {
var tween = this.pathTween;
if (tween && tween.isPlaying()) {
tween.pause();
}
return this;
},
/**
* Resumes a previously paused PathFollower.
*
* If the PathFollower was not paused this has no effect.
*
* @method Phaser.GameObjects.Components.PathFollower#resumeFollow
* @since 3.3.0
*
* @return {this} This Game Object.
*/
resumeFollow: function() {
var tween = this.pathTween;
if (tween && tween.isPaused()) {
tween.resume();
}
return this;
},
/**
* Stops this PathFollower from following the path any longer.
*
* This will invoke any 'stop' conditions that may exist on the Path, or for the follower.
*
* @method Phaser.GameObjects.Components.PathFollower#stopFollow
* @since 3.3.0
*
* @return {this} This Game Object.
*/
stopFollow: function() {
var tween = this.pathTween;
if (tween && tween.isPlaying()) {
tween.stop();
}
return this;
},
/**
* Internal update handler that advances this PathFollower along the path.
*
* Called automatically by the Scene step, should not typically be called directly.
*
* @method Phaser.GameObjects.Components.PathFollower#pathUpdate
* @since 3.17.0
*/
pathUpdate: function() {
var tween = this.pathTween;
if (tween && tween.data) {
var tweenData = tween.data[0];
var pathDelta = this.pathDelta;
var pathVector = this.pathVector;
pathDelta.copy(pathVector).negate();
if (tweenData.state === TWEEN_CONST.COMPLETE) {
this.path.getPoint(tweenData.end, pathVector);
pathDelta.add(pathVector);
pathVector.add(this.pathOffset);
this.setPosition(pathVector.x, pathVector.y);
return;
} else if (tweenData.state !== TWEEN_CONST.PLAYING_FORWARD && tweenData.state !== TWEEN_CONST.PLAYING_BACKWARD) {
return;
}
this.path.getPoint(tween.getValue(), pathVector);
pathDelta.add(pathVector);
pathVector.add(this.pathOffset);
var oldX = this.x;
var oldY = this.y;
this.setPosition(pathVector.x, pathVector.y);
var speedX = this.x - oldX;
var speedY = this.y - oldY;
if (speedX === 0 && speedY === 0) {
return;
}
if (tweenData.state !== this._prevDirection) {
this._prevDirection = tweenData.state;
return;
}
if (this.rotateToPath) {
this.rotation = Math.atan2(speedY, speedX) + DegToRad(this.pathRotationOffset);
}
}
}
};
module2.exports = PathFollower;
}
),
/***/
72699: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var DeepCopy = __webpack_require__2(62644);
var Pipeline = {
/**
* The initial WebGL pipeline of this Game Object.
*
* If you call `resetPipeline` on this Game Object, the pipeline is reset to this default.
*
* @name Phaser.GameObjects.Components.Pipeline#defaultPipeline
* @type {Phaser.Renderer.WebGL.WebGLPipeline}
* @default null
* @webglOnly
* @since 3.0.0
*/
defaultPipeline: null,
/**
* The current WebGL pipeline of this Game Object.
*
* @name Phaser.GameObjects.Components.Pipeline#pipeline
* @type {Phaser.Renderer.WebGL.WebGLPipeline}
* @default null
* @webglOnly
* @since 3.0.0
*/
pipeline: null,
/**
* An object to store pipeline specific data in, to be read by the pipelines this Game Object uses.
*
* @name Phaser.GameObjects.Components.Pipeline#pipelineData
* @type {object}
* @webglOnly
* @since 3.50.0
*/
pipelineData: null,
/**
* Sets the initial WebGL Pipeline of this Game Object.
*
* This should only be called during the instantiation of the Game Object. After that, use `setPipeline`.
*
* @method Phaser.GameObjects.Components.Pipeline#initPipeline
* @webglOnly
* @since 3.0.0
*
* @param {(string|Phaser.Renderer.WebGL.WebGLPipeline)} [pipeline] - Either the string-based name of the pipeline, or a pipeline instance to set.
*
* @return {boolean} `true` if the pipeline was set successfully, otherwise `false`.
*/
initPipeline: function(pipeline) {
this.pipelineData = {};
var renderer = this.scene.sys.renderer;
if (!renderer) {
return false;
}
var pipelines = renderer.pipelines;
if (pipelines) {
if (pipeline === void 0) {
pipeline = pipelines.default;
}
var instance = pipelines.get(pipeline);
if (instance) {
this.defaultPipeline = instance;
this.pipeline = instance;
return true;
}
}
return false;
},
/**
* Sets the main WebGL Pipeline of this Game Object.
*
* Also sets the `pipelineData` property, if the parameter is given.
*
* @method Phaser.GameObjects.Components.Pipeline#setPipeline
* @webglOnly
* @since 3.0.0
*
* @param {(string|Phaser.Renderer.WebGL.WebGLPipeline)} pipeline - Either the string-based name of the pipeline, or a pipeline instance to set.
* @param {object} [pipelineData] - Optional pipeline data object that is set in to the `pipelineData` property of this Game Object.
* @param {boolean} [copyData=true] - Should the pipeline data object be _deep copied_ into the `pipelineData` property of this Game Object? If `false` it will be set by reference instead.
*
* @return {this} This Game Object instance.
*/
setPipeline: function(pipeline, pipelineData, copyData) {
var renderer = this.scene.sys.renderer;
if (!renderer) {
return this;
}
var pipelines = renderer.pipelines;
if (pipelines) {
var instance = pipelines.get(pipeline);
if (instance) {
this.pipeline = instance;
}
if (pipelineData) {
this.pipelineData = copyData ? DeepCopy(pipelineData) : pipelineData;
}
}
return this;
},
/**
* Adds an entry to the `pipelineData` object belonging to this Game Object.
*
* If the 'key' already exists, its value is updated. If it doesn't exist, it is created.
*
* If `value` is undefined, and `key` exists, `key` is removed from the data object.
*
* @method Phaser.GameObjects.Components.Pipeline#setPipelineData
* @webglOnly
* @since 3.50.0
*
* @param {string} key - The key of the pipeline data to set, update, or delete.
* @param {any} [value] - The value to be set with the key. If `undefined` then `key` will be deleted from the object.
*
* @return {this} This Game Object instance.
*/
setPipelineData: function(key, value) {
var data = this.pipelineData;
if (value === void 0) {
delete data[key];
} else {
data[key] = value;
}
return this;
},
/**
* Resets the WebGL Pipeline of this Game Object back to the default it was created with.
*
* @method Phaser.GameObjects.Components.Pipeline#resetPipeline
* @webglOnly
* @since 3.0.0
*
* @param {boolean} [resetData=false] - Reset the `pipelineData` object to being an empty object?
*
* @return {boolean} `true` if the pipeline was reset successfully, otherwise `false`.
*/
resetPipeline: function(resetData) {
if (resetData === void 0) {
resetData = false;
}
this.pipeline = this.defaultPipeline;
if (resetData) {
this.pipelineData = {};
}
return this.pipeline !== null;
},
/**
* Gets the name of the WebGL Pipeline this Game Object is currently using.
*
* @method Phaser.GameObjects.Components.Pipeline#getPipelineName
* @webglOnly
* @since 3.0.0
*
* @return {?string} The string-based name of the pipeline being used by this Game Object, or null.
*/
getPipelineName: function() {
return this.pipeline === null ? null : this.pipeline.name;
}
};
module2.exports = Pipeline;
}
),
/***/
17581: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var DeepCopy = __webpack_require__2(62644);
var FX = __webpack_require__2(47059);
var SpliceOne = __webpack_require__2(19133);
var PostPipeline = {
/**
* Does this Game Object have any Post Pipelines set?
*
* @name Phaser.GameObjects.Components.PostPipeline#hasPostPipeline
* @type {boolean}
* @webglOnly
* @since 3.60.0
*/
hasPostPipeline: false,
/**
* The WebGL Post FX Pipelines this Game Object uses for post-render effects.
*
* The pipelines are processed in the order in which they appear in this array.
*
* If you modify this array directly, be sure to set the
* `hasPostPipeline` property accordingly.
*
* @name Phaser.GameObjects.Components.PostPipeline#postPipelines
* @type {Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[]}
* @webglOnly
* @since 3.60.0
*/
postPipelines: null,
/**
* An object to store pipeline specific data in, to be read by the pipelines this Game Object uses.
*
* @name Phaser.GameObjects.Components.PostPipeline#postPipelineData
* @type {object}
* @webglOnly
* @since 3.60.0
*/
postPipelineData: null,
/**
* The Pre FX component of this Game Object.
*
* This component allows you to apply a variety of built-in effects to this Game Object, such
* as glow, blur, bloom, displacements, vignettes and more. You access them via this property,
* for example:
*
* ```js
* const player = this.add.sprite();
* player.preFX.addBloom();
* ```
*
* Only the following Game Objects support Pre FX:
*
* * Image
* * Sprite
* * TileSprite
* * Text
* * RenderTexture
* * Video
*
* All FX are WebGL only and do not have Canvas counterparts.
*
* Please see the FX Class for more details and available methods.
*
* @name Phaser.GameObjects.Components.PostPipeline#preFX
* @type {?Phaser.GameObjects.Components.FX}
* @webglOnly
* @since 3.60.0
*/
preFX: null,
/**
* The Post FX component of this Game Object.
*
* This component allows you to apply a variety of built-in effects to this Game Object, such
* as glow, blur, bloom, displacements, vignettes and more. You access them via this property,
* for example:
*
* ```js
* const player = this.add.sprite();
* player.postFX.addBloom();
* ```
*
* All FX are WebGL only and do not have Canvas counterparts.
*
* Please see the FX Class for more details and available methods.
*
* This property is always `null` until the `initPostPipeline` method is called.
*
* @name Phaser.GameObjects.Components.PostPipeline#postFX
* @type {Phaser.GameObjects.Components.FX}
* @webglOnly
* @since 3.60.0
*/
postFX: null,
/**
* This should only be called during the instantiation of the Game Object.
*
* It is called by default by all core Game Objects and doesn't need
* calling again.
*
* After that, use `setPostPipeline`.
*
* @method Phaser.GameObjects.Components.PostPipeline#initPostPipeline
* @webglOnly
* @since 3.60.0
*
* @param {boolean} [preFX=false] - Does this Game Object support Pre FX?
*/
initPostPipeline: function(preFX) {
this.postPipelines = [];
this.postPipelineData = {};
this.postFX = new FX(this, true);
if (preFX) {
this.preFX = new FX(this, false);
}
},
/**
* Sets one, or more, Post Pipelines on this Game Object.
*
* Post Pipelines are invoked after this Game Object has rendered to its target and
* are commonly used for post-fx.
*
* The post pipelines are appended to the `postPipelines` array belonging to this
* Game Object. When the renderer processes this Game Object, it iterates through the post
* pipelines in the order in which they appear in the array. If you are stacking together
* multiple effects, be aware that the order is important.
*
* If you call this method multiple times, the new pipelines will be appended to any existing
* post pipelines already set. Use the `resetPostPipeline` method to clear them first, if required.
*
* You can optionally also set the `postPipelineData` property, if the parameter is given.
*
* @method Phaser.GameObjects.Components.PostPipeline#setPostPipeline
* @webglOnly
* @since 3.60.0
*
* @param {(string|string[]|function|function[]|Phaser.Renderer.WebGL.Pipelines.PostFXPipeline|Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[])} pipelines - Either the string-based name of the pipeline, or a pipeline instance, or class, or an array of them.
* @param {object} [pipelineData] - Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object.
* @param {boolean} [copyData=true] - Should the pipeline data object be _deep copied_ into the `postPipelineData` property of this Game Object? If `false` it will be set by reference instead.
*
* @return {this} This Game Object instance.
*/
setPostPipeline: function(pipelines, pipelineData, copyData) {
var renderer = this.scene.sys.renderer;
if (!renderer) {
return this;
}
var pipelineManager = renderer.pipelines;
if (pipelineManager) {
if (!Array.isArray(pipelines)) {
pipelines = [pipelines];
}
for (var i = 0; i < pipelines.length; i++) {
var instance = pipelineManager.getPostPipeline(pipelines[i], this, pipelineData);
if (instance) {
this.postPipelines.push(instance);
}
}
if (pipelineData) {
this.postPipelineData = copyData ? DeepCopy(pipelineData) : pipelineData;
}
}
this.hasPostPipeline = this.postPipelines.length > 0;
return this;
},
/**
* Adds an entry to the `postPipelineData` object belonging to this Game Object.
*
* If the 'key' already exists, its value is updated. If it doesn't exist, it is created.
*
* If `value` is undefined, and `key` exists, `key` is removed from the data object.
*
* @method Phaser.GameObjects.Components.PostPipeline#setPostPipelineData
* @webglOnly
* @since 3.60.0
*
* @param {string} key - The key of the pipeline data to set, update, or delete.
* @param {any} [value] - The value to be set with the key. If `undefined` then `key` will be deleted from the object.
*
* @return {this} This Game Object instance.
*/
setPostPipelineData: function(key, value) {
var data = this.postPipelineData;
if (value === void 0) {
delete data[key];
} else {
data[key] = value;
}
return this;
},
/**
* Gets a Post Pipeline instance from this Game Object, based on the given name, and returns it.
*
* @method Phaser.GameObjects.Components.PostPipeline#getPostPipeline
* @webglOnly
* @since 3.60.0
*
* @param {(string|function|Phaser.Renderer.WebGL.Pipelines.PostFXPipeline)} pipeline - The string-based name of the pipeline, or a pipeline class.
*
* @return {(Phaser.Renderer.WebGL.Pipelines.PostFXPipeline|Phaser.Renderer.WebGL.Pipelines.PostFXPipeline[])} An array of all the Post Pipelines matching the name. This array will be empty if there was no match. If there was only one single match, that pipeline is returned directly, not in an array.
*/
getPostPipeline: function(pipeline) {
var isString = typeof pipeline === "string";
var pipelines = this.postPipelines;
var results = [];
for (var i = 0; i < pipelines.length; i++) {
var instance = pipelines[i];
if (isString && instance.name === pipeline || !isString && instance instanceof pipeline) {
results.push(instance);
}
}
return results.length === 1 ? results[0] : results;
},
/**
* Resets the WebGL Post Pipelines of this Game Object. It does this by calling
* the `destroy` method on each post pipeline and then clearing the local array.
*
* @method Phaser.GameObjects.Components.PostPipeline#resetPostPipeline
* @webglOnly
* @since 3.60.0
*
* @param {boolean} [resetData=false] - Reset the `postPipelineData` object to being an empty object?
*/
resetPostPipeline: function(resetData) {
if (resetData === void 0) {
resetData = false;
}
var pipelines = this.postPipelines;
for (var i = 0; i < pipelines.length; i++) {
pipelines[i].destroy();
}
this.postPipelines = [];
this.hasPostPipeline = false;
if (resetData) {
this.postPipelineData = {};
}
},
/**
* Removes a type of Post Pipeline instances from this Game Object, based on the given name, and destroys them.
*
* If you wish to remove all Post Pipelines use the `resetPostPipeline` method instead.
*
* @method Phaser.GameObjects.Components.PostPipeline#removePostPipeline
* @webglOnly
* @since 3.60.0
*
* @param {string|Phaser.Renderer.WebGL.Pipelines.PostFXPipeline} pipeline - The string-based name of the pipeline, or a pipeline class.
*
* @return {this} This Game Object.
*/
removePostPipeline: function(pipeline) {
var isString = typeof pipeline === "string";
var pipelines = this.postPipelines;
for (var i = pipelines.length - 1; i >= 0; i--) {
var instance = pipelines[i];
if (isString && instance.name === pipeline || !isString && instance === pipeline) {
instance.destroy();
SpliceOne(pipelines, i);
}
}
this.hasPostPipeline = this.postPipelines.length > 0;
return this;
},
/**
* Removes all Pre and Post FX Controllers from this Game Object.
*
* If you wish to remove a single controller, use the `preFX.remove(fx)` or `postFX.remove(fx)` methods instead.
*
* If you wish to clear a single controller, use the `preFX.clear()` or `postFX.clear()` methods instead.
*
* @method Phaser.GameObjects.Components.PostPipeline#clearFX
* @webglOnly
* @since 3.60.0
*
* @return {this} This Game Object.
*/
clearFX: function() {
if (this.preFX) {
this.preFX.clear();
}
if (this.postFX) {
this.postFX.clear();
}
return this;
}
};
module2.exports = PostPipeline;
}
),
/***/
80227: (
/***/
(module2) => {
var ScrollFactor = {
/**
* The horizontal scroll factor of this Game Object.
*
* The scroll factor controls the influence of the movement of a Camera upon this Game Object.
*
* When a camera scrolls it will change the location at which this Game Object is rendered on-screen.
* It does not change the Game Objects actual position values.
*
* A value of 1 means it will move exactly in sync with a camera.
* A value of 0 means it will not move at all, even if the camera moves.
* Other values control the degree to which the camera movement is mapped to this Game Object.
*
* Please be aware that scroll factor values other than 1 are not taken in to consideration when
* calculating physics collisions. Bodies always collide based on their world position, but changing
* the scroll factor is a visual adjustment to where the textures are rendered, which can offset
* them from physics bodies if not accounted for in your code.
*
* @name Phaser.GameObjects.Components.ScrollFactor#scrollFactorX
* @type {number}
* @default 1
* @since 3.0.0
*/
scrollFactorX: 1,
/**
* The vertical scroll factor of this Game Object.
*
* The scroll factor controls the influence of the movement of a Camera upon this Game Object.
*
* When a camera scrolls it will change the location at which this Game Object is rendered on-screen.
* It does not change the Game Objects actual position values.
*
* A value of 1 means it will move exactly in sync with a camera.
* A value of 0 means it will not move at all, even if the camera moves.
* Other values control the degree to which the camera movement is mapped to this Game Object.
*
* Please be aware that scroll factor values other than 1 are not taken in to consideration when
* calculating physics collisions. Bodies always collide based on their world position, but changing
* the scroll factor is a visual adjustment to where the textures are rendered, which can offset
* them from physics bodies if not accounted for in your code.
*
* @name Phaser.GameObjects.Components.ScrollFactor#scrollFactorY
* @type {number}
* @default 1
* @since 3.0.0
*/
scrollFactorY: 1,
/**
* Sets the scroll factor of this Game Object.
*
* The scroll factor controls the influence of the movement of a Camera upon this Game Object.
*
* When a camera scrolls it will change the location at which this Game Object is rendered on-screen.
* It does not change the Game Objects actual position values.
*
* A value of 1 means it will move exactly in sync with a camera.
* A value of 0 means it will not move at all, even if the camera moves.
* Other values control the degree to which the camera movement is mapped to this Game Object.
*
* Please be aware that scroll factor values other than 1 are not taken in to consideration when
* calculating physics collisions. Bodies always collide based on their world position, but changing
* the scroll factor is a visual adjustment to where the textures are rendered, which can offset
* them from physics bodies if not accounted for in your code.
*
* @method Phaser.GameObjects.Components.ScrollFactor#setScrollFactor
* @since 3.0.0
*
* @param {number} x - The horizontal scroll factor of this Game Object.
* @param {number} [y=x] - The vertical scroll factor of this Game Object. If not set it will use the `x` value.
*
* @return {this} This Game Object instance.
*/
setScrollFactor: function(x, y) {
if (y === void 0) {
y = x;
}
this.scrollFactorX = x;
this.scrollFactorY = y;
return this;
}
};
module2.exports = ScrollFactor;
}
),
/***/
16736: (
/***/
(module2) => {
var Size = {
/**
* A property indicating that a Game Object has this component.
*
* @name Phaser.GameObjects.Components.Size#_sizeComponent
* @type {boolean}
* @private
* @default true
* @since 3.2.0
*/
_sizeComponent: true,
/**
* The native (un-scaled) width of this Game Object.
*
* Changing this value will not change the size that the Game Object is rendered in-game.
* For that you need to either set the scale of the Game Object (`setScale`) or use
* the `displayWidth` property.
*
* @name Phaser.GameObjects.Components.Size#width
* @type {number}
* @since 3.0.0
*/
width: 0,
/**
* The native (un-scaled) height of this Game Object.
*
* Changing this value will not change the size that the Game Object is rendered in-game.
* For that you need to either set the scale of the Game Object (`setScale`) or use
* the `displayHeight` property.
*
* @name Phaser.GameObjects.Components.Size#height
* @type {number}
* @since 3.0.0
*/
height: 0,
/**
* The displayed width of this Game Object.
*
* This value takes into account the scale factor.
*
* Setting this value will adjust the Game Object's scale property.
*
* @name Phaser.GameObjects.Components.Size#displayWidth
* @type {number}
* @since 3.0.0
*/
displayWidth: {
get: function() {
return Math.abs(this.scaleX * this.frame.realWidth);
},
set: function(value) {
this.scaleX = value / this.frame.realWidth;
}
},
/**
* The displayed height of this Game Object.
*
* This value takes into account the scale factor.
*
* Setting this value will adjust the Game Object's scale property.
*
* @name Phaser.GameObjects.Components.Size#displayHeight
* @type {number}
* @since 3.0.0
*/
displayHeight: {
get: function() {
return Math.abs(this.scaleY * this.frame.realHeight);
},
set: function(value) {
this.scaleY = value / this.frame.realHeight;
}
},
/**
* Sets the size of this Game Object to be that of the given Frame.
*
* This will not change the size that the Game Object is rendered in-game.
* For that you need to either set the scale of the Game Object (`setScale`) or call the
* `setDisplaySize` method, which is the same thing as changing the scale but allows you
* to do so by giving pixel values.
*
* If you have enabled this Game Object for input, changing the size will _not_ change the
* size of the hit area. To do this you should adjust the `input.hitArea` object directly.
*
* @method Phaser.GameObjects.Components.Size#setSizeToFrame
* @since 3.0.0
*
* @param {Phaser.Textures.Frame|boolean} [frame] - The frame to base the size of this Game Object on.
*
* @return {this} This Game Object instance.
*/
setSizeToFrame: function(frame) {
if (!frame) {
frame = this.frame;
}
this.width = frame.realWidth;
this.height = frame.realHeight;
var input = this.input;
if (input && !input.customHitArea) {
input.hitArea.width = this.width;
input.hitArea.height = this.height;
}
return this;
},
/**
* Sets the internal size of this Game Object, as used for frame or physics body creation.
*
* This will not change the size that the Game Object is rendered in-game.
* For that you need to either set the scale of the Game Object (`setScale`) or call the
* `setDisplaySize` method, which is the same thing as changing the scale but allows you
* to do so by giving pixel values.
*
* If you have enabled this Game Object for input, changing the size will _not_ change the
* size of the hit area. To do this you should adjust the `input.hitArea` object directly.
*
* @method Phaser.GameObjects.Components.Size#setSize
* @since 3.0.0
*
* @param {number} width - The width of this Game Object.
* @param {number} height - The height of this Game Object.
*
* @return {this} This Game Object instance.
*/
setSize: function(width, height) {
this.width = width;
this.height = height;
return this;
},
/**
* Sets the display size of this Game Object.
*
* Calling this will adjust the scale.
*
* @method Phaser.GameObjects.Components.Size#setDisplaySize
* @since 3.0.0
*
* @param {number} width - The width of this Game Object.
* @param {number} height - The height of this Game Object.
*
* @return {this} This Game Object instance.
*/
setDisplaySize: function(width, height) {
this.displayWidth = width;
this.displayHeight = height;
return this;
}
};
module2.exports = Size;
}
),
/***/
37726: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Frame = __webpack_require__2(4327);
var _FLAG = 8;
var Texture = {
/**
* The Texture this Game Object is using to render with.
*
* @name Phaser.GameObjects.Components.Texture#texture
* @type {Phaser.Textures.Texture|Phaser.Textures.CanvasTexture}
* @since 3.0.0
*/
texture: null,
/**
* The Texture Frame this Game Object is using to render with.
*
* @name Phaser.GameObjects.Components.Texture#frame
* @type {Phaser.Textures.Frame}
* @since 3.0.0
*/
frame: null,
/**
* Internal flag. Not to be set by this Game Object.
*
* @name Phaser.GameObjects.Components.Texture#isCropped
* @type {boolean}
* @private
* @since 3.11.0
*/
isCropped: false,
/**
* Sets the texture and frame this Game Object will use to render with.
*
* Textures are referenced by their string-based keys, as stored in the Texture Manager.
*
* Calling this method will modify the `width` and `height` properties of your Game Object.
*
* It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer.
*
* @method Phaser.GameObjects.Components.Texture#setTexture
* @since 3.0.0
*
* @param {(string|Phaser.Textures.Texture)} key - The key of the texture to be used, as stored in the Texture Manager, or a Texture instance.
* @param {(string|number)} [frame] - The name or index of the frame within the Texture.
* @param {boolean} [updateSize=true] - Should this call adjust the size of the Game Object?
* @param {boolean} [updateOrigin=true] - Should this call change the origin of the Game Object?
*
* @return {this} This Game Object instance.
*/
setTexture: function(key, frame, updateSize, updateOrigin) {
this.texture = this.scene.sys.textures.get(key);
return this.setFrame(frame, updateSize, updateOrigin);
},
/**
* Sets the frame this Game Object will use to render with.
*
* If you pass a string or index then the Frame has to belong to the current Texture being used
* by this Game Object.
*
* If you pass a Frame instance, then the Texture being used by this Game Object will also be updated.
*
* Calling `setFrame` will modify the `width` and `height` properties of your Game Object.
*
* It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer.
*
* @method Phaser.GameObjects.Components.Texture#setFrame
* @since 3.0.0
*
* @param {(string|number|Phaser.Textures.Frame)} frame - The name or index of the frame within the Texture, or a Frame instance.
* @param {boolean} [updateSize=true] - Should this call adjust the size of the Game Object?
* @param {boolean} [updateOrigin=true] - Should this call adjust the origin of the Game Object?
*
* @return {this} This Game Object instance.
*/
setFrame: function(frame, updateSize, updateOrigin) {
if (updateSize === void 0) {
updateSize = true;
}
if (updateOrigin === void 0) {
updateOrigin = true;
}
if (frame instanceof Frame) {
this.texture = this.scene.sys.textures.get(frame.texture.key);
this.frame = frame;
} else {
this.frame = this.texture.get(frame);
}
if (!this.frame.cutWidth || !this.frame.cutHeight) {
this.renderFlags &= ~_FLAG;
} else {
this.renderFlags |= _FLAG;
}
if (this._sizeComponent && updateSize) {
this.setSizeToFrame();
}
if (this._originComponent && updateOrigin) {
if (this.frame.customPivot) {
this.setOrigin(this.frame.pivotX, this.frame.pivotY);
} else {
this.updateDisplayOrigin();
}
}
return this;
}
};
module2.exports = Texture;
}
),
/***/
79812: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Frame = __webpack_require__2(4327);
var _FLAG = 8;
var TextureCrop = {
/**
* The Texture this Game Object is using to render with.
*
* @name Phaser.GameObjects.Components.TextureCrop#texture
* @type {Phaser.Textures.Texture|Phaser.Textures.CanvasTexture}
* @since 3.0.0
*/
texture: null,
/**
* The Texture Frame this Game Object is using to render with.
*
* @name Phaser.GameObjects.Components.TextureCrop#frame
* @type {Phaser.Textures.Frame}
* @since 3.0.0
*/
frame: null,
/**
* A boolean flag indicating if this Game Object is being cropped or not.
* You can toggle this at any time after `setCrop` has been called, to turn cropping on or off.
* Equally, calling `setCrop` with no arguments will reset the crop and disable it.
*
* @name Phaser.GameObjects.Components.TextureCrop#isCropped
* @type {boolean}
* @since 3.11.0
*/
isCropped: false,
/**
* Applies a crop to a texture based Game Object, such as a Sprite or Image.
*
* The crop is a rectangle that limits the area of the texture frame that is visible during rendering.
*
* Cropping a Game Object does not change its size, dimensions, physics body or hit area, it just
* changes what is shown when rendered.
*
* The crop size as well as coordinates can not exceed the the size of the texture frame.
*
* The crop coordinates are relative to the texture frame, not the Game Object, meaning 0 x 0 is the top-left.
*
* Therefore, if you had a Game Object that had an 800x600 sized texture, and you wanted to show only the left
* half of it, you could call `setCrop(0, 0, 400, 600)`.
*
* It is also scaled to match the Game Object scale automatically. Therefore a crop rectangle of 100x50 would crop
* an area of 200x100 when applied to a Game Object that had a scale factor of 2.
*
* You can either pass in numeric values directly, or you can provide a single Rectangle object as the first argument.
*
* Call this method with no arguments at all to reset the crop, or toggle the property `isCropped` to `false`.
*
* You should do this if the crop rectangle becomes the same size as the frame itself, as it will allow
* the renderer to skip several internal calculations.
*
* @method Phaser.GameObjects.Components.TextureCrop#setCrop
* @since 3.11.0
*
* @param {(number|Phaser.Geom.Rectangle)} [x] - The x coordinate to start the crop from. Cannot be negative or exceed the Frame width. Or a Phaser.Geom.Rectangle object, in which case the rest of the arguments are ignored.
* @param {number} [y] - The y coordinate to start the crop from. Cannot be negative or exceed the Frame height.
* @param {number} [width] - The width of the crop rectangle in pixels. Cannot exceed the Frame width.
* @param {number} [height] - The height of the crop rectangle in pixels. Cannot exceed the Frame height.
*
* @return {this} This Game Object instance.
*/
setCrop: function(x, y, width, height) {
if (x === void 0) {
this.isCropped = false;
} else if (this.frame) {
if (typeof x === "number") {
this.frame.setCropUVs(this._crop, x, y, width, height, this.flipX, this.flipY);
} else {
var rect = x;
this.frame.setCropUVs(this._crop, rect.x, rect.y, rect.width, rect.height, this.flipX, this.flipY);
}
this.isCropped = true;
}
return this;
},
/**
* Sets the texture and frame this Game Object will use to render with.
*
* Textures are referenced by their string-based keys, as stored in the Texture Manager.
*
* @method Phaser.GameObjects.Components.TextureCrop#setTexture
* @since 3.0.0
*
* @param {string} key - The key of the texture to be used, as stored in the Texture Manager.
* @param {(string|number)} [frame] - The name or index of the frame within the Texture.
*
* @return {this} This Game Object instance.
*/
setTexture: function(key, frame) {
this.texture = this.scene.sys.textures.get(key);
return this.setFrame(frame);
},
/**
* Sets the frame this Game Object will use to render with.
*
* If you pass a string or index then the Frame has to belong to the current Texture being used
* by this Game Object.
*
* If you pass a Frame instance, then the Texture being used by this Game Object will also be updated.
*
* Calling `setFrame` will modify the `width` and `height` properties of your Game Object.
*
* It will also change the `origin` if the Frame has a custom pivot point, as exported from packages like Texture Packer.
*
* @method Phaser.GameObjects.Components.TextureCrop#setFrame
* @since 3.0.0
*
* @param {(string|number|Phaser.Textures.Frame)} frame - The name or index of the frame within the Texture, or a Frame instance.
* @param {boolean} [updateSize=true] - Should this call adjust the size of the Game Object?
* @param {boolean} [updateOrigin=true] - Should this call adjust the origin of the Game Object?
*
* @return {this} This Game Object instance.
*/
setFrame: function(frame, updateSize, updateOrigin) {
if (updateSize === void 0) {
updateSize = true;
}
if (updateOrigin === void 0) {
updateOrigin = true;
}
if (frame instanceof Frame) {
this.texture = this.scene.sys.textures.get(frame.texture.key);
this.frame = frame;
} else {
this.frame = this.texture.get(frame);
}
if (!this.frame.cutWidth || !this.frame.cutHeight) {
this.renderFlags &= ~_FLAG;
} else {
this.renderFlags |= _FLAG;
}
if (this._sizeComponent && updateSize) {
this.setSizeToFrame();
}
if (this._originComponent && updateOrigin) {
if (this.frame.customPivot) {
this.setOrigin(this.frame.pivotX, this.frame.pivotY);
} else {
this.updateDisplayOrigin();
}
}
if (this.isCropped) {
this.frame.updateCropUVs(this._crop, this.flipX, this.flipY);
}
return this;
},
/**
* Internal method that returns a blank, well-formed crop object for use by a Game Object.
*
* @method Phaser.GameObjects.Components.TextureCrop#resetCropObject
* @private
* @since 3.12.0
*
* @return {object} The crop object.
*/
resetCropObject: function() {
return { u0: 0, v0: 0, u1: 0, v1: 0, width: 0, height: 0, x: 0, y: 0, flipX: false, flipY: false, cx: 0, cy: 0, cw: 0, ch: 0 };
}
};
module2.exports = TextureCrop;
}
),
/***/
27472: (
/***/
(module2) => {
var Tint = {
/**
* The tint value being applied to the top-left vertice of the Game Object.
* This value is interpolated from the corner to the center of the Game Object.
* The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple.
*
* @name Phaser.GameObjects.Components.Tint#tintTopLeft
* @type {number}
* @default 0xffffff
* @since 3.0.0
*/
tintTopLeft: 16777215,
/**
* The tint value being applied to the top-right vertice of the Game Object.
* This value is interpolated from the corner to the center of the Game Object.
* The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple.
*
* @name Phaser.GameObjects.Components.Tint#tintTopRight
* @type {number}
* @default 0xffffff
* @since 3.0.0
*/
tintTopRight: 16777215,
/**
* The tint value being applied to the bottom-left vertice of the Game Object.
* This value is interpolated from the corner to the center of the Game Object.
* The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple.
*
* @name Phaser.GameObjects.Components.Tint#tintBottomLeft
* @type {number}
* @default 0xffffff
* @since 3.0.0
*/
tintBottomLeft: 16777215,
/**
* The tint value being applied to the bottom-right vertice of the Game Object.
* This value is interpolated from the corner to the center of the Game Object.
* The value should be set as a hex number, i.e. 0xff0000 for red, or 0xff00ff for purple.
*
* @name Phaser.GameObjects.Components.Tint#tintBottomRight
* @type {number}
* @default 0xffffff
* @since 3.0.0
*/
tintBottomRight: 16777215,
/**
* The tint fill mode.
*
* `false` = An additive tint (the default), where vertices colors are blended with the texture.
* `true` = A fill tint, where the vertices colors replace the texture, but respects texture alpha.
*
* @name Phaser.GameObjects.Components.Tint#tintFill
* @type {boolean}
* @default false
* @since 3.11.0
*/
tintFill: false,
/**
* Clears all tint values associated with this Game Object.
*
* Immediately sets the color values back to 0xffffff and the tint type to 'additive',
* which results in no visible change to the texture.
*
* @method Phaser.GameObjects.Components.Tint#clearTint
* @webglOnly
* @since 3.0.0
*
* @return {this} This Game Object instance.
*/
clearTint: function() {
this.setTint(16777215);
return this;
},
/**
* Sets an additive tint on this Game Object.
*
* The tint works by taking the pixel color values from the Game Objects texture, and then
* multiplying it by the color value of the tint. You can provide either one color value,
* in which case the whole Game Object will be tinted in that color. Or you can provide a color
* per corner. The colors are blended together across the extent of the Game Object.
*
* To modify the tint color once set, either call this method again with new values or use the
* `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight,
* `tintBottomLeft` and `tintBottomRight` to set the corner color values independently.
*
* To remove a tint call `clearTint`.
*
* To swap this from being an additive tint to a fill based tint set the property `tintFill` to `true`.
*
* @method Phaser.GameObjects.Components.Tint#setTint
* @webglOnly
* @since 3.0.0
*
* @param {number} [topLeft=0xffffff] - The tint being applied to the top-left of the Game Object. If no other values are given this value is applied evenly, tinting the whole Game Object.
* @param {number} [topRight] - The tint being applied to the top-right of the Game Object.
* @param {number} [bottomLeft] - The tint being applied to the bottom-left of the Game Object.
* @param {number} [bottomRight] - The tint being applied to the bottom-right of the Game Object.
*
* @return {this} This Game Object instance.
*/
setTint: function(topLeft, topRight, bottomLeft, bottomRight) {
if (topLeft === void 0) {
topLeft = 16777215;
}
if (topRight === void 0) {
topRight = topLeft;
bottomLeft = topLeft;
bottomRight = topLeft;
}
this.tintTopLeft = topLeft;
this.tintTopRight = topRight;
this.tintBottomLeft = bottomLeft;
this.tintBottomRight = bottomRight;
this.tintFill = false;
return this;
},
/**
* Sets a fill-based tint on this Game Object.
*
* Unlike an additive tint, a fill-tint literally replaces the pixel colors from the texture
* with those in the tint. You can use this for effects such as making a player flash 'white'
* if hit by something. You can provide either one color value, in which case the whole
* Game Object will be rendered in that color. Or you can provide a color per corner. The colors
* are blended together across the extent of the Game Object.
*
* To modify the tint color once set, either call this method again with new values or use the
* `tint` property to set all colors at once. Or, use the properties `tintTopLeft`, `tintTopRight,
* `tintBottomLeft` and `tintBottomRight` to set the corner color values independently.
*
* To remove a tint call `clearTint`.
*
* To swap this from being a fill-tint to an additive tint set the property `tintFill` to `false`.
*
* @method Phaser.GameObjects.Components.Tint#setTintFill
* @webglOnly
* @since 3.11.0
*
* @param {number} [topLeft=0xffffff] - The tint being applied to the top-left of the Game Object. If not other values are given this value is applied evenly, tinting the whole Game Object.
* @param {number} [topRight] - The tint being applied to the top-right of the Game Object.
* @param {number} [bottomLeft] - The tint being applied to the bottom-left of the Game Object.
* @param {number} [bottomRight] - The tint being applied to the bottom-right of the Game Object.
*
* @return {this} This Game Object instance.
*/
setTintFill: function(topLeft, topRight, bottomLeft, bottomRight) {
this.setTint(topLeft, topRight, bottomLeft, bottomRight);
this.tintFill = true;
return this;
},
/**
* The tint value being applied to the whole of the Game Object.
* Return `tintTopLeft` when read this tint property.
*
* @name Phaser.GameObjects.Components.Tint#tint
* @type {number}
* @webglOnly
* @since 3.0.0
*/
tint: {
get: function() {
return this.tintTopLeft;
},
set: function(value) {
this.setTint(value, value, value, value);
}
},
/**
* Does this Game Object have a tint applied?
*
* It checks to see if the 4 tint properties are set to the value 0xffffff
* and that the `tintFill` property is `false`. This indicates that a Game Object isn't tinted.
*
* @name Phaser.GameObjects.Components.Tint#isTinted
* @type {boolean}
* @webglOnly
* @readonly
* @since 3.11.0
*/
isTinted: {
get: function() {
var white = 16777215;
return this.tintFill || this.tintTopLeft !== white || this.tintTopRight !== white || this.tintBottomLeft !== white || this.tintBottomRight !== white;
}
}
};
module2.exports = Tint;
}
),
/***/
53774: (
/***/
(module2) => {
var ToJSON = function(gameObject) {
var out = {
name: gameObject.name,
type: gameObject.type,
x: gameObject.x,
y: gameObject.y,
depth: gameObject.depth,
scale: {
x: gameObject.scaleX,
y: gameObject.scaleY
},
origin: {
x: gameObject.originX,
y: gameObject.originY
},
flipX: gameObject.flipX,
flipY: gameObject.flipY,
rotation: gameObject.rotation,
alpha: gameObject.alpha,
visible: gameObject.visible,
blendMode: gameObject.blendMode,
textureKey: "",
frameKey: "",
data: {}
};
if (gameObject.texture) {
out.textureKey = gameObject.texture.key;
out.frameKey = gameObject.frame.name;
}
return out;
};
module2.exports = ToJSON;
}
),
/***/
16901: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var MATH_CONST = __webpack_require__2(36383);
var TransformMatrix = __webpack_require__2(61340);
var TransformXY = __webpack_require__2(85955);
var WrapAngle = __webpack_require__2(86554);
var WrapAngleDegrees = __webpack_require__2(30954);
var Vector2 = __webpack_require__2(26099);
var _FLAG = 4;
var Transform = {
/**
* A property indicating that a Game Object has this component.
*
* @name Phaser.GameObjects.Components.Transform#hasTransformComponent
* @type {boolean}
* @readonly
* @default true
* @since 3.60.0
*/
hasTransformComponent: true,
/**
* Private internal value. Holds the horizontal scale value.
*
* @name Phaser.GameObjects.Components.Transform#_scaleX
* @type {number}
* @private
* @default 1
* @since 3.0.0
*/
_scaleX: 1,
/**
* Private internal value. Holds the vertical scale value.
*
* @name Phaser.GameObjects.Components.Transform#_scaleY
* @type {number}
* @private
* @default 1
* @since 3.0.0
*/
_scaleY: 1,
/**
* Private internal value. Holds the rotation value in radians.
*
* @name Phaser.GameObjects.Components.Transform#_rotation
* @type {number}
* @private
* @default 0
* @since 3.0.0
*/
_rotation: 0,
/**
* The x position of this Game Object.
*
* @name Phaser.GameObjects.Components.Transform#x
* @type {number}
* @default 0
* @since 3.0.0
*/
x: 0,
/**
* The y position of this Game Object.
*
* @name Phaser.GameObjects.Components.Transform#y
* @type {number}
* @default 0
* @since 3.0.0
*/
y: 0,
/**
* The z position of this Game Object.
*
* Note: The z position does not control the rendering order of 2D Game Objects. Use
* {@link Phaser.GameObjects.Components.Depth#depth} instead.
*
* @name Phaser.GameObjects.Components.Transform#z
* @type {number}
* @default 0
* @since 3.0.0
*/
z: 0,
/**
* The w position of this Game Object.
*
* @name Phaser.GameObjects.Components.Transform#w
* @type {number}
* @default 0
* @since 3.0.0
*/
w: 0,
/**
* This is a special setter that allows you to set both the horizontal and vertical scale of this Game Object
* to the same value, at the same time. When reading this value the result returned is `(scaleX + scaleY) / 2`.
*
* Use of this property implies you wish the horizontal and vertical scales to be equal to each other. If this
* isn't the case, use the `scaleX` or `scaleY` properties instead.
*
* @name Phaser.GameObjects.Components.Transform#scale
* @type {number}
* @default 1
* @since 3.18.0
*/
scale: {
get: function() {
return (this._scaleX + this._scaleY) / 2;
},
set: function(value) {
this._scaleX = value;
this._scaleY = value;
if (value === 0) {
this.renderFlags &= ~_FLAG;
} else {
this.renderFlags |= _FLAG;
}
}
},
/**
* The horizontal scale of this Game Object.
*
* @name Phaser.GameObjects.Components.Transform#scaleX
* @type {number}
* @default 1
* @since 3.0.0
*/
scaleX: {
get: function() {
return this._scaleX;
},
set: function(value) {
this._scaleX = value;
if (value === 0) {
this.renderFlags &= ~_FLAG;
} else if (this._scaleY !== 0) {
this.renderFlags |= _FLAG;
}
}
},
/**
* The vertical scale of this Game Object.
*
* @name Phaser.GameObjects.Components.Transform#scaleY
* @type {number}
* @default 1
* @since 3.0.0
*/
scaleY: {
get: function() {
return this._scaleY;
},
set: function(value) {
this._scaleY = value;
if (value === 0) {
this.renderFlags &= ~_FLAG;
} else if (this._scaleX !== 0) {
this.renderFlags |= _FLAG;
}
}
},
/**
* The angle of this Game Object as expressed in degrees.
*
* Phaser uses a right-hand clockwise rotation system, where 0 is right, 90 is down, 180/-180 is left
* and -90 is up.
*
* If you prefer to work in radians, see the `rotation` property instead.
*
* @name Phaser.GameObjects.Components.Transform#angle
* @type {number}
* @default 0
* @since 3.0.0
*/
angle: {
get: function() {
return WrapAngleDegrees(this._rotation * MATH_CONST.RAD_TO_DEG);
},
set: function(value) {
this.rotation = WrapAngleDegrees(value) * MATH_CONST.DEG_TO_RAD;
}
},
/**
* The angle of this Game Object in radians.
*
* Phaser uses a right-hand clockwise rotation system, where 0 is right, PI/2 is down, +-PI is left
* and -PI/2 is up.
*
* If you prefer to work in degrees, see the `angle` property instead.
*
* @name Phaser.GameObjects.Components.Transform#rotation
* @type {number}
* @default 1
* @since 3.0.0
*/
rotation: {
get: function() {
return this._rotation;
},
set: function(value) {
this._rotation = WrapAngle(value);
}
},
/**
* Sets the position of this Game Object.
*
* @method Phaser.GameObjects.Components.Transform#setPosition
* @since 3.0.0
*
* @param {number} [x=0] - The x position of this Game Object.
* @param {number} [y=x] - The y position of this Game Object. If not set it will use the `x` value.
* @param {number} [z=0] - The z position of this Game Object.
* @param {number} [w=0] - The w position of this Game Object.
*
* @return {this} This Game Object instance.
*/
setPosition: function(x, y, z, w) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = x;
}
if (z === void 0) {
z = 0;
}
if (w === void 0) {
w = 0;
}
this.x = x;
this.y = y;
this.z = z;
this.w = w;
return this;
},
/**
* Copies an object's coordinates to this Game Object's position.
*
* @method Phaser.GameObjects.Components.Transform#copyPosition
* @since 3.50.0
*
* @param {(Phaser.Types.Math.Vector2Like|Phaser.Types.Math.Vector3Like|Phaser.Types.Math.Vector4Like)} source - An object with numeric 'x', 'y', 'z', or 'w' properties. Undefined values are not copied.
*
* @return {this} This Game Object instance.
*/
copyPosition: function(source) {
if (source.x !== void 0) {
this.x = source.x;
}
if (source.y !== void 0) {
this.y = source.y;
}
if (source.z !== void 0) {
this.z = source.z;
}
if (source.w !== void 0) {
this.w = source.w;
}
return this;
},
/**
* Sets the position of this Game Object to be a random position within the confines of
* the given area.
*
* If no area is specified a random position between 0 x 0 and the game width x height is used instead.
*
* The position does not factor in the size of this Game Object, meaning that only the origin is
* guaranteed to be within the area.
*
* @method Phaser.GameObjects.Components.Transform#setRandomPosition
* @since 3.8.0
*
* @param {number} [x=0] - The x position of the top-left of the random area.
* @param {number} [y=0] - The y position of the top-left of the random area.
* @param {number} [width] - The width of the random area.
* @param {number} [height] - The height of the random area.
*
* @return {this} This Game Object instance.
*/
setRandomPosition: function(x, y, width, height) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (width === void 0) {
width = this.scene.sys.scale.width;
}
if (height === void 0) {
height = this.scene.sys.scale.height;
}
this.x = x + Math.random() * width;
this.y = y + Math.random() * height;
return this;
},
/**
* Sets the rotation of this Game Object.
*
* @method Phaser.GameObjects.Components.Transform#setRotation
* @since 3.0.0
*
* @param {number} [radians=0] - The rotation of this Game Object, in radians.
*
* @return {this} This Game Object instance.
*/
setRotation: function(radians) {
if (radians === void 0) {
radians = 0;
}
this.rotation = radians;
return this;
},
/**
* Sets the angle of this Game Object.
*
* @method Phaser.GameObjects.Components.Transform#setAngle
* @since 3.0.0
*
* @param {number} [degrees=0] - The rotation of this Game Object, in degrees.
*
* @return {this} This Game Object instance.
*/
setAngle: function(degrees) {
if (degrees === void 0) {
degrees = 0;
}
this.angle = degrees;
return this;
},
/**
* Sets the scale of this Game Object.
*
* @method Phaser.GameObjects.Components.Transform#setScale
* @since 3.0.0
*
* @param {number} [x=1] - The horizontal scale of this Game Object.
* @param {number} [y=x] - The vertical scale of this Game Object. If not set it will use the `x` value.
*
* @return {this} This Game Object instance.
*/
setScale: function(x, y) {
if (x === void 0) {
x = 1;
}
if (y === void 0) {
y = x;
}
this.scaleX = x;
this.scaleY = y;
return this;
},
/**
* Sets the x position of this Game Object.
*
* @method Phaser.GameObjects.Components.Transform#setX
* @since 3.0.0
*
* @param {number} [value=0] - The x position of this Game Object.
*
* @return {this} This Game Object instance.
*/
setX: function(value) {
if (value === void 0) {
value = 0;
}
this.x = value;
return this;
},
/**
* Sets the y position of this Game Object.
*
* @method Phaser.GameObjects.Components.Transform#setY
* @since 3.0.0
*
* @param {number} [value=0] - The y position of this Game Object.
*
* @return {this} This Game Object instance.
*/
setY: function(value) {
if (value === void 0) {
value = 0;
}
this.y = value;
return this;
},
/**
* Sets the z position of this Game Object.
*
* Note: The z position does not control the rendering order of 2D Game Objects. Use
* {@link Phaser.GameObjects.Components.Depth#setDepth} instead.
*
* @method Phaser.GameObjects.Components.Transform#setZ
* @since 3.0.0
*
* @param {number} [value=0] - The z position of this Game Object.
*
* @return {this} This Game Object instance.
*/
setZ: function(value) {
if (value === void 0) {
value = 0;
}
this.z = value;
return this;
},
/**
* Sets the w position of this Game Object.
*
* @method Phaser.GameObjects.Components.Transform#setW
* @since 3.0.0
*
* @param {number} [value=0] - The w position of this Game Object.
*
* @return {this} This Game Object instance.
*/
setW: function(value) {
if (value === void 0) {
value = 0;
}
this.w = value;
return this;
},
/**
* Gets the local transform matrix for this Game Object.
*
* @method Phaser.GameObjects.Components.Transform#getLocalTransformMatrix
* @since 3.4.0
*
* @param {Phaser.GameObjects.Components.TransformMatrix} [tempMatrix] - The matrix to populate with the values from this Game Object.
*
* @return {Phaser.GameObjects.Components.TransformMatrix} The populated Transform Matrix.
*/
getLocalTransformMatrix: function(tempMatrix) {
if (tempMatrix === void 0) {
tempMatrix = new TransformMatrix();
}
return tempMatrix.applyITRS(this.x, this.y, this._rotation, this._scaleX, this._scaleY);
},
/**
* Gets the world transform matrix for this Game Object, factoring in any parent Containers.
*
* @method Phaser.GameObjects.Components.Transform#getWorldTransformMatrix
* @since 3.4.0
*
* @param {Phaser.GameObjects.Components.TransformMatrix} [tempMatrix] - The matrix to populate with the values from this Game Object.
* @param {Phaser.GameObjects.Components.TransformMatrix} [parentMatrix] - A temporary matrix to hold parent values during the calculations.
*
* @return {Phaser.GameObjects.Components.TransformMatrix} The populated Transform Matrix.
*/
getWorldTransformMatrix: function(tempMatrix, parentMatrix) {
if (tempMatrix === void 0) {
tempMatrix = new TransformMatrix();
}
var parent = this.parentContainer;
if (!parent) {
return this.getLocalTransformMatrix(tempMatrix);
}
if (!parentMatrix) {
parentMatrix = new TransformMatrix();
}
tempMatrix.applyITRS(this.x, this.y, this._rotation, this._scaleX, this._scaleY);
while (parent) {
parentMatrix.applyITRS(parent.x, parent.y, parent._rotation, parent._scaleX, parent._scaleY);
parentMatrix.multiply(tempMatrix, tempMatrix);
parent = parent.parentContainer;
}
return tempMatrix;
},
/**
* Takes the given `x` and `y` coordinates and converts them into local space for this
* Game Object, taking into account parent and local transforms, and the Display Origin.
*
* The returned Vector2 contains the translated point in its properties.
*
* A Camera needs to be provided in order to handle modified scroll factors. If no
* camera is specified, it will use the `main` camera from the Scene to which this
* Game Object belongs.
*
* @method Phaser.GameObjects.Components.Transform#getLocalPoint
* @since 3.50.0
*
* @param {number} x - The x position to translate.
* @param {number} y - The y position to translate.
* @param {Phaser.Math.Vector2} [point] - A Vector2, or point-like object, to store the results in.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera which is being tested against. If not given will use the Scene default camera.
*
* @return {Phaser.Math.Vector2} The translated point.
*/
getLocalPoint: function(x, y, point, camera) {
if (!point) {
point = new Vector2();
}
if (!camera) {
camera = this.scene.sys.cameras.main;
}
var csx = camera.scrollX;
var csy = camera.scrollY;
var px = x + csx * this.scrollFactorX - csx;
var py = y + csy * this.scrollFactorY - csy;
if (this.parentContainer) {
this.getWorldTransformMatrix().applyInverse(px, py, point);
} else {
TransformXY(px, py, this.x, this.y, this.rotation, this.scaleX, this.scaleY, point);
}
if (this._originComponent) {
point.x += this._displayOriginX;
point.y += this._displayOriginY;
}
return point;
},
/**
* Gets the sum total rotation of all of this Game Objects parent Containers.
*
* The returned value is in radians and will be zero if this Game Object has no parent container.
*
* @method Phaser.GameObjects.Components.Transform#getParentRotation
* @since 3.18.0
*
* @return {number} The sum total rotation, in radians, of all parent containers of this Game Object.
*/
getParentRotation: function() {
var rotation = 0;
var parent = this.parentContainer;
while (parent) {
rotation += parent.rotation;
parent = parent.parentContainer;
}
return rotation;
}
};
module2.exports = Transform;
}
),
/***/
61340: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var MATH_CONST = __webpack_require__2(36383);
var Vector2 = __webpack_require__2(26099);
var TransformMatrix = new Class({
initialize: function TransformMatrix2(a, b, c, d, tx, ty) {
if (a === void 0) {
a = 1;
}
if (b === void 0) {
b = 0;
}
if (c === void 0) {
c = 0;
}
if (d === void 0) {
d = 1;
}
if (tx === void 0) {
tx = 0;
}
if (ty === void 0) {
ty = 0;
}
this.matrix = new Float32Array([a, b, c, d, tx, ty, 0, 0, 1]);
this.decomposedMatrix = {
translateX: 0,
translateY: 0,
scaleX: 1,
scaleY: 1,
rotation: 0
};
this.quad = new Float32Array(8);
},
/**
* The Scale X value.
*
* @name Phaser.GameObjects.Components.TransformMatrix#a
* @type {number}
* @since 3.4.0
*/
a: {
get: function() {
return this.matrix[0];
},
set: function(value) {
this.matrix[0] = value;
}
},
/**
* The Skew Y value.
*
* @name Phaser.GameObjects.Components.TransformMatrix#b
* @type {number}
* @since 3.4.0
*/
b: {
get: function() {
return this.matrix[1];
},
set: function(value) {
this.matrix[1] = value;
}
},
/**
* The Skew X value.
*
* @name Phaser.GameObjects.Components.TransformMatrix#c
* @type {number}
* @since 3.4.0
*/
c: {
get: function() {
return this.matrix[2];
},
set: function(value) {
this.matrix[2] = value;
}
},
/**
* The Scale Y value.
*
* @name Phaser.GameObjects.Components.TransformMatrix#d
* @type {number}
* @since 3.4.0
*/
d: {
get: function() {
return this.matrix[3];
},
set: function(value) {
this.matrix[3] = value;
}
},
/**
* The Translate X value.
*
* @name Phaser.GameObjects.Components.TransformMatrix#e
* @type {number}
* @since 3.11.0
*/
e: {
get: function() {
return this.matrix[4];
},
set: function(value) {
this.matrix[4] = value;
}
},
/**
* The Translate Y value.
*
* @name Phaser.GameObjects.Components.TransformMatrix#f
* @type {number}
* @since 3.11.0
*/
f: {
get: function() {
return this.matrix[5];
},
set: function(value) {
this.matrix[5] = value;
}
},
/**
* The Translate X value.
*
* @name Phaser.GameObjects.Components.TransformMatrix#tx
* @type {number}
* @since 3.4.0
*/
tx: {
get: function() {
return this.matrix[4];
},
set: function(value) {
this.matrix[4] = value;
}
},
/**
* The Translate Y value.
*
* @name Phaser.GameObjects.Components.TransformMatrix#ty
* @type {number}
* @since 3.4.0
*/
ty: {
get: function() {
return this.matrix[5];
},
set: function(value) {
this.matrix[5] = value;
}
},
/**
* The rotation of the Matrix. Value is in radians.
*
* @name Phaser.GameObjects.Components.TransformMatrix#rotation
* @type {number}
* @readonly
* @since 3.4.0
*/
rotation: {
get: function() {
return Math.acos(this.a / this.scaleX) * (Math.atan(-this.c / this.a) < 0 ? -1 : 1);
}
},
/**
* The rotation of the Matrix, normalized to be within the Phaser right-handed
* clockwise rotation space. Value is in radians.
*
* @name Phaser.GameObjects.Components.TransformMatrix#rotationNormalized
* @type {number}
* @readonly
* @since 3.19.0
*/
rotationNormalized: {
get: function() {
var matrix = this.matrix;
var a = matrix[0];
var b = matrix[1];
var c = matrix[2];
var d = matrix[3];
if (a || b) {
return b > 0 ? Math.acos(a / this.scaleX) : -Math.acos(a / this.scaleX);
} else if (c || d) {
return MATH_CONST.TAU - (d > 0 ? Math.acos(-c / this.scaleY) : -Math.acos(c / this.scaleY));
} else {
return 0;
}
}
},
/**
* The decomposed horizontal scale of the Matrix. This value is always positive.
*
* @name Phaser.GameObjects.Components.TransformMatrix#scaleX
* @type {number}
* @readonly
* @since 3.4.0
*/
scaleX: {
get: function() {
return Math.sqrt(this.a * this.a + this.b * this.b);
}
},
/**
* The decomposed vertical scale of the Matrix. This value is always positive.
*
* @name Phaser.GameObjects.Components.TransformMatrix#scaleY
* @type {number}
* @readonly
* @since 3.4.0
*/
scaleY: {
get: function() {
return Math.sqrt(this.c * this.c + this.d * this.d);
}
},
/**
* Reset the Matrix to an identity matrix.
*
* @method Phaser.GameObjects.Components.TransformMatrix#loadIdentity
* @since 3.0.0
*
* @return {this} This TransformMatrix.
*/
loadIdentity: function() {
var matrix = this.matrix;
matrix[0] = 1;
matrix[1] = 0;
matrix[2] = 0;
matrix[3] = 1;
matrix[4] = 0;
matrix[5] = 0;
return this;
},
/**
* Translate the Matrix.
*
* @method Phaser.GameObjects.Components.TransformMatrix#translate
* @since 3.0.0
*
* @param {number} x - The horizontal translation value.
* @param {number} y - The vertical translation value.
*
* @return {this} This TransformMatrix.
*/
translate: function(x, y) {
var matrix = this.matrix;
matrix[4] = matrix[0] * x + matrix[2] * y + matrix[4];
matrix[5] = matrix[1] * x + matrix[3] * y + matrix[5];
return this;
},
/**
* Scale the Matrix.
*
* @method Phaser.GameObjects.Components.TransformMatrix#scale
* @since 3.0.0
*
* @param {number} x - The horizontal scale value.
* @param {number} y - The vertical scale value.
*
* @return {this} This TransformMatrix.
*/
scale: function(x, y) {
var matrix = this.matrix;
matrix[0] *= x;
matrix[1] *= x;
matrix[2] *= y;
matrix[3] *= y;
return this;
},
/**
* Rotate the Matrix.
*
* @method Phaser.GameObjects.Components.TransformMatrix#rotate
* @since 3.0.0
*
* @param {number} angle - The angle of rotation in radians.
*
* @return {this} This TransformMatrix.
*/
rotate: function(angle) {
var sin = Math.sin(angle);
var cos = Math.cos(angle);
var matrix = this.matrix;
var a = matrix[0];
var b = matrix[1];
var c = matrix[2];
var d = matrix[3];
matrix[0] = a * cos + c * sin;
matrix[1] = b * cos + d * sin;
matrix[2] = a * -sin + c * cos;
matrix[3] = b * -sin + d * cos;
return this;
},
/**
* Multiply this Matrix by the given Matrix.
*
* If an `out` Matrix is given then the results will be stored in it.
* If it is not given, this matrix will be updated in place instead.
* Use an `out` Matrix if you do not wish to mutate this matrix.
*
* @method Phaser.GameObjects.Components.TransformMatrix#multiply
* @since 3.0.0
*
* @param {Phaser.GameObjects.Components.TransformMatrix} rhs - The Matrix to multiply by.
* @param {Phaser.GameObjects.Components.TransformMatrix} [out] - An optional Matrix to store the results in.
*
* @return {(this|Phaser.GameObjects.Components.TransformMatrix)} Either this TransformMatrix, or the `out` Matrix, if given in the arguments.
*/
multiply: function(rhs, out) {
var matrix = this.matrix;
var source = rhs.matrix;
var localA = matrix[0];
var localB = matrix[1];
var localC = matrix[2];
var localD = matrix[3];
var localE = matrix[4];
var localF = matrix[5];
var sourceA = source[0];
var sourceB = source[1];
var sourceC = source[2];
var sourceD = source[3];
var sourceE = source[4];
var sourceF = source[5];
var destinationMatrix = out === void 0 ? matrix : out.matrix;
destinationMatrix[0] = sourceA * localA + sourceB * localC;
destinationMatrix[1] = sourceA * localB + sourceB * localD;
destinationMatrix[2] = sourceC * localA + sourceD * localC;
destinationMatrix[3] = sourceC * localB + sourceD * localD;
destinationMatrix[4] = sourceE * localA + sourceF * localC + localE;
destinationMatrix[5] = sourceE * localB + sourceF * localD + localF;
return destinationMatrix;
},
/**
* Multiply this Matrix by the matrix given, including the offset.
*
* The offsetX is added to the tx value: `offsetX * a + offsetY * c + tx`.
* The offsetY is added to the ty value: `offsetY * b + offsetY * d + ty`.
*
* @method Phaser.GameObjects.Components.TransformMatrix#multiplyWithOffset
* @since 3.11.0
*
* @param {Phaser.GameObjects.Components.TransformMatrix} src - The source Matrix to copy from.
* @param {number} offsetX - Horizontal offset to factor in to the multiplication.
* @param {number} offsetY - Vertical offset to factor in to the multiplication.
*
* @return {this} This TransformMatrix.
*/
multiplyWithOffset: function(src, offsetX, offsetY) {
var matrix = this.matrix;
var otherMatrix = src.matrix;
var a0 = matrix[0];
var b0 = matrix[1];
var c0 = matrix[2];
var d0 = matrix[3];
var tx0 = matrix[4];
var ty0 = matrix[5];
var pse = offsetX * a0 + offsetY * c0 + tx0;
var psf = offsetX * b0 + offsetY * d0 + ty0;
var a1 = otherMatrix[0];
var b1 = otherMatrix[1];
var c1 = otherMatrix[2];
var d1 = otherMatrix[3];
var tx1 = otherMatrix[4];
var ty1 = otherMatrix[5];
matrix[0] = a1 * a0 + b1 * c0;
matrix[1] = a1 * b0 + b1 * d0;
matrix[2] = c1 * a0 + d1 * c0;
matrix[3] = c1 * b0 + d1 * d0;
matrix[4] = tx1 * a0 + ty1 * c0 + pse;
matrix[5] = tx1 * b0 + ty1 * d0 + psf;
return this;
},
/**
* Transform the Matrix.
*
* @method Phaser.GameObjects.Components.TransformMatrix#transform
* @since 3.0.0
*
* @param {number} a - The Scale X value.
* @param {number} b - The Shear Y value.
* @param {number} c - The Shear X value.
* @param {number} d - The Scale Y value.
* @param {number} tx - The Translate X value.
* @param {number} ty - The Translate Y value.
*
* @return {this} This TransformMatrix.
*/
transform: function(a, b, c, d, tx, ty) {
var matrix = this.matrix;
var a0 = matrix[0];
var b0 = matrix[1];
var c0 = matrix[2];
var d0 = matrix[3];
var tx0 = matrix[4];
var ty0 = matrix[5];
matrix[0] = a * a0 + b * c0;
matrix[1] = a * b0 + b * d0;
matrix[2] = c * a0 + d * c0;
matrix[3] = c * b0 + d * d0;
matrix[4] = tx * a0 + ty * c0 + tx0;
matrix[5] = tx * b0 + ty * d0 + ty0;
return this;
},
/**
* Transform a point in to the local space of this Matrix.
*
* @method Phaser.GameObjects.Components.TransformMatrix#transformPoint
* @since 3.0.0
*
* @param {number} x - The x coordinate of the point to transform.
* @param {number} y - The y coordinate of the point to transform.
* @param {Phaser.Types.Math.Vector2Like} [point] - Optional Point object to store the transformed coordinates in.
*
* @return {Phaser.Types.Math.Vector2Like} The Point containing the transformed coordinates.
*/
transformPoint: function(x, y, point) {
if (point === void 0) {
point = { x: 0, y: 0 };
}
var matrix = this.matrix;
var a = matrix[0];
var b = matrix[1];
var c = matrix[2];
var d = matrix[3];
var tx = matrix[4];
var ty = matrix[5];
point.x = x * a + y * c + tx;
point.y = x * b + y * d + ty;
return point;
},
/**
* Invert the Matrix.
*
* @method Phaser.GameObjects.Components.TransformMatrix#invert
* @since 3.0.0
*
* @return {this} This TransformMatrix.
*/
invert: function() {
var matrix = this.matrix;
var a = matrix[0];
var b = matrix[1];
var c = matrix[2];
var d = matrix[3];
var tx = matrix[4];
var ty = matrix[5];
var n = a * d - b * c;
matrix[0] = d / n;
matrix[1] = -b / n;
matrix[2] = -c / n;
matrix[3] = a / n;
matrix[4] = (c * ty - d * tx) / n;
matrix[5] = -(a * ty - b * tx) / n;
return this;
},
/**
* Set the values of this Matrix to copy those of the matrix given.
*
* @method Phaser.GameObjects.Components.TransformMatrix#copyFrom
* @since 3.11.0
*
* @param {Phaser.GameObjects.Components.TransformMatrix} src - The source Matrix to copy from.
*
* @return {this} This TransformMatrix.
*/
copyFrom: function(src) {
var matrix = this.matrix;
matrix[0] = src.a;
matrix[1] = src.b;
matrix[2] = src.c;
matrix[3] = src.d;
matrix[4] = src.e;
matrix[5] = src.f;
return this;
},
/**
* Set the values of this Matrix to copy those of the array given.
* Where array indexes 0, 1, 2, 3, 4 and 5 are mapped to a, b, c, d, e and f.
*
* @method Phaser.GameObjects.Components.TransformMatrix#copyFromArray
* @since 3.11.0
*
* @param {array} src - The array of values to set into this matrix.
*
* @return {this} This TransformMatrix.
*/
copyFromArray: function(src) {
var matrix = this.matrix;
matrix[0] = src[0];
matrix[1] = src[1];
matrix[2] = src[2];
matrix[3] = src[3];
matrix[4] = src[4];
matrix[5] = src[5];
return this;
},
/**
* Copy the values from this Matrix to the given Canvas Rendering Context.
* This will use the Context.transform method.
*
* @method Phaser.GameObjects.Components.TransformMatrix#copyToContext
* @since 3.12.0
*
* @param {CanvasRenderingContext2D} ctx - The Canvas Rendering Context to copy the matrix values to.
*
* @return {CanvasRenderingContext2D} The Canvas Rendering Context.
*/
copyToContext: function(ctx) {
var matrix = this.matrix;
ctx.transform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]);
return ctx;
},
/**
* Copy the values from this Matrix to the given Canvas Rendering Context.
* This will use the Context.setTransform method.
*
* @method Phaser.GameObjects.Components.TransformMatrix#setToContext
* @since 3.12.0
*
* @param {CanvasRenderingContext2D} ctx - The Canvas Rendering Context to copy the matrix values to.
*
* @return {CanvasRenderingContext2D} The Canvas Rendering Context.
*/
setToContext: function(ctx) {
ctx.setTransform(this);
return ctx;
},
/**
* Copy the values in this Matrix to the array given.
*
* Where array indexes 0, 1, 2, 3, 4 and 5 are mapped to a, b, c, d, e and f.
*
* @method Phaser.GameObjects.Components.TransformMatrix#copyToArray
* @since 3.12.0
*
* @param {array} [out] - The array to copy the matrix values in to.
*
* @return {array} An array where elements 0 to 5 contain the values from this matrix.
*/
copyToArray: function(out) {
var matrix = this.matrix;
if (out === void 0) {
out = [matrix[0], matrix[1], matrix[2], matrix[3], matrix[4], matrix[5]];
} else {
out[0] = matrix[0];
out[1] = matrix[1];
out[2] = matrix[2];
out[3] = matrix[3];
out[4] = matrix[4];
out[5] = matrix[5];
}
return out;
},
/**
* Set the values of this Matrix.
*
* @method Phaser.GameObjects.Components.TransformMatrix#setTransform
* @since 3.0.0
*
* @param {number} a - The Scale X value.
* @param {number} b - The Shear Y value.
* @param {number} c - The Shear X value.
* @param {number} d - The Scale Y value.
* @param {number} tx - The Translate X value.
* @param {number} ty - The Translate Y value.
*
* @return {this} This TransformMatrix.
*/
setTransform: function(a, b, c, d, tx, ty) {
var matrix = this.matrix;
matrix[0] = a;
matrix[1] = b;
matrix[2] = c;
matrix[3] = d;
matrix[4] = tx;
matrix[5] = ty;
return this;
},
/**
* Decompose this Matrix into its translation, scale and rotation values using QR decomposition.
*
* The result must be applied in the following order to reproduce the current matrix:
*
* translate -> rotate -> scale
*
* @method Phaser.GameObjects.Components.TransformMatrix#decomposeMatrix
* @since 3.0.0
*
* @return {Phaser.Types.GameObjects.DecomposeMatrixResults} The decomposed Matrix.
*/
decomposeMatrix: function() {
var decomposedMatrix = this.decomposedMatrix;
var matrix = this.matrix;
var a = matrix[0];
var b = matrix[1];
var c = matrix[2];
var d = matrix[3];
var determ = a * d - b * c;
decomposedMatrix.translateX = matrix[4];
decomposedMatrix.translateY = matrix[5];
if (a || b) {
var r = Math.sqrt(a * a + b * b);
decomposedMatrix.rotation = b > 0 ? Math.acos(a / r) : -Math.acos(a / r);
decomposedMatrix.scaleX = r;
decomposedMatrix.scaleY = determ / r;
} else if (c || d) {
var s = Math.sqrt(c * c + d * d);
decomposedMatrix.rotation = Math.PI * 0.5 - (d > 0 ? Math.acos(-c / s) : -Math.acos(c / s));
decomposedMatrix.scaleX = determ / s;
decomposedMatrix.scaleY = s;
} else {
decomposedMatrix.rotation = 0;
decomposedMatrix.scaleX = 0;
decomposedMatrix.scaleY = 0;
}
return decomposedMatrix;
},
/**
* Apply the identity, translate, rotate and scale operations on the Matrix.
*
* @method Phaser.GameObjects.Components.TransformMatrix#applyITRS
* @since 3.0.0
*
* @param {number} x - The horizontal translation.
* @param {number} y - The vertical translation.
* @param {number} rotation - The angle of rotation in radians.
* @param {number} scaleX - The horizontal scale.
* @param {number} scaleY - The vertical scale.
*
* @return {this} This TransformMatrix.
*/
applyITRS: function(x, y, rotation, scaleX, scaleY) {
var matrix = this.matrix;
var radianSin = Math.sin(rotation);
var radianCos = Math.cos(rotation);
matrix[4] = x;
matrix[5] = y;
matrix[0] = radianCos * scaleX;
matrix[1] = radianSin * scaleX;
matrix[2] = -radianSin * scaleY;
matrix[3] = radianCos * scaleY;
return this;
},
/**
* Takes the `x` and `y` values and returns a new position in the `output` vector that is the inverse of
* the current matrix with its transformation applied.
*
* Can be used to translate points from world to local space.
*
* @method Phaser.GameObjects.Components.TransformMatrix#applyInverse
* @since 3.12.0
*
* @param {number} x - The x position to translate.
* @param {number} y - The y position to translate.
* @param {Phaser.Math.Vector2} [output] - A Vector2, or point-like object, to store the results in.
*
* @return {Phaser.Math.Vector2} The coordinates, inverse-transformed through this matrix.
*/
applyInverse: function(x, y, output) {
if (output === void 0) {
output = new Vector2();
}
var matrix = this.matrix;
var a = matrix[0];
var b = matrix[1];
var c = matrix[2];
var d = matrix[3];
var tx = matrix[4];
var ty = matrix[5];
var id = 1 / (a * d + c * -b);
output.x = d * id * x + -c * id * y + (ty * c - tx * d) * id;
output.y = a * id * y + -b * id * x + (-ty * a + tx * b) * id;
return output;
},
/**
* Performs the 8 calculations required to create the vertices of
* a quad based on this matrix and the given x/y/xw/yh values.
*
* The result is stored in `TransformMatrix.quad`, which is returned
* from this method.
*
* @method Phaser.GameObjects.Components.TransformMatrix#setQuad
* @since 3.60.0
*
* @param {number} x - The x value.
* @param {number} y - The y value.
* @param {number} xw - The xw value.
* @param {number} yh - The yh value.
* @param {boolean} [roundPixels=false] - Pass the results via Math.round?
* @param {Float32Array} [quad] - Optional Float32Array to store the results in. Otherwises uses the local quad array.
*
* @return {Float32Array} The quad Float32Array.
*/
setQuad: function(x, y, xw, yh, roundPixels, quad) {
if (roundPixels === void 0) {
roundPixels = false;
}
if (quad === void 0) {
quad = this.quad;
}
var matrix = this.matrix;
var a = matrix[0];
var b = matrix[1];
var c = matrix[2];
var d = matrix[3];
var e = matrix[4];
var f = matrix[5];
var x0 = x * a + y * c + e;
var y0 = x * b + y * d + f;
var x1 = x * a + yh * c + e;
var y1 = x * b + yh * d + f;
var x2 = xw * a + yh * c + e;
var y2 = xw * b + yh * d + f;
var x3 = xw * a + y * c + e;
var y3 = xw * b + y * d + f;
if (roundPixels) {
var rx0 = Math.floor(x0 + 0.5);
var ry0 = Math.floor(y0 + 0.5);
var dx = rx0 - x0;
var dy = ry0 - y0;
quad[0] = rx0;
quad[1] = ry0;
quad[2] = x1 + dx;
quad[3] = y1 + dy;
quad[4] = x2 + dx;
quad[5] = y2 + dy;
quad[6] = x3 + dx;
quad[7] = y3 + dy;
} else {
quad[0] = x0;
quad[1] = y0;
quad[2] = x1;
quad[3] = y1;
quad[4] = x2;
quad[5] = y2;
quad[6] = x3;
quad[7] = y3;
}
return quad;
},
/**
* Returns the X component of this matrix multiplied by the given values.
* This is the same as `x * a + y * c + e`.
*
* @method Phaser.GameObjects.Components.TransformMatrix#getX
* @since 3.12.0
*
* @param {number} x - The x value.
* @param {number} y - The y value.
*
* @return {number} The calculated x value.
*/
getX: function(x, y) {
return x * this.a + y * this.c + this.e;
},
/**
* Returns the Y component of this matrix multiplied by the given values.
* This is the same as `x * b + y * d + f`.
*
* @method Phaser.GameObjects.Components.TransformMatrix#getY
* @since 3.12.0
*
* @param {number} x - The x value.
* @param {number} y - The y value.
*
* @return {number} The calculated y value.
*/
getY: function(x, y) {
return x * this.b + y * this.d + this.f;
},
/**
* Returns the X component of this matrix multiplied by the given values.
*
* This is the same as `x * a + y * c + e`, optionally passing via `Math.round`.
*
* @method Phaser.GameObjects.Components.TransformMatrix#getXRound
* @since 3.50.0
*
* @param {number} x - The x value.
* @param {number} y - The y value.
* @param {boolean} [round=false] - Math.round the resulting value?
*
* @return {number} The calculated x value.
*/
getXRound: function(x, y, round) {
var v = this.getX(x, y);
if (round) {
v = Math.floor(v + 0.5);
}
return v;
},
/**
* Returns the Y component of this matrix multiplied by the given values.
*
* This is the same as `x * b + y * d + f`, optionally passing via `Math.round`.
*
* @method Phaser.GameObjects.Components.TransformMatrix#getYRound
* @since 3.50.0
*
* @param {number} x - The x value.
* @param {number} y - The y value.
* @param {boolean} [round=false] - Math.round the resulting value?
*
* @return {number} The calculated y value.
*/
getYRound: function(x, y, round) {
var v = this.getY(x, y);
if (round) {
v = Math.floor(v + 0.5);
}
return v;
},
/**
* Returns a string that can be used in a CSS Transform call as a `matrix` property.
*
* @method Phaser.GameObjects.Components.TransformMatrix#getCSSMatrix
* @since 3.12.0
*
* @return {string} A string containing the CSS Transform matrix values.
*/
getCSSMatrix: function() {
var m = this.matrix;
return "matrix(" + m[0] + "," + m[1] + "," + m[2] + "," + m[3] + "," + m[4] + "," + m[5] + ")";
},
/**
* Destroys this Transform Matrix.
*
* @method Phaser.GameObjects.Components.TransformMatrix#destroy
* @since 3.4.0
*/
destroy: function() {
this.matrix = null;
this.quad = null;
this.decomposedMatrix = null;
}
});
module2.exports = TransformMatrix;
}
),
/***/
59715: (
/***/
(module2) => {
var _FLAG = 1;
var Visible = {
/**
* Private internal value. Holds the visible value.
*
* @name Phaser.GameObjects.Components.Visible#_visible
* @type {boolean}
* @private
* @default true
* @since 3.0.0
*/
_visible: true,
/**
* The visible state of the Game Object.
*
* An invisible Game Object will skip rendering, but will still process update logic.
*
* @name Phaser.GameObjects.Components.Visible#visible
* @type {boolean}
* @since 3.0.0
*/
visible: {
get: function() {
return this._visible;
},
set: function(value) {
if (value) {
this._visible = true;
this.renderFlags |= _FLAG;
} else {
this._visible = false;
this.renderFlags &= ~_FLAG;
}
}
},
/**
* Sets the visibility of this Game Object.
*
* An invisible Game Object will skip rendering, but will still process update logic.
*
* @method Phaser.GameObjects.Components.Visible#setVisible
* @since 3.0.0
*
* @param {boolean} value - The visible state of the Game Object.
*
* @return {this} This Game Object instance.
*/
setVisible: function(value) {
this.visible = value;
return this;
}
};
module2.exports = Visible;
}
),
/***/
31401: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Alpha: __webpack_require__2(16005),
AlphaSingle: __webpack_require__2(88509),
BlendMode: __webpack_require__2(90065),
ComputedSize: __webpack_require__2(94215),
Crop: __webpack_require__2(61683),
Depth: __webpack_require__2(89272),
Flip: __webpack_require__2(54434),
FX: __webpack_require__2(47059),
GetBounds: __webpack_require__2(8004),
Mask: __webpack_require__2(8573),
Origin: __webpack_require__2(27387),
PathFollower: __webpack_require__2(37640),
Pipeline: __webpack_require__2(72699),
PostPipeline: __webpack_require__2(17581),
ScrollFactor: __webpack_require__2(80227),
Size: __webpack_require__2(16736),
Texture: __webpack_require__2(37726),
TextureCrop: __webpack_require__2(79812),
Tint: __webpack_require__2(27472),
ToJSON: __webpack_require__2(53774),
Transform: __webpack_require__2(16901),
TransformMatrix: __webpack_require__2(61340),
Visible: __webpack_require__2(59715)
};
}
),
/***/
31559: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var ArrayUtils = __webpack_require__2(37105);
var BlendModes = __webpack_require__2(10312);
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31401);
var Events = __webpack_require__2(51708);
var GameObject = __webpack_require__2(95643);
var Rectangle = __webpack_require__2(87841);
var Render = __webpack_require__2(29959);
var Union = __webpack_require__2(36899);
var Vector2 = __webpack_require__2(26099);
var tempTransformMatrix = new Components.TransformMatrix();
var Container = new Class({
Extends: GameObject,
Mixins: [
Components.AlphaSingle,
Components.BlendMode,
Components.ComputedSize,
Components.Depth,
Components.Mask,
Components.PostPipeline,
Components.Transform,
Components.Visible,
Render
],
initialize: function Container2(scene, x, y, children) {
GameObject.call(this, scene, "Container");
this.list = [];
this.exclusive = true;
this.maxSize = -1;
this.position = 0;
this.localTransform = new Components.TransformMatrix();
this._sortKey = "";
this._sysEvents = scene.sys.events;
this.scrollFactorX = 1;
this.scrollFactorY = 1;
this.initPostPipeline();
this.setPosition(x, y);
this.setBlendMode(BlendModes.SKIP_CHECK);
if (children) {
this.add(children);
}
},
/**
* Internal value to allow Containers to be used for input and physics.
* Do not change this value. It has no effect other than to break things.
*
* @name Phaser.GameObjects.Container#originX
* @type {number}
* @readonly
* @override
* @since 3.4.0
*/
originX: {
get: function() {
return 0.5;
}
},
/**
* Internal value to allow Containers to be used for input and physics.
* Do not change this value. It has no effect other than to break things.
*
* @name Phaser.GameObjects.Container#originY
* @type {number}
* @readonly
* @override
* @since 3.4.0
*/
originY: {
get: function() {
return 0.5;
}
},
/**
* Internal value to allow Containers to be used for input and physics.
* Do not change this value. It has no effect other than to break things.
*
* @name Phaser.GameObjects.Container#displayOriginX
* @type {number}
* @readonly
* @override
* @since 3.4.0
*/
displayOriginX: {
get: function() {
return this.width * 0.5;
}
},
/**
* Internal value to allow Containers to be used for input and physics.
* Do not change this value. It has no effect other than to break things.
*
* @name Phaser.GameObjects.Container#displayOriginY
* @type {number}
* @readonly
* @override
* @since 3.4.0
*/
displayOriginY: {
get: function() {
return this.height * 0.5;
}
},
/**
* Does this Container exclusively manage its children?
*
* The default is `true` which means a child added to this Container cannot
* belong in another Container, which includes the Scene display list.
*
* If you disable this then this Container will no longer exclusively manage its children.
* This allows you to create all kinds of interesting graphical effects, such as replicating
* Game Objects without reparenting them all over the Scene.
* However, doing so will prevent children from receiving any kind of input event or have
* their physics bodies work by default, as they're no longer a single entity on the
* display list, but are being replicated where-ever this Container is.
*
* @method Phaser.GameObjects.Container#setExclusive
* @since 3.4.0
*
* @param {boolean} [value=true] - The exclusive state of this Container.
*
* @return {this} This Container.
*/
setExclusive: function(value) {
if (value === void 0) {
value = true;
}
this.exclusive = value;
return this;
},
/**
* Gets the bounds of this Container. It works by iterating all children of the Container,
* getting their respective bounds, and then working out a min-max rectangle from that.
* It does not factor in if the children render or not, all are included.
*
* Some children are unable to return their bounds, such as Graphics objects, in which case
* they are skipped.
*
* Depending on the quantity of children in this Container it could be a really expensive call,
* so cache it and only poll it as needed.
*
* The values are stored and returned in a Rectangle object.
*
* @method Phaser.GameObjects.Container#getBounds
* @since 3.4.0
*
* @param {Phaser.Geom.Rectangle} [output] - A Geom.Rectangle object to store the values in. If not provided a new Rectangle will be created.
*
* @return {Phaser.Geom.Rectangle} The values stored in the output object.
*/
getBounds: function(output) {
if (output === void 0) {
output = new Rectangle();
}
output.setTo(this.x, this.y, 0, 0);
if (this.parentContainer) {
var parentMatrix = this.parentContainer.getBoundsTransformMatrix();
var transformedPosition = parentMatrix.transformPoint(this.x, this.y);
output.setTo(transformedPosition.x, transformedPosition.y, 0, 0);
}
if (this.list.length > 0) {
var children = this.list;
var tempRect = new Rectangle();
var hasSetFirst = false;
output.setEmpty();
for (var i = 0; i < children.length; i++) {
var entry = children[i];
if (entry.getBounds) {
entry.getBounds(tempRect);
if (!hasSetFirst) {
output.setTo(tempRect.x, tempRect.y, tempRect.width, tempRect.height);
hasSetFirst = true;
} else {
Union(tempRect, output, output);
}
}
}
}
return output;
},
/**
* Internal add handler.
*
* @method Phaser.GameObjects.Container#addHandler
* @private
* @since 3.4.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was just added to this Container.
*/
addHandler: function(gameObject) {
gameObject.once(Events.DESTROY, this.onChildDestroyed, this);
if (this.exclusive) {
if (gameObject.parentContainer) {
gameObject.parentContainer.remove(gameObject);
}
gameObject.parentContainer = this;
gameObject.removeFromDisplayList();
gameObject.addedToScene();
}
},
/**
* Internal remove handler.
*
* @method Phaser.GameObjects.Container#removeHandler
* @private
* @since 3.4.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was just removed from this Container.
*/
removeHandler: function(gameObject) {
gameObject.off(Events.DESTROY, this.remove, this);
if (this.exclusive) {
gameObject.parentContainer = null;
gameObject.removedFromScene();
gameObject.addToDisplayList();
}
},
/**
* Takes a Point-like object, such as a Vector2, Geom.Point or object with public x and y properties,
* and transforms it into the space of this Container, then returns it in the output object.
*
* @method Phaser.GameObjects.Container#pointToContainer
* @since 3.4.0
*
* @param {Phaser.Types.Math.Vector2Like} source - The Source Point to be transformed.
* @param {Phaser.Types.Math.Vector2Like} [output] - A destination object to store the transformed point in. If none given a Vector2 will be created and returned.
*
* @return {Phaser.Types.Math.Vector2Like} The transformed point.
*/
pointToContainer: function(source, output) {
if (output === void 0) {
output = new Vector2();
}
if (this.parentContainer) {
this.parentContainer.pointToContainer(source, output);
} else {
output.x = source.x;
output.y = source.y;
}
var tempMatrix = tempTransformMatrix;
tempMatrix.applyITRS(this.x, this.y, this.rotation, this.scaleX, this.scaleY);
tempMatrix.invert();
tempMatrix.transformPoint(source.x, source.y, output);
return output;
},
/**
* Returns the world transform matrix as used for Bounds checks.
*
* The returned matrix is temporal and shouldn't be stored.
*
* @method Phaser.GameObjects.Container#getBoundsTransformMatrix
* @since 3.4.0
*
* @return {Phaser.GameObjects.Components.TransformMatrix} The world transform matrix.
*/
getBoundsTransformMatrix: function() {
return this.getWorldTransformMatrix(tempTransformMatrix, this.localTransform);
},
/**
* Adds the given Game Object, or array of Game Objects, to this Container.
*
* Each Game Object must be unique within the Container.
*
* @method Phaser.GameObjects.Container#add
* @since 3.4.0
*
* @generic {Phaser.GameObjects.GameObject} T
* @genericUse {(T|T[])} - [child]
*
* @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} child - The Game Object, or array of Game Objects, to add to the Container.
*
* @return {this} This Container instance.
*/
add: function(child) {
ArrayUtils.Add(this.list, child, this.maxSize, this.addHandler, this);
return this;
},
/**
* Adds the given Game Object, or array of Game Objects, to this Container at the specified position.
*
* Existing Game Objects in the Container are shifted up.
*
* Each Game Object must be unique within the Container.
*
* @method Phaser.GameObjects.Container#addAt
* @since 3.4.0
*
* @generic {Phaser.GameObjects.GameObject} T
* @genericUse {(T|T[])} - [child]
*
* @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} child - The Game Object, or array of Game Objects, to add to the Container.
* @param {number} [index=0] - The position to insert the Game Object/s at.
*
* @return {this} This Container instance.
*/
addAt: function(child, index) {
ArrayUtils.AddAt(this.list, child, index, this.maxSize, this.addHandler, this);
return this;
},
/**
* Returns the Game Object at the given position in this Container.
*
* @method Phaser.GameObjects.Container#getAt
* @since 3.4.0
*
* @generic {Phaser.GameObjects.GameObject} T
* @genericUse {T} - [$return]
*
* @param {number} index - The position to get the Game Object from.
*
* @return {?Phaser.GameObjects.GameObject} The Game Object at the specified index, or `null` if none found.
*/
getAt: function(index) {
return this.list[index];
},
/**
* Returns the index of the given Game Object in this Container.
*
* @method Phaser.GameObjects.Container#getIndex
* @since 3.4.0
*
* @generic {Phaser.GameObjects.GameObject} T
* @genericUse {T} - [child]
*
* @param {Phaser.GameObjects.GameObject} child - The Game Object to search for in this Container.
*
* @return {number} The index of the Game Object in this Container, or -1 if not found.
*/
getIndex: function(child) {
return this.list.indexOf(child);
},
/**
* Sort the contents of this Container so the items are in order based on the given property.
* For example: `sort('alpha')` would sort the elements based on the value of their `alpha` property.
*
* @method Phaser.GameObjects.Container#sort
* @since 3.4.0
*
* @param {string} property - The property to lexically sort by.
* @param {function} [handler] - Provide your own custom handler function. Will receive 2 children which it should compare and return a boolean.
*
* @return {this} This Container instance.
*/
sort: function(property, handler) {
if (!property) {
return this;
}
if (handler === void 0) {
handler = function(childA, childB) {
return childA[property] - childB[property];
};
}
ArrayUtils.StableSort(this.list, handler);
return this;
},
/**
* Searches for the first instance of a child with its `name` property matching the given argument.
* Should more than one child have the same name only the first is returned.
*
* @method Phaser.GameObjects.Container#getByName
* @since 3.4.0
*
* @generic {Phaser.GameObjects.GameObject} T
* @genericUse {T} - [$return]
*
* @param {string} name - The name to search for.
*
* @return {?Phaser.GameObjects.GameObject} The first child with a matching name, or `null` if none were found.
*/
getByName: function(name) {
return ArrayUtils.GetFirst(this.list, "name", name);
},
/**
* Returns a random Game Object from this Container.
*
* @method Phaser.GameObjects.Container#getRandom
* @since 3.4.0
*
* @generic {Phaser.GameObjects.GameObject} T
* @genericUse {T} - [$return]
*
* @param {number} [startIndex=0] - An optional start index.
* @param {number} [length] - An optional length, the total number of elements (from the startIndex) to choose from.
*
* @return {?Phaser.GameObjects.GameObject} A random child from the Container, or `null` if the Container is empty.
*/
getRandom: function(startIndex, length) {
return ArrayUtils.GetRandom(this.list, startIndex, length);
},
/**
* Gets the first Game Object in this Container.
*
* You can also specify a property and value to search for, in which case it will return the first
* Game Object in this Container with a matching property and / or value.
*
* For example: `getFirst('visible', true)` would return the first Game Object that had its `visible` property set.
*
* You can limit the search to the `startIndex` - `endIndex` range.
*
* @method Phaser.GameObjects.Container#getFirst
* @since 3.4.0
*
* @generic {Phaser.GameObjects.GameObject} T
* @genericUse {T} - [$return]
*
* @param {string} property - The property to test on each Game Object in the Container.
* @param {*} value - The value to test the property against. Must pass a strict (`===`) comparison check.
* @param {number} [startIndex=0] - An optional start index to search from.
* @param {number} [endIndex=Container.length] - An optional end index to search up to (but not included)
*
* @return {?Phaser.GameObjects.GameObject} The first matching Game Object, or `null` if none was found.
*/
getFirst: function(property, value, startIndex, endIndex) {
return ArrayUtils.GetFirst(this.list, property, value, startIndex, endIndex);
},
/**
* Returns all Game Objects in this Container.
*
* You can optionally specify a matching criteria using the `property` and `value` arguments.
*
* For example: `getAll('body')` would return only Game Objects that have a body property.
*
* You can also specify a value to compare the property to:
*
* `getAll('visible', true)` would return only Game Objects that have their visible property set to `true`.
*
* Optionally you can specify a start and end index. For example if this Container had 100 Game Objects,
* and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only
* the first 50 Game Objects.
*
* @method Phaser.GameObjects.Container#getAll
* @since 3.4.0
*
* @generic {Phaser.GameObjects.GameObject} T
* @genericUse {T[]} - [$return]
*
* @param {string} [property] - The property to test on each Game Object in the Container.
* @param {any} [value] - If property is set then the `property` must strictly equal this value to be included in the results.
* @param {number} [startIndex=0] - An optional start index to search from.
* @param {number} [endIndex=Container.length] - An optional end index to search up to (but not included)
*
* @return {Phaser.GameObjects.GameObject[]} An array of matching Game Objects from this Container.
*/
getAll: function(property, value, startIndex, endIndex) {
return ArrayUtils.GetAll(this.list, property, value, startIndex, endIndex);
},
/**
* Returns the total number of Game Objects in this Container that have a property
* matching the given value.
*
* For example: `count('visible', true)` would count all the elements that have their visible property set.
*
* You can optionally limit the operation to the `startIndex` - `endIndex` range.
*
* @method Phaser.GameObjects.Container#count
* @since 3.4.0
*
* @param {string} property - The property to check.
* @param {any} value - The value to check.
* @param {number} [startIndex=0] - An optional start index to search from.
* @param {number} [endIndex=Container.length] - An optional end index to search up to (but not included)
*
* @return {number} The total number of Game Objects in this Container with a property matching the given value.
*/
count: function(property, value, startIndex, endIndex) {
return ArrayUtils.CountAllMatching(this.list, property, value, startIndex, endIndex);
},
/**
* Swaps the position of two Game Objects in this Container.
* Both Game Objects must belong to this Container.
*
* @method Phaser.GameObjects.Container#swap
* @since 3.4.0
*
* @generic {Phaser.GameObjects.GameObject} T
* @genericUse {T} - [child1,child2]
*
* @param {Phaser.GameObjects.GameObject} child1 - The first Game Object to swap.
* @param {Phaser.GameObjects.GameObject} child2 - The second Game Object to swap.
*
* @return {this} This Container instance.
*/
swap: function(child1, child2) {
ArrayUtils.Swap(this.list, child1, child2);
return this;
},
/**
* Moves a Game Object to a new position within this Container.
*
* The Game Object must already be a child of this Container.
*
* The Game Object is removed from its old position and inserted into the new one.
* Therefore the Container size does not change. Other children will change position accordingly.
*
* @method Phaser.GameObjects.Container#moveTo
* @since 3.4.0
*
* @generic {Phaser.GameObjects.GameObject} T
* @genericUse {T} - [child]
*
* @param {Phaser.GameObjects.GameObject} child - The Game Object to move.
* @param {number} index - The new position of the Game Object in this Container.
*
* @return {this} This Container instance.
*/
moveTo: function(child, index) {
ArrayUtils.MoveTo(this.list, child, index);
return this;
},
/**
* Moves a Game Object above another one within this Container.
* If the Game Object is already above the other, it isn't moved.
*
* These 2 Game Objects must already be children of this Container.
*
* @method Phaser.GameObjects.Container#moveAbove
* @since 3.55.0
*
* @generic {Phaser.GameObjects.GameObject} T
* @genericUse {T} - [child1,child2]
*
* @param {Phaser.GameObjects.GameObject} child1 - The Game Object to move above base Game Object.
* @param {Phaser.GameObjects.GameObject} child2 - The base Game Object.
*
* @return {this} This Container instance.
*/
moveAbove: function(child1, child2) {
ArrayUtils.MoveAbove(this.list, child1, child2);
return this;
},
/**
* Moves a Game Object below another one within this Container.
* If the Game Object is already below the other, it isn't moved.
*
* These 2 Game Objects must already be children of this Container.
*
* @method Phaser.GameObjects.Container#moveBelow
* @since 3.55.0
*
* @generic {Phaser.GameObjects.GameObject} T
* @genericUse {T} - [child1,child2]
*
* @param {Phaser.GameObjects.GameObject} child1 - The Game Object to move below base Game Object.
* @param {Phaser.GameObjects.GameObject} child2 - The base Game Object.
*
* @return {this} This Container instance.
*/
moveBelow: function(child1, child2) {
ArrayUtils.MoveBelow(this.list, child1, child2);
return this;
},
/**
* Removes the given Game Object, or array of Game Objects, from this Container.
*
* The Game Objects must already be children of this Container.
*
* You can also optionally call `destroy` on each Game Object that is removed from the Container.
*
* @method Phaser.GameObjects.Container#remove
* @since 3.4.0
*
* @generic {Phaser.GameObjects.GameObject} T
* @genericUse {(T|T[])} - [child]
*
* @param {Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]} child - The Game Object, or array of Game Objects, to be removed from the Container.
* @param {boolean} [destroyChild=false] - Optionally call `destroy` on each child successfully removed from this Container.
*
* @return {this} This Container instance.
*/
remove: function(child, destroyChild) {
var removed = ArrayUtils.Remove(this.list, child, this.removeHandler, this);
if (destroyChild && removed) {
if (!Array.isArray(removed)) {
removed = [removed];
}
for (var i = 0; i < removed.length; i++) {
removed[i].destroy();
}
}
return this;
},
/**
* Removes the Game Object at the given position in this Container.
*
* You can also optionally call `destroy` on the Game Object, if one is found.
*
* @method Phaser.GameObjects.Container#removeAt
* @since 3.4.0
*
* @param {number} index - The index of the Game Object to be removed.
* @param {boolean} [destroyChild=false] - Optionally call `destroy` on the Game Object if successfully removed from this Container.
*
* @return {this} This Container instance.
*/
removeAt: function(index, destroyChild) {
var removed = ArrayUtils.RemoveAt(this.list, index, this.removeHandler, this);
if (destroyChild && removed) {
removed.destroy();
}
return this;
},
/**
* Removes the Game Objects between the given positions in this Container.
*
* You can also optionally call `destroy` on each Game Object that is removed from the Container.
*
* @method Phaser.GameObjects.Container#removeBetween
* @since 3.4.0
*
* @param {number} [startIndex=0] - An optional start index to search from.
* @param {number} [endIndex=Container.length] - An optional end index to search up to (but not included)
* @param {boolean} [destroyChild=false] - Optionally call `destroy` on each Game Object successfully removed from this Container.
*
* @return {this} This Container instance.
*/
removeBetween: function(startIndex, endIndex, destroyChild) {
var removed = ArrayUtils.RemoveBetween(this.list, startIndex, endIndex, this.removeHandler, this);
if (destroyChild) {
for (var i = 0; i < removed.length; i++) {
removed[i].destroy();
}
}
return this;
},
/**
* Removes all Game Objects from this Container.
*
* You can also optionally call `destroy` on each Game Object that is removed from the Container.
*
* @method Phaser.GameObjects.Container#removeAll
* @since 3.4.0
*
* @param {boolean} [destroyChild=false] - Optionally call `destroy` on each Game Object successfully removed from this Container.
*
* @return {this} This Container instance.
*/
removeAll: function(destroyChild) {
var list = this.list;
if (destroyChild) {
for (var i = 0; i < list.length; i++) {
if (list[i] && list[i].scene) {
list[i].off(Events.DESTROY, this.onChildDestroyed, this);
list[i].destroy();
}
}
this.list = [];
} else {
ArrayUtils.RemoveBetween(list, 0, list.length, this.removeHandler, this);
}
return this;
},
/**
* Brings the given Game Object to the top of this Container.
* This will cause it to render on-top of any other objects in the Container.
*
* @method Phaser.GameObjects.Container#bringToTop
* @since 3.4.0
*
* @generic {Phaser.GameObjects.GameObject} T
* @genericUse {T} - [child]
*
* @param {Phaser.GameObjects.GameObject} child - The Game Object to bring to the top of the Container.
*
* @return {this} This Container instance.
*/
bringToTop: function(child) {
ArrayUtils.BringToTop(this.list, child);
return this;
},
/**
* Sends the given Game Object to the bottom of this Container.
* This will cause it to render below any other objects in the Container.
*
* @method Phaser.GameObjects.Container#sendToBack
* @since 3.4.0
*
* @generic {Phaser.GameObjects.GameObject} T
* @genericUse {T} - [child]
*
* @param {Phaser.GameObjects.GameObject} child - The Game Object to send to the bottom of the Container.
*
* @return {this} This Container instance.
*/
sendToBack: function(child) {
ArrayUtils.SendToBack(this.list, child);
return this;
},
/**
* Moves the given Game Object up one place in this Container, unless it's already at the top.
*
* @method Phaser.GameObjects.Container#moveUp
* @since 3.4.0
*
* @generic {Phaser.GameObjects.GameObject} T
* @genericUse {T} - [child]
*
* @param {Phaser.GameObjects.GameObject} child - The Game Object to be moved in the Container.
*
* @return {this} This Container instance.
*/
moveUp: function(child) {
ArrayUtils.MoveUp(this.list, child);
return this;
},
/**
* Moves the given Game Object down one place in this Container, unless it's already at the bottom.
*
* @method Phaser.GameObjects.Container#moveDown
* @since 3.4.0
*
* @generic {Phaser.GameObjects.GameObject} T
* @genericUse {T} - [child]
*
* @param {Phaser.GameObjects.GameObject} child - The Game Object to be moved in the Container.
*
* @return {this} This Container instance.
*/
moveDown: function(child) {
ArrayUtils.MoveDown(this.list, child);
return this;
},
/**
* Reverses the order of all Game Objects in this Container.
*
* @method Phaser.GameObjects.Container#reverse
* @since 3.4.0
*
* @return {this} This Container instance.
*/
reverse: function() {
this.list.reverse();
return this;
},
/**
* Shuffles the all Game Objects in this Container using the Fisher-Yates implementation.
*
* @method Phaser.GameObjects.Container#shuffle
* @since 3.4.0
*
* @return {this} This Container instance.
*/
shuffle: function() {
ArrayUtils.Shuffle(this.list);
return this;
},
/**
* Replaces a Game Object in this Container with the new Game Object.
* The new Game Object cannot already be a child of this Container.
*
* @method Phaser.GameObjects.Container#replace
* @since 3.4.0
*
* @generic {Phaser.GameObjects.GameObject} T
* @genericUse {T} - [oldChild,newChild]
*
* @param {Phaser.GameObjects.GameObject} oldChild - The Game Object in this Container that will be replaced.
* @param {Phaser.GameObjects.GameObject} newChild - The Game Object to be added to this Container.
* @param {boolean} [destroyChild=false] - Optionally call `destroy` on the Game Object if successfully removed from this Container.
*
* @return {this} This Container instance.
*/
replace: function(oldChild, newChild, destroyChild) {
var moved = ArrayUtils.Replace(this.list, oldChild, newChild);
if (moved) {
this.addHandler(newChild);
this.removeHandler(oldChild);
if (destroyChild) {
oldChild.destroy();
}
}
return this;
},
/**
* Returns `true` if the given Game Object is a direct child of this Container.
*
* This check does not scan nested Containers.
*
* @method Phaser.GameObjects.Container#exists
* @since 3.4.0
*
* @generic {Phaser.GameObjects.GameObject} T
* @genericUse {T} - [child]
*
* @param {Phaser.GameObjects.GameObject} child - The Game Object to check for within this Container.
*
* @return {boolean} True if the Game Object is an immediate child of this Container, otherwise false.
*/
exists: function(child) {
return this.list.indexOf(child) > -1;
},
/**
* Sets the property to the given value on all Game Objects in this Container.
*
* Optionally you can specify a start and end index. For example if this Container had 100 Game Objects,
* and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only
* the first 50 Game Objects.
*
* @method Phaser.GameObjects.Container#setAll
* @since 3.4.0
*
* @param {string} property - The property that must exist on the Game Object.
* @param {any} value - The value to get the property to.
* @param {number} [startIndex=0] - An optional start index to search from.
* @param {number} [endIndex=Container.length] - An optional end index to search up to (but not included)
*
* @return {this} This Container instance.
*/
setAll: function(property, value, startIndex, endIndex) {
ArrayUtils.SetAll(this.list, property, value, startIndex, endIndex);
return this;
},
/**
* @callback EachContainerCallback
* @generic I - [item]
*
* @param {*} item - The child Game Object of the Container.
* @param {...*} [args] - Additional arguments that will be passed to the callback, after the child.
*/
/**
* Passes all Game Objects in this Container to the given callback.
*
* A copy of the Container is made before passing each entry to your callback.
* This protects against the callback itself modifying the Container.
*
* If you know for sure that the callback will not change the size of this Container
* then you can use the more performant `Container.iterate` method instead.
*
* @method Phaser.GameObjects.Container#each
* @since 3.4.0
*
* @param {function} callback - The function to call.
* @param {object} [context] - Value to use as `this` when executing callback.
* @param {...*} [args] - Additional arguments that will be passed to the callback, after the child.
*
* @return {this} This Container instance.
*/
each: function(callback, context) {
var args = [null];
var i;
var temp = this.list.slice();
var len = temp.length;
for (i = 2; i < arguments.length; i++) {
args.push(arguments[i]);
}
for (i = 0; i < len; i++) {
args[0] = temp[i];
callback.apply(context, args);
}
return this;
},
/**
* Passes all Game Objects in this Container to the given callback.
*
* Only use this method when you absolutely know that the Container will not be modified during
* the iteration, i.e. by removing or adding to its contents.
*
* @method Phaser.GameObjects.Container#iterate
* @since 3.4.0
*
* @param {function} callback - The function to call.
* @param {object} [context] - Value to use as `this` when executing callback.
* @param {...*} [args] - Additional arguments that will be passed to the callback, after the child.
*
* @return {this} This Container instance.
*/
iterate: function(callback, context) {
var args = [null];
var i;
for (i = 2; i < arguments.length; i++) {
args.push(arguments[i]);
}
for (i = 0; i < this.list.length; i++) {
args[0] = this.list[i];
callback.apply(context, args);
}
return this;
},
/**
* Sets the scroll factor of this Container and optionally all of its children.
*
* The scroll factor controls the influence of the movement of a Camera upon this Game Object.
*
* When a camera scrolls it will change the location at which this Game Object is rendered on-screen.
* It does not change the Game Objects actual position values.
*
* A value of 1 means it will move exactly in sync with a camera.
* A value of 0 means it will not move at all, even if the camera moves.
* Other values control the degree to which the camera movement is mapped to this Game Object.
*
* Please be aware that scroll factor values other than 1 are not taken in to consideration when
* calculating physics collisions. Bodies always collide based on their world position, but changing
* the scroll factor is a visual adjustment to where the textures are rendered, which can offset
* them from physics bodies if not accounted for in your code.
*
* @method Phaser.GameObjects.Container#setScrollFactor
* @since 3.4.0
*
* @param {number} x - The horizontal scroll factor of this Game Object.
* @param {number} [y=x] - The vertical scroll factor of this Game Object. If not set it will use the `x` value.
* @param {boolean} [updateChildren=false] - Apply this scrollFactor to all Container children as well?
*
* @return {this} This Game Object instance.
*/
setScrollFactor: function(x, y, updateChildren) {
if (y === void 0) {
y = x;
}
if (updateChildren === void 0) {
updateChildren = false;
}
this.scrollFactorX = x;
this.scrollFactorY = y;
if (updateChildren) {
ArrayUtils.SetAll(this.list, "scrollFactorX", x);
ArrayUtils.SetAll(this.list, "scrollFactorY", y);
}
return this;
},
/**
* The number of Game Objects inside this Container.
*
* @name Phaser.GameObjects.Container#length
* @type {number}
* @readonly
* @since 3.4.0
*/
length: {
get: function() {
return this.list.length;
}
},
/**
* Returns the first Game Object within the Container, or `null` if it is empty.
*
* You can move the cursor by calling `Container.next` and `Container.previous`.
*
* @name Phaser.GameObjects.Container#first
* @type {?Phaser.GameObjects.GameObject}
* @readonly
* @since 3.4.0
*/
first: {
get: function() {
this.position = 0;
if (this.list.length > 0) {
return this.list[0];
} else {
return null;
}
}
},
/**
* Returns the last Game Object within the Container, or `null` if it is empty.
*
* You can move the cursor by calling `Container.next` and `Container.previous`.
*
* @name Phaser.GameObjects.Container#last
* @type {?Phaser.GameObjects.GameObject}
* @readonly
* @since 3.4.0
*/
last: {
get: function() {
if (this.list.length > 0) {
this.position = this.list.length - 1;
return this.list[this.position];
} else {
return null;
}
}
},
/**
* Returns the next Game Object within the Container, or `null` if it is empty.
*
* You can move the cursor by calling `Container.next` and `Container.previous`.
*
* @name Phaser.GameObjects.Container#next
* @type {?Phaser.GameObjects.GameObject}
* @readonly
* @since 3.4.0
*/
next: {
get: function() {
if (this.position < this.list.length) {
this.position++;
return this.list[this.position];
} else {
return null;
}
}
},
/**
* Returns the previous Game Object within the Container, or `null` if it is empty.
*
* You can move the cursor by calling `Container.next` and `Container.previous`.
*
* @name Phaser.GameObjects.Container#previous
* @type {?Phaser.GameObjects.GameObject}
* @readonly
* @since 3.4.0
*/
previous: {
get: function() {
if (this.position > 0) {
this.position--;
return this.list[this.position];
} else {
return null;
}
}
},
/**
* Internal destroy handler, called as part of the destroy process.
*
* @method Phaser.GameObjects.Container#preDestroy
* @protected
* @since 3.9.0
*/
preDestroy: function() {
this.removeAll(!!this.exclusive);
this.localTransform.destroy();
this.list = [];
},
/**
* Internal handler, called when a child is destroyed.
*
* @method Phaser.GameObjects.Container#onChildDestroyed
* @protected
* @since 3.80.0
*/
onChildDestroyed: function(gameObject) {
ArrayUtils.Remove(this.list, gameObject);
if (this.exclusive) {
gameObject.parentContainer = null;
gameObject.removedFromScene();
}
}
});
module2.exports = Container;
}
),
/***/
53584: (
/***/
(module2) => {
var ContainerCanvasRenderer = function(renderer, container, camera, parentMatrix) {
camera.addToRenderList(container);
var children = container.list;
if (children.length === 0) {
return;
}
var transformMatrix = container.localTransform;
if (parentMatrix) {
transformMatrix.loadIdentity();
transformMatrix.multiply(parentMatrix);
transformMatrix.translate(container.x, container.y);
transformMatrix.rotate(container.rotation);
transformMatrix.scale(container.scaleX, container.scaleY);
} else {
transformMatrix.applyITRS(container.x, container.y, container.rotation, container.scaleX, container.scaleY);
}
var containerHasBlendMode = container.blendMode !== -1;
if (!containerHasBlendMode) {
renderer.setBlendMode(0);
}
var alpha = container._alpha;
var scrollFactorX = container.scrollFactorX;
var scrollFactorY = container.scrollFactorY;
if (container.mask) {
container.mask.preRenderCanvas(renderer, null, camera);
}
for (var i = 0; i < children.length; i++) {
var child = children[i];
if (!child.willRender(camera)) {
continue;
}
var childAlpha = child.alpha;
var childScrollFactorX = child.scrollFactorX;
var childScrollFactorY = child.scrollFactorY;
if (!containerHasBlendMode && child.blendMode !== renderer.currentBlendMode) {
renderer.setBlendMode(child.blendMode);
}
child.setScrollFactor(childScrollFactorX * scrollFactorX, childScrollFactorY * scrollFactorY);
child.setAlpha(childAlpha * alpha);
child.renderCanvas(renderer, child, camera, transformMatrix);
child.setAlpha(childAlpha);
child.setScrollFactor(childScrollFactorX, childScrollFactorY);
}
if (container.mask) {
container.mask.postRenderCanvas(renderer);
}
};
module2.exports = ContainerCanvasRenderer;
}
),
/***/
77143: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var BuildGameObject = __webpack_require__2(25305);
var Container = __webpack_require__2(31559);
var GameObjectCreator = __webpack_require__2(44603);
var GetAdvancedValue = __webpack_require__2(23568);
var GetFastValue = __webpack_require__2(95540);
GameObjectCreator.register("container", function(config, addToScene) {
if (config === void 0) {
config = {};
}
var x = GetAdvancedValue(config, "x", 0);
var y = GetAdvancedValue(config, "y", 0);
var children = GetFastValue(config, "children", null);
var container = new Container(this.scene, x, y, children);
if (addToScene !== void 0) {
config.add = addToScene;
}
BuildGameObject(this.scene, container, config);
return container;
});
}
),
/***/
24961: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var Container = __webpack_require__2(31559);
var GameObjectFactory = __webpack_require__2(39429);
GameObjectFactory.register("container", function(x, y, children) {
return this.displayList.add(new Container(this.scene, x, y, children));
});
}
),
/***/
29959: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(72249);
}
if (true) {
renderCanvas = __webpack_require__2(53584);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
72249: (
/***/
(module2) => {
var ContainerWebGLRenderer = function(renderer, container, camera, parentMatrix) {
camera.addToRenderList(container);
var children = container.list;
var childCount = children.length;
if (childCount === 0) {
return;
}
var transformMatrix = container.localTransform;
if (parentMatrix) {
transformMatrix.loadIdentity();
transformMatrix.multiply(parentMatrix);
transformMatrix.translate(container.x, container.y);
transformMatrix.rotate(container.rotation);
transformMatrix.scale(container.scaleX, container.scaleY);
} else {
transformMatrix.applyITRS(container.x, container.y, container.rotation, container.scaleX, container.scaleY);
}
renderer.pipelines.preBatch(container);
var containerHasBlendMode = container.blendMode !== -1;
if (!containerHasBlendMode) {
renderer.setBlendMode(0);
}
var alpha = container.alpha;
var scrollFactorX = container.scrollFactorX;
var scrollFactorY = container.scrollFactorY;
for (var i = 0; i < childCount; i++) {
var child = children[i];
if (!child.willRender(camera)) {
continue;
}
var childAlphaTopLeft;
var childAlphaTopRight;
var childAlphaBottomLeft;
var childAlphaBottomRight;
if (child.alphaTopLeft !== void 0) {
childAlphaTopLeft = child.alphaTopLeft;
childAlphaTopRight = child.alphaTopRight;
childAlphaBottomLeft = child.alphaBottomLeft;
childAlphaBottomRight = child.alphaBottomRight;
} else {
var childAlpha = child.alpha;
childAlphaTopLeft = childAlpha;
childAlphaTopRight = childAlpha;
childAlphaBottomLeft = childAlpha;
childAlphaBottomRight = childAlpha;
}
var childScrollFactorX = child.scrollFactorX;
var childScrollFactorY = child.scrollFactorY;
if (!containerHasBlendMode && child.blendMode !== renderer.currentBlendMode) {
renderer.setBlendMode(child.blendMode);
}
var mask = child.mask;
if (mask) {
mask.preRenderWebGL(renderer, child, camera);
}
var type = child.type;
if (type !== renderer.currentType) {
renderer.newType = true;
renderer.currentType = type;
}
renderer.nextTypeMatch = i < childCount - 1 ? children[i + 1].type === renderer.currentType : false;
child.setScrollFactor(childScrollFactorX * scrollFactorX, childScrollFactorY * scrollFactorY);
child.setAlpha(childAlphaTopLeft * alpha, childAlphaTopRight * alpha, childAlphaBottomLeft * alpha, childAlphaBottomRight * alpha);
child.renderWebGL(renderer, child, camera, transformMatrix, container);
child.setAlpha(childAlphaTopLeft, childAlphaTopRight, childAlphaBottomLeft, childAlphaBottomRight);
child.setScrollFactor(childScrollFactorX, childScrollFactorY);
if (mask) {
mask.postRenderWebGL(renderer, camera);
}
renderer.newType = false;
}
renderer.pipelines.postBatch(container);
};
module2.exports = ContainerWebGLRenderer;
}
),
/***/
47407: (
/***/
(module2) => {
module2.exports = [
"normal",
"multiply",
"multiply",
"screen",
"overlay",
"darken",
"lighten",
"color-dodge",
"color-burn",
"hard-light",
"soft-light",
"difference",
"exclusion",
"hue",
"saturation",
"color",
"luminosity"
];
}
),
/***/
3069: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31401);
var DOMElementRender = __webpack_require__2(441);
var GameObject = __webpack_require__2(95643);
var IsPlainObject = __webpack_require__2(41212);
var RemoveFromDOM = __webpack_require__2(35846);
var SCENE_EVENTS = __webpack_require__2(44594);
var Vector4 = __webpack_require__2(61369);
var DOMElement = new Class({
Extends: GameObject,
Mixins: [
Components.AlphaSingle,
Components.BlendMode,
Components.Depth,
Components.Origin,
Components.ScrollFactor,
Components.Transform,
Components.Visible,
DOMElementRender
],
initialize: function DOMElement2(scene, x, y, element, style, innerText) {
GameObject.call(this, scene, "DOMElement");
this.parent = scene.sys.game.domContainer;
this.cache = scene.sys.cache.html;
this.node;
this.transformOnly = false;
this.skewX = 0;
this.skewY = 0;
this.rotate3d = new Vector4();
this.rotate3dAngle = "deg";
this.pointerEvents = "auto";
this.width = 0;
this.height = 0;
this.displayWidth = 0;
this.displayHeight = 0;
this.handler = this.dispatchNativeEvent.bind(this);
this.setPosition(x, y);
if (typeof element === "string") {
if (element[0] === "#") {
this.setElement(element.substr(1), style, innerText);
} else {
this.createElement(element, style, innerText);
}
} else if (element) {
this.setElement(element, style, innerText);
}
scene.sys.events.on(SCENE_EVENTS.SLEEP, this.handleSceneEvent, this);
scene.sys.events.on(SCENE_EVENTS.WAKE, this.handleSceneEvent, this);
scene.sys.events.on(SCENE_EVENTS.PRE_RENDER, this.preRender, this);
},
/**
* Handles a Scene Sleep and Wake event.
*
* @method Phaser.GameObjects.DOMElement#handleSceneEvent
* @private
* @since 3.22.0
*
* @param {Phaser.Scenes.Systems} sys - The Scene Systems.
*/
handleSceneEvent: function(sys) {
var node = this.node;
var style = node.style;
if (node) {
style.display = sys.settings.visible ? "block" : "none";
}
},
/**
* Sets the horizontal and vertical skew values of this DOM Element.
*
* For more information see: https://developer.mozilla.org/en-US/docs/Web/CSS/transform
*
* @method Phaser.GameObjects.DOMElement#setSkew
* @since 3.17.0
*
* @param {number} [x=0] - The angle, in radians, by which to skew the DOM Element on the horizontal axis.
* @param {number} [y=x] - The angle, in radians, by which to skew the DOM Element on the vertical axis.
*
* @return {this} This DOM Element instance.
*/
setSkew: function(x, y) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = x;
}
this.skewX = x;
this.skewY = y;
return this;
},
/**
* Sets the perspective CSS property of the _parent DOM Container_. This determines the distance between the z=0
* plane and the user in order to give a 3D-positioned element some perspective. Each 3D element with
* z > 0 becomes larger; each 3D-element with z < 0 becomes smaller. The strength of the effect is determined
* by the value of this property.
*
* For more information see: https://developer.mozilla.org/en-US/docs/Web/CSS/perspective
*
* **Changing this value changes it globally for all DOM Elements, as they all share the same parent container.**
*
* @method Phaser.GameObjects.DOMElement#setPerspective
* @since 3.17.0
*
* @param {number} value - The perspective value, in pixels, that determines the distance between the z plane and the user.
*
* @return {this} This DOM Element instance.
*/
setPerspective: function(value) {
this.parent.style.perspective = value + "px";
return this;
},
/**
* The perspective CSS property value of the _parent DOM Container_. This determines the distance between the z=0
* plane and the user in order to give a 3D-positioned element some perspective. Each 3D element with
* z > 0 becomes larger; each 3D-element with z < 0 becomes smaller. The strength of the effect is determined
* by the value of this property.
*
* For more information see: https://developer.mozilla.org/en-US/docs/Web/CSS/perspective
*
* **Changing this value changes it globally for all DOM Elements, as they all share the same parent container.**
*
* @name Phaser.GameObjects.DOMElement#perspective
* @type {number}
* @since 3.17.0
*/
perspective: {
get: function() {
return parseFloat(this.parent.style.perspective);
},
set: function(value) {
this.parent.style.perspective = value + "px";
}
},
/**
* Adds one or more native DOM event listeners onto the underlying Element of this Game Object.
* The event is then dispatched via this Game Objects standard event emitter.
*
* For example:
*
* ```javascript
* var div = this.add.dom(x, y, element);
*
* div.addListener('click');
*
* div.on('click', handler);
* ```
*
* @method Phaser.GameObjects.DOMElement#addListener
* @since 3.17.0
*
* @param {string} events - The DOM event/s to listen for. You can specify multiple events by separating them with spaces.
*
* @return {this} This DOM Element instance.
*/
addListener: function(events) {
if (this.node) {
events = events.split(" ");
for (var i = 0; i < events.length; i++) {
this.node.addEventListener(events[i], this.handler, false);
}
}
return this;
},
/**
* Removes one or more native DOM event listeners from the underlying Element of this Game Object.
*
* @method Phaser.GameObjects.DOMElement#removeListener
* @since 3.17.0
*
* @param {string} events - The DOM event/s to stop listening for. You can specify multiple events by separating them with spaces.
*
* @return {this} This DOM Element instance.
*/
removeListener: function(events) {
if (this.node) {
events = events.split(" ");
for (var i = 0; i < events.length; i++) {
this.node.removeEventListener(events[i], this.handler);
}
}
return this;
},
/**
* Internal event proxy to dispatch native DOM Events via this Game Object.
*
* @method Phaser.GameObjects.DOMElement#dispatchNativeEvent
* @private
* @since 3.17.0
*
* @param {any} event - The native DOM event.
*/
dispatchNativeEvent: function(event) {
this.emit(event.type, event);
},
/**
* Creates a native DOM Element, adds it to the parent DOM Container and then binds it to this Game Object,
* so you can control it. The `tagName` should be a string and is passed to `document.createElement`:
*
* ```javascript
* this.add.dom().createElement('div');
* ```
*
* For more details on acceptable tag names see: https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement
*
* You can also pass in a DOMString or style object to set the CSS on the created element, and an optional `innerText`
* value as well. Here is an example of a DOMString:
*
* ```javascript
* this.add.dom().createElement('div', 'background-color: lime; width: 220px; height: 100px; font: 48px Arial', 'Phaser');
* ```
*
* And using a style object:
*
* ```javascript
* var style = {
* 'background-color': 'lime';
* 'width': '200px';
* 'height': '100px';
* 'font': '48px Arial';
* };
*
* this.add.dom().createElement('div', style, 'Phaser');
* ```
*
* If this Game Object already has an Element, it is removed from the DOM entirely first.
* Any event listeners you may have previously created will need to be re-created after this call.
*
* @method Phaser.GameObjects.DOMElement#createElement
* @since 3.17.0
*
* @param {string} tagName - A string that specifies the type of element to be created. The nodeName of the created element is initialized with the value of tagName. Don't use qualified names (like "html:a") with this method.
* @param {(string|any)} [style] - Either a DOMString that holds the CSS styles to be applied to the created element, or an object the styles will be ready from.
* @param {string} [innerText] - A DOMString that holds the text that will be set as the innerText of the created element.
*
* @return {this} This DOM Element instance.
*/
createElement: function(tagName, style, innerText) {
return this.setElement(document.createElement(tagName), style, innerText);
},
/**
* Binds a new DOM Element to this Game Object. If this Game Object already has an Element it is removed from the DOM
* entirely first. Any event listeners you may have previously created will need to be re-created on the new element.
*
* The `element` argument you pass to this method can be either a string tagName:
*
* ```javascript
* <h1 id="heading">Phaser</h1>
*
* this.add.dom().setElement('heading');
* ```
*
* Or a reference to an Element instance:
*
* ```javascript
* <h1 id="heading">Phaser</h1>
*
* var h1 = document.getElementById('heading');
*
* this.add.dom().setElement(h1);
* ```
*
* You can also pass in a DOMString or style object to set the CSS on the created element, and an optional `innerText`
* value as well. Here is an example of a DOMString:
*
* ```javascript
* this.add.dom().setElement(h1, 'background-color: lime; width: 220px; height: 100px; font: 48px Arial', 'Phaser');
* ```
*
* And using a style object:
*
* ```javascript
* var style = {
* 'background-color': 'lime';
* 'width': '200px';
* 'height': '100px';
* 'font': '48px Arial';
* };
*
* this.add.dom().setElement(h1, style, 'Phaser');
* ```
*
* @method Phaser.GameObjects.DOMElement#setElement
* @since 3.17.0
*
* @param {(string|Element)} element - If a string it is passed to `getElementById()`, or it should be a reference to an existing Element.
* @param {(string|any)} [style] - Either a DOMString that holds the CSS styles to be applied to the created element, or an object the styles will be ready from.
* @param {string} [innerText] - A DOMString that holds the text that will be set as the innerText of the created element.
*
* @return {this} This DOM Element instance.
*/
setElement: function(element, style, innerText) {
this.removeElement();
var target;
if (typeof element === "string") {
if (element[0] === "#") {
element = element.substr(1);
}
target = document.getElementById(element);
} else if (typeof element === "object" && element.nodeType === 1) {
target = element;
}
if (!target) {
return this;
}
this.node = target;
if (style && IsPlainObject(style)) {
for (var key in style) {
target.style[key] = style[key];
}
} else if (typeof style === "string") {
target.style = style;
}
target.style.zIndex = "0";
target.style.display = "inline";
target.style.position = "absolute";
target.phaser = this;
if (this.parent) {
this.parent.appendChild(target);
}
if (innerText) {
target.innerText = innerText;
}
return this.updateSize();
},
/**
* Takes a block of html from the HTML Cache, that has previously been preloaded into the game, and then
* creates a DOM Element from it. The loaded HTML is set as the `innerHTML` property of the created
* element.
*
* Assume the following html is stored in a file called `loginform.html`:
*
* ```html
* <input type="text" name="nameField" placeholder="Enter your name" style="font-size: 32px">
* <input type="button" name="playButton" value="Let's Play" style="font-size: 32px">
* ```
*
* Which is loaded into your game using the cache key 'login':
*
* ```javascript
* this.load.html('login', 'assets/loginform.html');
* ```
*
* You can create a DOM Element from it using the cache key:
*
* ```javascript
* this.add.dom().createFromCache('login');
* ```
*
* The optional `elementType` argument controls the container that is created, into which the loaded html is inserted.
* The default is a plain `div` object, but any valid tagName can be given.
*
* If this Game Object already has an Element, it is removed from the DOM entirely first.
* Any event listeners you may have previously created will need to be re-created after this call.
*
* @method Phaser.GameObjects.DOMElement#createFromCache
* @since 3.17.0
*
* @param {string} The key of the html cache entry to use for this DOM Element.
* @param {string} [tagName='div'] - The tag name of the element into which all of the loaded html will be inserted. Defaults to a plain div tag.
*
* @return {this} This DOM Element instance.
*/
createFromCache: function(key, tagName) {
var html = this.cache.get(key);
if (html) {
this.createFromHTML(html, tagName);
}
return this;
},
/**
* Takes a string of html and then creates a DOM Element from it. The HTML is set as the `innerHTML`
* property of the created element.
*
* ```javascript
* let form = `
* <input type="text" name="nameField" placeholder="Enter your name" style="font-size: 32px">
* <input type="button" name="playButton" value="Let's Play" style="font-size: 32px">
* `;
* ```
*
* You can create a DOM Element from it using the string:
*
* ```javascript
* this.add.dom().createFromHTML(form);
* ```
*
* The optional `elementType` argument controls the type of container that is created, into which the html is inserted.
* The default is a plain `div` object, but any valid tagName can be given.
*
* If this Game Object already has an Element, it is removed from the DOM entirely first.
* Any event listeners you may have previously created will need to be re-created after this call.
*
* @method Phaser.GameObjects.DOMElement#createFromHTML
* @since 3.17.0
*
* @param {string} html - A string of html to be set as the `innerHTML` property of the created element.
* @param {string} [tagName='div'] - The tag name of the element into which all of the html will be inserted. Defaults to a plain div tag.
*
* @return {this} This DOM Element instance.
*/
createFromHTML: function(html, tagName) {
if (tagName === void 0) {
tagName = "div";
}
this.removeElement();
var element = document.createElement(tagName);
this.node = element;
element.style.zIndex = "0";
element.style.display = "inline";
element.style.position = "absolute";
element.phaser = this;
if (this.parent) {
this.parent.appendChild(element);
}
element.innerHTML = html;
return this.updateSize();
},
/**
* Removes the current DOM Element bound to this Game Object from the DOM entirely and resets the
* `node` property of this Game Object to be `null`.
*
* @method Phaser.GameObjects.DOMElement#removeElement
* @since 3.17.0
*
* @return {this} This DOM Element instance.
*/
removeElement: function() {
if (this.node) {
RemoveFromDOM(this.node);
this.node = null;
}
return this;
},
/**
* Internal method that calls `getBoundingClientRect` on the `node` and then sets the bounds width
* and height into the `displayWidth` and `displayHeight` properties, and the `clientWidth` and `clientHeight`
* values into the `width` and `height` properties respectively.
*
* This is called automatically whenever a new element is created or set.
*
* @method Phaser.GameObjects.DOMElement#updateSize
* @since 3.17.0
*
* @return {this} This DOM Element instance.
*/
updateSize: function() {
var node = this.node;
var nodeBounds = node.getBoundingClientRect();
this.width = node.clientWidth;
this.height = node.clientHeight;
this.displayWidth = nodeBounds.width || 0;
this.displayHeight = nodeBounds.height || 0;
return this;
},
/**
* Gets all children from this DOM Elements node, using `querySelectorAll('*')` and then iterates through
* them, looking for the first one that has a property matching the given key and value. It then returns this child
* if found, or `null` if not.
*
* @method Phaser.GameObjects.DOMElement#getChildByProperty
* @since 3.17.0
*
* @param {string} property - The property to search the children for.
* @param {string} value - The value the property must strictly equal.
*
* @return {?Element} The first matching child DOM Element, or `null` if not found.
*/
getChildByProperty: function(property, value) {
if (this.node) {
var children = this.node.querySelectorAll("*");
for (var i = 0; i < children.length; i++) {
if (children[i][property] === value) {
return children[i];
}
}
}
return null;
},
/**
* Gets all children from this DOM Elements node, using `querySelectorAll('*')` and then iterates through
* them, looking for the first one that has a matching id. It then returns this child if found, or `null` if not.
*
* Be aware that class and id names are case-sensitive.
*
* @method Phaser.GameObjects.DOMElement#getChildByID
* @since 3.17.0
*
* @param {string} id - The id to search the children for.
*
* @return {?Element} The first matching child DOM Element, or `null` if not found.
*/
getChildByID: function(id) {
return this.getChildByProperty("id", id);
},
/**
* Gets all children from this DOM Elements node, using `querySelectorAll('*')` and then iterates through
* them, looking for the first one that has a matching name. It then returns this child if found, or `null` if not.
*
* Be aware that class and id names are case-sensitive.
*
* @method Phaser.GameObjects.DOMElement#getChildByName
* @since 3.17.0
*
* @param {string} name - The name to search the children for.
*
* @return {?Element} The first matching child DOM Element, or `null` if not found.
*/
getChildByName: function(name) {
return this.getChildByProperty("name", name);
},
/**
* Sets the `className` property of the DOM Element node and updates the internal sizes.
*
* @method Phaser.GameObjects.DOMElement#setClassName
* @since 3.17.0
*
* @param {string} className - A string representing the class or space-separated classes of the element.
*
* @return {this} This DOM Element instance.
*/
setClassName: function(className) {
if (this.node) {
this.node.className = className;
this.updateSize();
}
return this;
},
/**
* Sets the `innerText` property of the DOM Element node and updates the internal sizes.
*
* Note that only certain types of Elements can have `innerText` set on them.
*
* @method Phaser.GameObjects.DOMElement#setText
* @since 3.17.0
*
* @param {string} text - A DOMString representing the rendered text content of the element.
*
* @return {this} This DOM Element instance.
*/
setText: function(text) {
if (this.node) {
this.node.innerText = text;
this.updateSize();
}
return this;
},
/**
* Sets the `innerHTML` property of the DOM Element node and updates the internal sizes.
*
* @method Phaser.GameObjects.DOMElement#setHTML
* @since 3.17.0
*
* @param {string} html - A DOMString of html to be set as the `innerHTML` property of the element.
*
* @return {this} This DOM Element instance.
*/
setHTML: function(html) {
if (this.node) {
this.node.innerHTML = html;
this.updateSize();
}
return this;
},
/**
* Runs internal update tasks.
*
* @method Phaser.GameObjects.DOMElement#preRender
* @private
* @since 3.60.0
*/
preRender: function() {
var parent = this.parentContainer;
var node = this.node;
if (node && parent && !parent.willRender()) {
node.style.display = "none";
}
},
/**
* Compares the renderMask with the renderFlags to see if this Game Object will render or not.
*
* DOMElements always return `true` as they need to still set values during the render pass, even if not visible.
*
* @method Phaser.GameObjects.DOMElement#willRender
* @since 3.17.0
*
* @return {boolean} `true` if the Game Object should be rendered, otherwise `false`.
*/
willRender: function() {
return true;
},
/**
* Handles the pre-destroy step for the DOM Element, which removes the underlying node from the DOM.
*
* @method Phaser.GameObjects.DOMElement#preDestroy
* @private
* @since 3.17.0
*/
preDestroy: function() {
this.removeElement();
this.scene.sys.events.off(SCENE_EVENTS.SLEEP, this.handleSceneEvent, this);
this.scene.sys.events.off(SCENE_EVENTS.WAKE, this.handleSceneEvent, this);
this.scene.sys.events.off(SCENE_EVENTS.PRE_RENDER, this.preRender, this);
}
});
module2.exports = DOMElement;
}
),
/***/
49381: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CSSBlendModes = __webpack_require__2(47407);
var GameObject = __webpack_require__2(95643);
var TransformMatrix = __webpack_require__2(61340);
var tempMatrix1 = new TransformMatrix();
var tempMatrix2 = new TransformMatrix();
var tempMatrix3 = new TransformMatrix();
var DOMElementCSSRenderer = function(renderer, src, camera, parentMatrix) {
if (!src.node) {
return;
}
var style = src.node.style;
var settings = src.scene.sys.settings;
if (!style || !settings.visible || GameObject.RENDER_MASK !== src.renderFlags || src.cameraFilter !== 0 && src.cameraFilter & camera.id || src.parentContainer && !src.parentContainer.willRender()) {
style.display = "none";
return;
}
var parent = src.parentContainer;
var alpha = camera.alpha * src.alpha;
if (parent) {
alpha *= parent.alpha;
}
var camMatrix = tempMatrix1;
var srcMatrix = tempMatrix2;
var calcMatrix = tempMatrix3;
var dx = 0;
var dy = 0;
var tx = "0%";
var ty = "0%";
if (parentMatrix) {
dx = src.width * src.scaleX * src.originX;
dy = src.height * src.scaleY * src.originY;
srcMatrix.applyITRS(src.x - dx, src.y - dy, src.rotation, src.scaleX, src.scaleY);
camMatrix.copyFrom(camera.matrix);
camMatrix.multiplyWithOffset(parentMatrix, -camera.scrollX * src.scrollFactorX, -camera.scrollY * src.scrollFactorY);
srcMatrix.e = src.x - dx;
srcMatrix.f = src.y - dy;
camMatrix.multiply(srcMatrix, calcMatrix);
} else {
dx = src.width * src.originX;
dy = src.height * src.originY;
srcMatrix.applyITRS(src.x, src.y, src.rotation, src.scaleX, src.scaleY);
camMatrix.copyFrom(camera.matrix);
tx = 100 * src.originX + "%";
ty = 100 * src.originY + "%";
srcMatrix.e -= camera.scrollX * src.scrollFactorX;
srcMatrix.f -= camera.scrollY * src.scrollFactorY;
camMatrix.multiply(srcMatrix, calcMatrix);
calcMatrix.e -= dx;
calcMatrix.f -= dy;
}
if (!src.transformOnly) {
style.display = "block";
style.opacity = alpha;
style.zIndex = src._depth;
style.pointerEvents = src.pointerEvents;
style.mixBlendMode = CSSBlendModes[src._blendMode];
}
style.transform = calcMatrix.getCSSMatrix() + " skew(" + src.skewX + "rad, " + src.skewY + "rad) rotate3d(" + src.rotate3d.x + "," + src.rotate3d.y + "," + src.rotate3d.z + "," + src.rotate3d.w + src.rotate3dAngle + ")";
style.transformOrigin = tx + " " + ty;
};
module2.exports = DOMElementCSSRenderer;
}
),
/***/
2611: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var DOMElement = __webpack_require__2(3069);
var GameObjectFactory = __webpack_require__2(39429);
GameObjectFactory.register("dom", function(x, y, element, style, innerText) {
var gameObject = new DOMElement(this.scene, x, y, element, style, innerText);
this.displayList.add(gameObject);
return gameObject;
});
}
),
/***/
441: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(49381);
}
if (true) {
renderCanvas = __webpack_require__2(49381);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
62980: (
/***/
(module2) => {
module2.exports = "addedtoscene";
}
),
/***/
41337: (
/***/
(module2) => {
module2.exports = "destroy";
}
),
/***/
44947: (
/***/
(module2) => {
module2.exports = "removedfromscene";
}
),
/***/
49358: (
/***/
(module2) => {
module2.exports = "complete";
}
),
/***/
35163: (
/***/
(module2) => {
module2.exports = "created";
}
),
/***/
97249: (
/***/
(module2) => {
module2.exports = "error";
}
),
/***/
19483: (
/***/
(module2) => {
module2.exports = "locked";
}
),
/***/
56059: (
/***/
(module2) => {
module2.exports = "loop";
}
),
/***/
26772: (
/***/
(module2) => {
module2.exports = "metadata";
}
),
/***/
64437: (
/***/
(module2) => {
module2.exports = "playing";
}
),
/***/
83411: (
/***/
(module2) => {
module2.exports = "play";
}
),
/***/
75780: (
/***/
(module2) => {
module2.exports = "seeked";
}
),
/***/
67799: (
/***/
(module2) => {
module2.exports = "seeking";
}
),
/***/
63500: (
/***/
(module2) => {
module2.exports = "stalled";
}
),
/***/
55541: (
/***/
(module2) => {
module2.exports = "stop";
}
),
/***/
53208: (
/***/
(module2) => {
module2.exports = "textureready";
}
),
/***/
4992: (
/***/
(module2) => {
module2.exports = "unlocked";
}
),
/***/
12: (
/***/
(module2) => {
module2.exports = "unsupported";
}
),
/***/
51708: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
ADDED_TO_SCENE: __webpack_require__2(62980),
DESTROY: __webpack_require__2(41337),
REMOVED_FROM_SCENE: __webpack_require__2(44947),
VIDEO_COMPLETE: __webpack_require__2(49358),
VIDEO_CREATED: __webpack_require__2(35163),
VIDEO_ERROR: __webpack_require__2(97249),
VIDEO_LOCKED: __webpack_require__2(19483),
VIDEO_LOOP: __webpack_require__2(56059),
VIDEO_METADATA: __webpack_require__2(26772),
VIDEO_PLAY: __webpack_require__2(83411),
VIDEO_PLAYING: __webpack_require__2(64437),
VIDEO_SEEKED: __webpack_require__2(75780),
VIDEO_SEEKING: __webpack_require__2(67799),
VIDEO_STALLED: __webpack_require__2(63500),
VIDEO_STOP: __webpack_require__2(55541),
VIDEO_TEXTURE: __webpack_require__2(53208),
VIDEO_UNLOCKED: __webpack_require__2(4992),
VIDEO_UNSUPPORTED: __webpack_require__2(12)
};
}
),
/***/
42421: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31401);
var GameObject = __webpack_require__2(95643);
var ExternRender = __webpack_require__2(64993);
var Extern = new Class({
Extends: GameObject,
Mixins: [
Components.Alpha,
Components.BlendMode,
Components.Depth,
Components.Flip,
Components.Origin,
Components.ScrollFactor,
Components.Size,
Components.Texture,
Components.Tint,
Components.Transform,
Components.Visible,
ExternRender
],
initialize: function Extern2(scene) {
GameObject.call(this, scene, "Extern");
},
// Overrides Game Object method
addedToScene: function() {
this.scene.sys.updateList.add(this);
},
// Overrides Game Object method
removedFromScene: function() {
this.scene.sys.updateList.remove(this);
},
preUpdate: function() {
},
render: function() {
}
});
module2.exports = Extern;
}
),
/***/
70217: (
/***/
() => {
}
),
/***/
56315: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var Extern = __webpack_require__2(42421);
var GameObjectFactory = __webpack_require__2(39429);
GameObjectFactory.register("extern", function() {
var extern = new Extern(this.scene);
this.displayList.add(extern);
return extern;
});
}
),
/***/
64993: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(80287);
}
if (true) {
renderCanvas = __webpack_require__2(70217);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
80287: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetCalcMatrix = __webpack_require__2(91296);
var ExternWebGLRenderer = function(renderer, src, camera, parentMatrix) {
renderer.pipelines.clear();
var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc;
src.render.call(src, renderer, camera, calcMatrix);
renderer.pipelines.rebind();
};
module2.exports = ExternWebGLRenderer;
}
),
/***/
85592: (
/***/
(module2) => {
module2.exports = {
ARC: 0,
BEGIN_PATH: 1,
CLOSE_PATH: 2,
FILL_RECT: 3,
LINE_TO: 4,
MOVE_TO: 5,
LINE_STYLE: 6,
FILL_STYLE: 7,
FILL_PATH: 8,
STROKE_PATH: 9,
FILL_TRIANGLE: 10,
STROKE_TRIANGLE: 11,
SAVE: 14,
RESTORE: 15,
TRANSLATE: 16,
SCALE: 17,
ROTATE: 18,
GRADIENT_FILL_STYLE: 21,
GRADIENT_LINE_STYLE: 22
};
}
),
/***/
43831: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BaseCamera = __webpack_require__2(71911);
var Class = __webpack_require__2(83419);
var Commands = __webpack_require__2(85592);
var Components = __webpack_require__2(31401);
var Ellipse = __webpack_require__2(8497);
var GameObject = __webpack_require__2(95643);
var GetFastValue = __webpack_require__2(95540);
var GetValue = __webpack_require__2(35154);
var MATH_CONST = __webpack_require__2(36383);
var Render = __webpack_require__2(84503);
var Graphics = new Class({
Extends: GameObject,
Mixins: [
Components.AlphaSingle,
Components.BlendMode,
Components.Depth,
Components.Mask,
Components.Pipeline,
Components.PostPipeline,
Components.Transform,
Components.Visible,
Components.ScrollFactor,
Render
],
initialize: function Graphics2(scene, options) {
var x = GetValue(options, "x", 0);
var y = GetValue(options, "y", 0);
GameObject.call(this, scene, "Graphics");
this.setPosition(x, y);
this.initPipeline();
this.initPostPipeline();
this.displayOriginX = 0;
this.displayOriginY = 0;
this.commandBuffer = [];
this.defaultFillColor = -1;
this.defaultFillAlpha = 1;
this.defaultStrokeWidth = 1;
this.defaultStrokeColor = -1;
this.defaultStrokeAlpha = 1;
this._lineWidth = 1;
this.lineStyle(1, 0, 0);
this.fillStyle(0, 0);
this.setDefaultStyles(options);
},
/**
* Set the default style settings for this Graphics object.
*
* @method Phaser.GameObjects.Graphics#setDefaultStyles
* @since 3.0.0
*
* @param {Phaser.Types.GameObjects.Graphics.Styles} options - The styles to set as defaults.
*
* @return {this} This Game Object.
*/
setDefaultStyles: function(options) {
if (GetValue(options, "lineStyle", null)) {
this.defaultStrokeWidth = GetValue(options, "lineStyle.width", 1);
this.defaultStrokeColor = GetValue(options, "lineStyle.color", 16777215);
this.defaultStrokeAlpha = GetValue(options, "lineStyle.alpha", 1);
this.lineStyle(this.defaultStrokeWidth, this.defaultStrokeColor, this.defaultStrokeAlpha);
}
if (GetValue(options, "fillStyle", null)) {
this.defaultFillColor = GetValue(options, "fillStyle.color", 16777215);
this.defaultFillAlpha = GetValue(options, "fillStyle.alpha", 1);
this.fillStyle(this.defaultFillColor, this.defaultFillAlpha);
}
return this;
},
/**
* Set the current line style. Used for all 'stroke' related functions.
*
* @method Phaser.GameObjects.Graphics#lineStyle
* @since 3.0.0
*
* @param {number} lineWidth - The stroke width.
* @param {number} color - The stroke color.
* @param {number} [alpha=1] - The stroke alpha.
*
* @return {this} This Game Object.
*/
lineStyle: function(lineWidth, color, alpha) {
if (alpha === void 0) {
alpha = 1;
}
this.commandBuffer.push(
Commands.LINE_STYLE,
lineWidth,
color,
alpha
);
this._lineWidth = lineWidth;
return this;
},
/**
* Set the current fill style. Used for all 'fill' related functions.
*
* @method Phaser.GameObjects.Graphics#fillStyle
* @since 3.0.0
*
* @param {number} color - The fill color.
* @param {number} [alpha=1] - The fill alpha.
*
* @return {this} This Game Object.
*/
fillStyle: function(color, alpha) {
if (alpha === void 0) {
alpha = 1;
}
this.commandBuffer.push(
Commands.FILL_STYLE,
color,
alpha
);
return this;
},
/**
* Sets a gradient fill style. This is a WebGL only feature.
*
* The gradient color values represent the 4 corners of an untransformed rectangle.
* The gradient is used to color all filled shapes and paths drawn after calling this method.
* If you wish to turn a gradient off, call `fillStyle` and provide a new single fill color.
*
* When filling a triangle only the first 3 color values provided are used for the 3 points of a triangle.
*
* This feature is best used only on rectangles and triangles. All other shapes will give strange results.
*
* Note that for objects such as arcs or ellipses, or anything which is made out of triangles, each triangle used
* will be filled with a gradient on its own. There is no ability to gradient fill a shape or path as a single
* entity at this time.
*
* @method Phaser.GameObjects.Graphics#fillGradientStyle
* @webglOnly
* @since 3.12.0
*
* @param {number} topLeft - The top left fill color.
* @param {number} topRight - The top right fill color.
* @param {number} bottomLeft - The bottom left fill color.
* @param {number} bottomRight - The bottom right fill color. Not used when filling triangles.
* @param {number} [alphaTopLeft=1] - The top left alpha value. If you give only this value, it's used for all corners.
* @param {number} [alphaTopRight=1] - The top right alpha value.
* @param {number} [alphaBottomLeft=1] - The bottom left alpha value.
* @param {number} [alphaBottomRight=1] - The bottom right alpha value.
*
* @return {this} This Game Object.
*/
fillGradientStyle: function(topLeft, topRight, bottomLeft, bottomRight, alphaTopLeft, alphaTopRight, alphaBottomLeft, alphaBottomRight) {
if (alphaTopLeft === void 0) {
alphaTopLeft = 1;
}
if (alphaTopRight === void 0) {
alphaTopRight = alphaTopLeft;
}
if (alphaBottomLeft === void 0) {
alphaBottomLeft = alphaTopLeft;
}
if (alphaBottomRight === void 0) {
alphaBottomRight = alphaTopLeft;
}
this.commandBuffer.push(
Commands.GRADIENT_FILL_STYLE,
alphaTopLeft,
alphaTopRight,
alphaBottomLeft,
alphaBottomRight,
topLeft,
topRight,
bottomLeft,
bottomRight
);
return this;
},
/**
* Sets a gradient line style. This is a WebGL only feature.
*
* The gradient color values represent the 4 corners of an untransformed rectangle.
* The gradient is used to color all stroked shapes and paths drawn after calling this method.
* If you wish to turn a gradient off, call `lineStyle` and provide a new single line color.
*
* This feature is best used only on single lines. All other shapes will give strange results.
*
* Note that for objects such as arcs or ellipses, or anything which is made out of triangles, each triangle used
* will be filled with a gradient on its own. There is no ability to gradient stroke a shape or path as a single
* entity at this time.
*
* @method Phaser.GameObjects.Graphics#lineGradientStyle
* @webglOnly
* @since 3.12.0
*
* @param {number} lineWidth - The stroke width.
* @param {number} topLeft - The tint being applied to the top-left of the Game Object.
* @param {number} topRight - The tint being applied to the top-right of the Game Object.
* @param {number} bottomLeft - The tint being applied to the bottom-left of the Game Object.
* @param {number} bottomRight - The tint being applied to the bottom-right of the Game Object.
* @param {number} [alpha=1] - The fill alpha.
*
* @return {this} This Game Object.
*/
lineGradientStyle: function(lineWidth, topLeft, topRight, bottomLeft, bottomRight, alpha) {
if (alpha === void 0) {
alpha = 1;
}
this.commandBuffer.push(
Commands.GRADIENT_LINE_STYLE,
lineWidth,
alpha,
topLeft,
topRight,
bottomLeft,
bottomRight
);
return this;
},
/**
* Start a new shape path.
*
* @method Phaser.GameObjects.Graphics#beginPath
* @since 3.0.0
*
* @return {this} This Game Object.
*/
beginPath: function() {
this.commandBuffer.push(
Commands.BEGIN_PATH
);
return this;
},
/**
* Close the current path.
*
* @method Phaser.GameObjects.Graphics#closePath
* @since 3.0.0
*
* @return {this} This Game Object.
*/
closePath: function() {
this.commandBuffer.push(
Commands.CLOSE_PATH
);
return this;
},
/**
* Fill the current path.
*
* @method Phaser.GameObjects.Graphics#fillPath
* @since 3.0.0
*
* @return {this} This Game Object.
*/
fillPath: function() {
this.commandBuffer.push(
Commands.FILL_PATH
);
return this;
},
/**
* Fill the current path.
*
* This is an alias for `Graphics.fillPath` and does the same thing.
* It was added to match the CanvasRenderingContext 2D API.
*
* @method Phaser.GameObjects.Graphics#fill
* @since 3.16.0
*
* @return {this} This Game Object.
*/
fill: function() {
this.commandBuffer.push(
Commands.FILL_PATH
);
return this;
},
/**
* Stroke the current path.
*
* @method Phaser.GameObjects.Graphics#strokePath
* @since 3.0.0
*
* @return {this} This Game Object.
*/
strokePath: function() {
this.commandBuffer.push(
Commands.STROKE_PATH
);
return this;
},
/**
* Stroke the current path.
*
* This is an alias for `Graphics.strokePath` and does the same thing.
* It was added to match the CanvasRenderingContext 2D API.
*
* @method Phaser.GameObjects.Graphics#stroke
* @since 3.16.0
*
* @return {this} This Game Object.
*/
stroke: function() {
this.commandBuffer.push(
Commands.STROKE_PATH
);
return this;
},
/**
* Fill the given circle.
*
* @method Phaser.GameObjects.Graphics#fillCircleShape
* @since 3.0.0
*
* @param {Phaser.Geom.Circle} circle - The circle to fill.
*
* @return {this} This Game Object.
*/
fillCircleShape: function(circle) {
return this.fillCircle(circle.x, circle.y, circle.radius);
},
/**
* Stroke the given circle.
*
* @method Phaser.GameObjects.Graphics#strokeCircleShape
* @since 3.0.0
*
* @param {Phaser.Geom.Circle} circle - The circle to stroke.
*
* @return {this} This Game Object.
*/
strokeCircleShape: function(circle) {
return this.strokeCircle(circle.x, circle.y, circle.radius);
},
/**
* Fill a circle with the given position and radius.
*
* @method Phaser.GameObjects.Graphics#fillCircle
* @since 3.0.0
*
* @param {number} x - The x coordinate of the center of the circle.
* @param {number} y - The y coordinate of the center of the circle.
* @param {number} radius - The radius of the circle.
*
* @return {this} This Game Object.
*/
fillCircle: function(x, y, radius) {
this.beginPath();
this.arc(x, y, radius, 0, MATH_CONST.PI2);
this.fillPath();
return this;
},
/**
* Stroke a circle with the given position and radius.
*
* @method Phaser.GameObjects.Graphics#strokeCircle
* @since 3.0.0
*
* @param {number} x - The x coordinate of the center of the circle.
* @param {number} y - The y coordinate of the center of the circle.
* @param {number} radius - The radius of the circle.
*
* @return {this} This Game Object.
*/
strokeCircle: function(x, y, radius) {
this.beginPath();
this.arc(x, y, radius, 0, MATH_CONST.PI2);
this.strokePath();
return this;
},
/**
* Fill the given rectangle.
*
* @method Phaser.GameObjects.Graphics#fillRectShape
* @since 3.0.0
*
* @param {Phaser.Geom.Rectangle} rect - The rectangle to fill.
*
* @return {this} This Game Object.
*/
fillRectShape: function(rect) {
return this.fillRect(rect.x, rect.y, rect.width, rect.height);
},
/**
* Stroke the given rectangle.
*
* @method Phaser.GameObjects.Graphics#strokeRectShape
* @since 3.0.0
*
* @param {Phaser.Geom.Rectangle} rect - The rectangle to stroke.
*
* @return {this} This Game Object.
*/
strokeRectShape: function(rect) {
return this.strokeRect(rect.x, rect.y, rect.width, rect.height);
},
/**
* Fill a rectangle with the given position and size.
*
* @method Phaser.GameObjects.Graphics#fillRect
* @since 3.0.0
*
* @param {number} x - The x coordinate of the top-left of the rectangle.
* @param {number} y - The y coordinate of the top-left of the rectangle.
* @param {number} width - The width of the rectangle.
* @param {number} height - The height of the rectangle.
*
* @return {this} This Game Object.
*/
fillRect: function(x, y, width, height) {
this.commandBuffer.push(
Commands.FILL_RECT,
x,
y,
width,
height
);
return this;
},
/**
* Stroke a rectangle with the given position and size.
*
* @method Phaser.GameObjects.Graphics#strokeRect
* @since 3.0.0
*
* @param {number} x - The x coordinate of the top-left of the rectangle.
* @param {number} y - The y coordinate of the top-left of the rectangle.
* @param {number} width - The width of the rectangle.
* @param {number} height - The height of the rectangle.
*
* @return {this} This Game Object.
*/
strokeRect: function(x, y, width, height) {
var lineWidthHalf = this._lineWidth / 2;
var minx = x - lineWidthHalf;
var maxx = x + lineWidthHalf;
this.beginPath();
this.moveTo(x, y);
this.lineTo(x, y + height);
this.strokePath();
this.beginPath();
this.moveTo(x + width, y);
this.lineTo(x + width, y + height);
this.strokePath();
this.beginPath();
this.moveTo(minx, y);
this.lineTo(maxx + width, y);
this.strokePath();
this.beginPath();
this.moveTo(minx, y + height);
this.lineTo(maxx + width, y + height);
this.strokePath();
return this;
},
/**
* Fill a rounded rectangle with the given position, size and radius.
*
* @method Phaser.GameObjects.Graphics#fillRoundedRect
* @since 3.11.0
*
* @param {number} x - The x coordinate of the top-left of the rectangle.
* @param {number} y - The y coordinate of the top-left of the rectangle.
* @param {number} width - The width of the rectangle.
* @param {number} height - The height of the rectangle.
* @param {(Phaser.Types.GameObjects.Graphics.RoundedRectRadius|number)} [radius=20] - The corner radius; It can also be an object to specify different radius for corners.
*
* @return {this} This Game Object.
*/
fillRoundedRect: function(x, y, width, height, radius) {
if (radius === void 0) {
radius = 20;
}
var tl = radius;
var tr = radius;
var bl = radius;
var br = radius;
if (typeof radius !== "number") {
tl = GetFastValue(radius, "tl", 20);
tr = GetFastValue(radius, "tr", 20);
bl = GetFastValue(radius, "bl", 20);
br = GetFastValue(radius, "br", 20);
}
var convexTL = tl >= 0;
var convexTR = tr >= 0;
var convexBL = bl >= 0;
var convexBR = br >= 0;
tl = Math.abs(tl);
tr = Math.abs(tr);
bl = Math.abs(bl);
br = Math.abs(br);
this.beginPath();
this.moveTo(x + tl, y);
this.lineTo(x + width - tr, y);
if (convexTR) {
this.arc(x + width - tr, y + tr, tr, -MATH_CONST.TAU, 0);
} else {
this.arc(x + width, y, tr, Math.PI, MATH_CONST.TAU, true);
}
this.lineTo(x + width, y + height - br);
if (convexBR) {
this.arc(x + width - br, y + height - br, br, 0, MATH_CONST.TAU);
} else {
this.arc(x + width, y + height, br, -MATH_CONST.TAU, Math.PI, true);
}
this.lineTo(x + bl, y + height);
if (convexBL) {
this.arc(x + bl, y + height - bl, bl, MATH_CONST.TAU, Math.PI);
} else {
this.arc(x, y + height, bl, 0, -MATH_CONST.TAU, true);
}
this.lineTo(x, y + tl);
if (convexTL) {
this.arc(x + tl, y + tl, tl, -Math.PI, -MATH_CONST.TAU);
} else {
this.arc(x, y, tl, MATH_CONST.TAU, 0, true);
}
this.fillPath();
return this;
},
/**
* Stroke a rounded rectangle with the given position, size and radius.
*
* @method Phaser.GameObjects.Graphics#strokeRoundedRect
* @since 3.11.0
*
* @param {number} x - The x coordinate of the top-left of the rectangle.
* @param {number} y - The y coordinate of the top-left of the rectangle.
* @param {number} width - The width of the rectangle.
* @param {number} height - The height of the rectangle.
* @param {(Phaser.Types.GameObjects.Graphics.RoundedRectRadius|number)} [radius=20] - The corner radius; It can also be an object to specify different radii for corners.
*
* @return {this} This Game Object.
*/
strokeRoundedRect: function(x, y, width, height, radius) {
if (radius === void 0) {
radius = 20;
}
var tl = radius;
var tr = radius;
var bl = radius;
var br = radius;
var maxRadius = Math.min(width, height) / 2;
if (typeof radius !== "number") {
tl = GetFastValue(radius, "tl", 20);
tr = GetFastValue(radius, "tr", 20);
bl = GetFastValue(radius, "bl", 20);
br = GetFastValue(radius, "br", 20);
}
var convexTL = tl >= 0;
var convexTR = tr >= 0;
var convexBL = bl >= 0;
var convexBR = br >= 0;
tl = Math.min(Math.abs(tl), maxRadius);
tr = Math.min(Math.abs(tr), maxRadius);
bl = Math.min(Math.abs(bl), maxRadius);
br = Math.min(Math.abs(br), maxRadius);
this.beginPath();
this.moveTo(x + tl, y);
this.lineTo(x + width - tr, y);
this.moveTo(x + width - tr, y);
if (convexTR) {
this.arc(x + width - tr, y + tr, tr, -MATH_CONST.TAU, 0);
} else {
this.arc(x + width, y, tr, Math.PI, MATH_CONST.TAU, true);
}
this.lineTo(x + width, y + height - br);
this.moveTo(x + width, y + height - br);
if (convexBR) {
this.arc(x + width - br, y + height - br, br, 0, MATH_CONST.TAU);
} else {
this.arc(x + width, y + height, br, -MATH_CONST.TAU, Math.PI, true);
}
this.lineTo(x + bl, y + height);
this.moveTo(x + bl, y + height);
if (convexBL) {
this.arc(x + bl, y + height - bl, bl, MATH_CONST.TAU, Math.PI);
} else {
this.arc(x, y + height, bl, 0, -MATH_CONST.TAU, true);
}
this.lineTo(x, y + tl);
this.moveTo(x, y + tl);
if (convexTL) {
this.arc(x + tl, y + tl, tl, -Math.PI, -MATH_CONST.TAU);
} else {
this.arc(x, y, tl, MATH_CONST.TAU, 0, true);
}
this.strokePath();
return this;
},
/**
* Fill the given point.
*
* Draws a square at the given position, 1 pixel in size by default.
*
* @method Phaser.GameObjects.Graphics#fillPointShape
* @since 3.0.0
*
* @param {(Phaser.Geom.Point|Phaser.Math.Vector2|object)} point - The point to fill.
* @param {number} [size=1] - The size of the square to draw.
*
* @return {this} This Game Object.
*/
fillPointShape: function(point, size) {
return this.fillPoint(point.x, point.y, size);
},
/**
* Fill a point at the given position.
*
* Draws a square at the given position, 1 pixel in size by default.
*
* @method Phaser.GameObjects.Graphics#fillPoint
* @since 3.0.0
*
* @param {number} x - The x coordinate of the point.
* @param {number} y - The y coordinate of the point.
* @param {number} [size=1] - The size of the square to draw.
*
* @return {this} This Game Object.
*/
fillPoint: function(x, y, size) {
if (!size || size < 1) {
size = 1;
} else {
x -= size / 2;
y -= size / 2;
}
this.commandBuffer.push(
Commands.FILL_RECT,
x,
y,
size,
size
);
return this;
},
/**
* Fill the given triangle.
*
* @method Phaser.GameObjects.Graphics#fillTriangleShape
* @since 3.0.0
*
* @param {Phaser.Geom.Triangle} triangle - The triangle to fill.
*
* @return {this} This Game Object.
*/
fillTriangleShape: function(triangle) {
return this.fillTriangle(triangle.x1, triangle.y1, triangle.x2, triangle.y2, triangle.x3, triangle.y3);
},
/**
* Stroke the given triangle.
*
* @method Phaser.GameObjects.Graphics#strokeTriangleShape
* @since 3.0.0
*
* @param {Phaser.Geom.Triangle} triangle - The triangle to stroke.
*
* @return {this} This Game Object.
*/
strokeTriangleShape: function(triangle) {
return this.strokeTriangle(triangle.x1, triangle.y1, triangle.x2, triangle.y2, triangle.x3, triangle.y3);
},
/**
* Fill a triangle with the given points.
*
* @method Phaser.GameObjects.Graphics#fillTriangle
* @since 3.0.0
*
* @param {number} x0 - The x coordinate of the first point.
* @param {number} y0 - The y coordinate of the first point.
* @param {number} x1 - The x coordinate of the second point.
* @param {number} y1 - The y coordinate of the second point.
* @param {number} x2 - The x coordinate of the third point.
* @param {number} y2 - The y coordinate of the third point.
*
* @return {this} This Game Object.
*/
fillTriangle: function(x0, y0, x1, y1, x2, y2) {
this.commandBuffer.push(
Commands.FILL_TRIANGLE,
x0,
y0,
x1,
y1,
x2,
y2
);
return this;
},
/**
* Stroke a triangle with the given points.
*
* @method Phaser.GameObjects.Graphics#strokeTriangle
* @since 3.0.0
*
* @param {number} x0 - The x coordinate of the first point.
* @param {number} y0 - The y coordinate of the first point.
* @param {number} x1 - The x coordinate of the second point.
* @param {number} y1 - The y coordinate of the second point.
* @param {number} x2 - The x coordinate of the third point.
* @param {number} y2 - The y coordinate of the third point.
*
* @return {this} This Game Object.
*/
strokeTriangle: function(x0, y0, x1, y1, x2, y2) {
this.commandBuffer.push(
Commands.STROKE_TRIANGLE,
x0,
y0,
x1,
y1,
x2,
y2
);
return this;
},
/**
* Draw the given line.
*
* @method Phaser.GameObjects.Graphics#strokeLineShape
* @since 3.0.0
*
* @param {Phaser.Geom.Line} line - The line to stroke.
*
* @return {this} This Game Object.
*/
strokeLineShape: function(line) {
return this.lineBetween(line.x1, line.y1, line.x2, line.y2);
},
/**
* Draw a line between the given points.
*
* @method Phaser.GameObjects.Graphics#lineBetween
* @since 3.0.0
*
* @param {number} x1 - The x coordinate of the start point of the line.
* @param {number} y1 - The y coordinate of the start point of the line.
* @param {number} x2 - The x coordinate of the end point of the line.
* @param {number} y2 - The y coordinate of the end point of the line.
*
* @return {this} This Game Object.
*/
lineBetween: function(x1, y1, x2, y2) {
this.beginPath();
this.moveTo(x1, y1);
this.lineTo(x2, y2);
this.strokePath();
return this;
},
/**
* Draw a line from the current drawing position to the given position.
*
* Moves the current drawing position to the given position.
*
* @method Phaser.GameObjects.Graphics#lineTo
* @since 3.0.0
*
* @param {number} x - The x coordinate to draw the line to.
* @param {number} y - The y coordinate to draw the line to.
*
* @return {this} This Game Object.
*/
lineTo: function(x, y) {
this.commandBuffer.push(
Commands.LINE_TO,
x,
y
);
return this;
},
/**
* Move the current drawing position to the given position.
*
* @method Phaser.GameObjects.Graphics#moveTo
* @since 3.0.0
*
* @param {number} x - The x coordinate to move to.
* @param {number} y - The y coordinate to move to.
*
* @return {this} This Game Object.
*/
moveTo: function(x, y) {
this.commandBuffer.push(
Commands.MOVE_TO,
x,
y
);
return this;
},
/**
* Stroke the shape represented by the given array of points.
*
* Pass `closeShape` to automatically close the shape by joining the last to the first point.
*
* Pass `closePath` to automatically close the path before it is stroked.
*
* @method Phaser.GameObjects.Graphics#strokePoints
* @since 3.0.0
*
* @param {(array|Phaser.Geom.Point[])} points - The points to stroke.
* @param {boolean} [closeShape=false] - When `true`, the shape is closed by joining the last point to the first point.
* @param {boolean} [closePath=false] - When `true`, the path is closed before being stroked.
* @param {number} [endIndex] - The index of `points` to stop drawing at. Defaults to `points.length`.
*
* @return {this} This Game Object.
*/
strokePoints: function(points, closeShape, closePath, endIndex) {
if (closeShape === void 0) {
closeShape = false;
}
if (closePath === void 0) {
closePath = false;
}
if (endIndex === void 0) {
endIndex = points.length;
}
this.beginPath();
this.moveTo(points[0].x, points[0].y);
for (var i = 1; i < endIndex; i++) {
this.lineTo(points[i].x, points[i].y);
}
if (closeShape) {
this.lineTo(points[0].x, points[0].y);
}
if (closePath) {
this.closePath();
}
this.strokePath();
return this;
},
/**
* Fill the shape represented by the given array of points.
*
* Pass `closeShape` to automatically close the shape by joining the last to the first point.
*
* Pass `closePath` to automatically close the path before it is filled.
*
* @method Phaser.GameObjects.Graphics#fillPoints
* @since 3.0.0
*
* @param {(array|Phaser.Geom.Point[])} points - The points to fill.
* @param {boolean} [closeShape=false] - When `true`, the shape is closed by joining the last point to the first point.
* @param {boolean} [closePath=false] - When `true`, the path is closed before being stroked.
* @param {number} [endIndex] - The index of `points` to stop at. Defaults to `points.length`.
*
* @return {this} This Game Object.
*/
fillPoints: function(points, closeShape, closePath, endIndex) {
if (closeShape === void 0) {
closeShape = false;
}
if (closePath === void 0) {
closePath = false;
}
if (endIndex === void 0) {
endIndex = points.length;
}
this.beginPath();
this.moveTo(points[0].x, points[0].y);
for (var i = 1; i < endIndex; i++) {
this.lineTo(points[i].x, points[i].y);
}
if (closeShape) {
this.lineTo(points[0].x, points[0].y);
}
if (closePath) {
this.closePath();
}
this.fillPath();
return this;
},
/**
* Stroke the given ellipse.
*
* @method Phaser.GameObjects.Graphics#strokeEllipseShape
* @since 3.0.0
*
* @param {Phaser.Geom.Ellipse} ellipse - The ellipse to stroke.
* @param {number} [smoothness=32] - The number of points to draw the ellipse with.
*
* @return {this} This Game Object.
*/
strokeEllipseShape: function(ellipse, smoothness) {
if (smoothness === void 0) {
smoothness = 32;
}
var points = ellipse.getPoints(smoothness);
return this.strokePoints(points, true);
},
/**
* Stroke an ellipse with the given position and size.
*
* @method Phaser.GameObjects.Graphics#strokeEllipse
* @since 3.0.0
*
* @param {number} x - The x coordinate of the center of the ellipse.
* @param {number} y - The y coordinate of the center of the ellipse.
* @param {number} width - The width of the ellipse.
* @param {number} height - The height of the ellipse.
* @param {number} [smoothness=32] - The number of points to draw the ellipse with.
*
* @return {this} This Game Object.
*/
strokeEllipse: function(x, y, width, height, smoothness) {
if (smoothness === void 0) {
smoothness = 32;
}
var ellipse = new Ellipse(x, y, width, height);
var points = ellipse.getPoints(smoothness);
return this.strokePoints(points, true);
},
/**
* Fill the given ellipse.
*
* @method Phaser.GameObjects.Graphics#fillEllipseShape
* @since 3.0.0
*
* @param {Phaser.Geom.Ellipse} ellipse - The ellipse to fill.
* @param {number} [smoothness=32] - The number of points to draw the ellipse with.
*
* @return {this} This Game Object.
*/
fillEllipseShape: function(ellipse, smoothness) {
if (smoothness === void 0) {
smoothness = 32;
}
var points = ellipse.getPoints(smoothness);
return this.fillPoints(points, true);
},
/**
* Fill an ellipse with the given position and size.
*
* @method Phaser.GameObjects.Graphics#fillEllipse
* @since 3.0.0
*
* @param {number} x - The x coordinate of the center of the ellipse.
* @param {number} y - The y coordinate of the center of the ellipse.
* @param {number} width - The width of the ellipse.
* @param {number} height - The height of the ellipse.
* @param {number} [smoothness=32] - The number of points to draw the ellipse with.
*
* @return {this} This Game Object.
*/
fillEllipse: function(x, y, width, height, smoothness) {
if (smoothness === void 0) {
smoothness = 32;
}
var ellipse = new Ellipse(x, y, width, height);
var points = ellipse.getPoints(smoothness);
return this.fillPoints(points, true);
},
/**
* Draw an arc.
*
* This method can be used to create circles, or parts of circles.
*
* Make sure you call `beginPath` before starting the arc unless you wish for the arc to automatically
* close when filled or stroked.
*
* Use the optional `overshoot` argument increase the number of iterations that take place when
* the arc is rendered in WebGL. This is useful if you're drawing an arc with an especially thick line,
* as it will allow the arc to fully join-up. Try small values at first, i.e. 0.01.
*
* Call {@link Phaser.GameObjects.Graphics#fillPath} or {@link Phaser.GameObjects.Graphics#strokePath} after calling
* this method to draw the arc.
*
* @method Phaser.GameObjects.Graphics#arc
* @since 3.0.0
*
* @param {number} x - The x coordinate of the center of the circle.
* @param {number} y - The y coordinate of the center of the circle.
* @param {number} radius - The radius of the circle.
* @param {number} startAngle - The starting angle, in radians.
* @param {number} endAngle - The ending angle, in radians.
* @param {boolean} [anticlockwise=false] - Whether the drawing should be anticlockwise or clockwise.
* @param {number} [overshoot=0] - This value allows you to increase the segment iterations in WebGL rendering. Useful if the arc has a thick stroke and needs to overshoot to join-up cleanly. Use small numbers such as 0.01 to start with and increase as needed.
*
* @return {this} This Game Object.
*/
arc: function(x, y, radius, startAngle, endAngle, anticlockwise, overshoot) {
if (anticlockwise === void 0) {
anticlockwise = false;
}
if (overshoot === void 0) {
overshoot = 0;
}
this.commandBuffer.push(
Commands.ARC,
x,
y,
radius,
startAngle,
endAngle,
anticlockwise,
overshoot
);
return this;
},
/**
* Creates a pie-chart slice shape centered at `x`, `y` with the given radius.
* You must define the start and end angle of the slice.
*
* Setting the `anticlockwise` argument to `true` creates a shape similar to Pacman.
* Setting it to `false` creates a shape like a slice of pie.
*
* This method will begin a new path and close the path at the end of it.
* To display the actual slice you need to call either `strokePath` or `fillPath` after it.
*
* @method Phaser.GameObjects.Graphics#slice
* @since 3.4.0
*
* @param {number} x - The horizontal center of the slice.
* @param {number} y - The vertical center of the slice.
* @param {number} radius - The radius of the slice.
* @param {number} startAngle - The start angle of the slice, given in radians.
* @param {number} endAngle - The end angle of the slice, given in radians.
* @param {boolean} [anticlockwise=false] - Whether the drawing should be anticlockwise or clockwise.
* @param {number} [overshoot=0] - This value allows you to overshoot the endAngle by this amount. Useful if the arc has a thick stroke and needs to overshoot to join-up cleanly.
*
* @return {this} This Game Object.
*/
slice: function(x, y, radius, startAngle, endAngle, anticlockwise, overshoot) {
if (anticlockwise === void 0) {
anticlockwise = false;
}
if (overshoot === void 0) {
overshoot = 0;
}
this.commandBuffer.push(Commands.BEGIN_PATH);
this.commandBuffer.push(Commands.MOVE_TO, x, y);
this.commandBuffer.push(Commands.ARC, x, y, radius, startAngle, endAngle, anticlockwise, overshoot);
this.commandBuffer.push(Commands.CLOSE_PATH);
return this;
},
/**
* Saves the state of the Graphics by pushing the current state onto a stack.
*
* The most recently saved state can then be restored with {@link Phaser.GameObjects.Graphics#restore}.
*
* @method Phaser.GameObjects.Graphics#save
* @since 3.0.0
*
* @return {this} This Game Object.
*/
save: function() {
this.commandBuffer.push(
Commands.SAVE
);
return this;
},
/**
* Restores the most recently saved state of the Graphics by popping from the state stack.
*
* Use {@link Phaser.GameObjects.Graphics#save} to save the current state, and call this afterwards to restore that state.
*
* If there is no saved state, this command does nothing.
*
* @method Phaser.GameObjects.Graphics#restore
* @since 3.0.0
*
* @return {this} This Game Object.
*/
restore: function() {
this.commandBuffer.push(
Commands.RESTORE
);
return this;
},
/**
* Inserts a translation command into this Graphics objects command buffer.
*
* All objects drawn _after_ calling this method will be translated
* by the given amount.
*
* This does not change the position of the Graphics object itself,
* only of the objects drawn by it after calling this method.
*
* @method Phaser.GameObjects.Graphics#translateCanvas
* @since 3.0.0
*
* @param {number} x - The horizontal translation to apply.
* @param {number} y - The vertical translation to apply.
*
* @return {this} This Game Object.
*/
translateCanvas: function(x, y) {
this.commandBuffer.push(
Commands.TRANSLATE,
x,
y
);
return this;
},
/**
* Inserts a scale command into this Graphics objects command buffer.
*
* All objects drawn _after_ calling this method will be scaled
* by the given amount.
*
* This does not change the scale of the Graphics object itself,
* only of the objects drawn by it after calling this method.
*
* @method Phaser.GameObjects.Graphics#scaleCanvas
* @since 3.0.0
*
* @param {number} x - The horizontal scale to apply.
* @param {number} y - The vertical scale to apply.
*
* @return {this} This Game Object.
*/
scaleCanvas: function(x, y) {
this.commandBuffer.push(
Commands.SCALE,
x,
y
);
return this;
},
/**
* Inserts a rotation command into this Graphics objects command buffer.
*
* All objects drawn _after_ calling this method will be rotated
* by the given amount.
*
* This does not change the rotation of the Graphics object itself,
* only of the objects drawn by it after calling this method.
*
* @method Phaser.GameObjects.Graphics#rotateCanvas
* @since 3.0.0
*
* @param {number} radians - The rotation angle, in radians.
*
* @return {this} This Game Object.
*/
rotateCanvas: function(radians) {
this.commandBuffer.push(
Commands.ROTATE,
radians
);
return this;
},
/**
* Clear the command buffer and reset the fill style and line style to their defaults.
*
* @method Phaser.GameObjects.Graphics#clear
* @since 3.0.0
*
* @return {this} This Game Object.
*/
clear: function() {
this.commandBuffer.length = 0;
if (this.defaultFillColor > -1) {
this.fillStyle(this.defaultFillColor, this.defaultFillAlpha);
}
if (this.defaultStrokeColor > -1) {
this.lineStyle(this.defaultStrokeWidth, this.defaultStrokeColor, this.defaultStrokeAlpha);
}
return this;
},
/**
* Generate a texture from this Graphics object.
*
* If `key` is a string it'll generate a new texture using it and add it into the
* Texture Manager (assuming no key conflict happens).
*
* If `key` is a Canvas it will draw the texture to that canvas context. Note that it will NOT
* automatically upload it to the GPU in WebGL mode.
*
* Please understand that the texture is created via the Canvas API of the browser, therefore some
* Graphics features, such as `fillGradientStyle`, will not appear on the resulting texture,
* as they're unsupported by the Canvas API.
*
* @method Phaser.GameObjects.Graphics#generateTexture
* @since 3.0.0
*
* @param {(string|HTMLCanvasElement)} key - The key to store the texture with in the Texture Manager, or a Canvas to draw to.
* @param {number} [width] - The width of the graphics to generate.
* @param {number} [height] - The height of the graphics to generate.
*
* @return {this} This Game Object.
*/
generateTexture: function(key, width, height) {
var sys = this.scene.sys;
var renderer = sys.game.renderer;
if (width === void 0) {
width = sys.scale.width;
}
if (height === void 0) {
height = sys.scale.height;
}
Graphics.TargetCamera.setScene(this.scene);
Graphics.TargetCamera.setViewport(0, 0, width, height);
Graphics.TargetCamera.scrollX = this.x;
Graphics.TargetCamera.scrollY = this.y;
var texture;
var ctx;
var willRead = { willReadFrequently: true };
if (typeof key === "string") {
if (sys.textures.exists(key)) {
texture = sys.textures.get(key);
var src = texture.getSourceImage();
if (src instanceof HTMLCanvasElement) {
ctx = src.getContext("2d", willRead);
}
} else {
texture = sys.textures.createCanvas(key, width, height);
ctx = texture.getSourceImage().getContext("2d", willRead);
}
} else if (key instanceof HTMLCanvasElement) {
ctx = key.getContext("2d", willRead);
}
if (ctx) {
this.renderCanvas(renderer, this, Graphics.TargetCamera, null, ctx, false);
if (texture) {
texture.refresh();
}
}
return this;
},
/**
* Internal destroy handler, called as part of the destroy process.
*
* @method Phaser.GameObjects.Graphics#preDestroy
* @protected
* @since 3.9.0
*/
preDestroy: function() {
this.commandBuffer = [];
}
});
Graphics.TargetCamera = new BaseCamera();
module2.exports = Graphics;
}
),
/***/
32768: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Commands = __webpack_require__2(85592);
var SetTransform = __webpack_require__2(20926);
var GraphicsCanvasRenderer = function(renderer, src, camera, parentMatrix, renderTargetCtx, allowClip) {
var commandBuffer = src.commandBuffer;
var commandBufferLength = commandBuffer.length;
var ctx = renderTargetCtx || renderer.currentContext;
if (commandBufferLength === 0 || !SetTransform(renderer, ctx, src, camera, parentMatrix)) {
return;
}
camera.addToRenderList(src);
var lineAlpha = 1;
var fillAlpha = 1;
var lineColor = 0;
var fillColor = 0;
var lineWidth = 1;
var red = 0;
var green = 0;
var blue = 0;
ctx.beginPath();
for (var index = 0; index < commandBufferLength; ++index) {
var commandID = commandBuffer[index];
switch (commandID) {
case Commands.ARC:
ctx.arc(
commandBuffer[index + 1],
commandBuffer[index + 2],
commandBuffer[index + 3],
commandBuffer[index + 4],
commandBuffer[index + 5],
commandBuffer[index + 6]
);
index += 7;
break;
case Commands.LINE_STYLE:
lineWidth = commandBuffer[index + 1];
lineColor = commandBuffer[index + 2];
lineAlpha = commandBuffer[index + 3];
red = (lineColor & 16711680) >>> 16;
green = (lineColor & 65280) >>> 8;
blue = lineColor & 255;
ctx.strokeStyle = "rgba(" + red + "," + green + "," + blue + "," + lineAlpha + ")";
ctx.lineWidth = lineWidth;
index += 3;
break;
case Commands.FILL_STYLE:
fillColor = commandBuffer[index + 1];
fillAlpha = commandBuffer[index + 2];
red = (fillColor & 16711680) >>> 16;
green = (fillColor & 65280) >>> 8;
blue = fillColor & 255;
ctx.fillStyle = "rgba(" + red + "," + green + "," + blue + "," + fillAlpha + ")";
index += 2;
break;
case Commands.BEGIN_PATH:
ctx.beginPath();
break;
case Commands.CLOSE_PATH:
ctx.closePath();
break;
case Commands.FILL_PATH:
if (!allowClip) {
ctx.fill();
}
break;
case Commands.STROKE_PATH:
if (!allowClip) {
ctx.stroke();
}
break;
case Commands.FILL_RECT:
if (!allowClip) {
ctx.fillRect(
commandBuffer[index + 1],
commandBuffer[index + 2],
commandBuffer[index + 3],
commandBuffer[index + 4]
);
} else {
ctx.rect(
commandBuffer[index + 1],
commandBuffer[index + 2],
commandBuffer[index + 3],
commandBuffer[index + 4]
);
}
index += 4;
break;
case Commands.FILL_TRIANGLE:
ctx.beginPath();
ctx.moveTo(commandBuffer[index + 1], commandBuffer[index + 2]);
ctx.lineTo(commandBuffer[index + 3], commandBuffer[index + 4]);
ctx.lineTo(commandBuffer[index + 5], commandBuffer[index + 6]);
ctx.closePath();
if (!allowClip) {
ctx.fill();
}
index += 6;
break;
case Commands.STROKE_TRIANGLE:
ctx.beginPath();
ctx.moveTo(commandBuffer[index + 1], commandBuffer[index + 2]);
ctx.lineTo(commandBuffer[index + 3], commandBuffer[index + 4]);
ctx.lineTo(commandBuffer[index + 5], commandBuffer[index + 6]);
ctx.closePath();
if (!allowClip) {
ctx.stroke();
}
index += 6;
break;
case Commands.LINE_TO:
ctx.lineTo(
commandBuffer[index + 1],
commandBuffer[index + 2]
);
index += 2;
break;
case Commands.MOVE_TO:
ctx.moveTo(
commandBuffer[index + 1],
commandBuffer[index + 2]
);
index += 2;
break;
case Commands.LINE_FX_TO:
ctx.lineTo(
commandBuffer[index + 1],
commandBuffer[index + 2]
);
index += 5;
break;
case Commands.MOVE_FX_TO:
ctx.moveTo(
commandBuffer[index + 1],
commandBuffer[index + 2]
);
index += 5;
break;
case Commands.SAVE:
ctx.save();
break;
case Commands.RESTORE:
ctx.restore();
break;
case Commands.TRANSLATE:
ctx.translate(
commandBuffer[index + 1],
commandBuffer[index + 2]
);
index += 2;
break;
case Commands.SCALE:
ctx.scale(
commandBuffer[index + 1],
commandBuffer[index + 2]
);
index += 2;
break;
case Commands.ROTATE:
ctx.rotate(
commandBuffer[index + 1]
);
index += 1;
break;
case Commands.GRADIENT_FILL_STYLE:
index += 5;
break;
case Commands.GRADIENT_LINE_STYLE:
index += 6;
break;
}
}
ctx.restore();
};
module2.exports = GraphicsCanvasRenderer;
}
),
/***/
87079: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var GameObjectCreator = __webpack_require__2(44603);
var Graphics = __webpack_require__2(43831);
GameObjectCreator.register("graphics", function(config, addToScene) {
if (config === void 0) {
config = {};
}
if (addToScene !== void 0) {
config.add = addToScene;
}
var graphics = new Graphics(this.scene, config);
if (config.add) {
this.scene.sys.displayList.add(graphics);
}
return graphics;
});
}
),
/***/
1201: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var Graphics = __webpack_require__2(43831);
var GameObjectFactory = __webpack_require__2(39429);
GameObjectFactory.register("graphics", function(config) {
return this.displayList.add(new Graphics(this.scene, config));
});
}
),
/***/
84503: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(77545);
renderCanvas = __webpack_require__2(32768);
}
if (true) {
renderCanvas = __webpack_require__2(32768);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
77545: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Commands = __webpack_require__2(85592);
var GetCalcMatrix = __webpack_require__2(91296);
var TransformMatrix = __webpack_require__2(61340);
var Utils = __webpack_require__2(70554);
var Point = function(x, y, width) {
this.x = x;
this.y = y;
this.width = width;
};
var Path = function(x, y, width) {
this.points = [];
this.pointsLength = 1;
this.points[0] = new Point(x, y, width);
};
var matrixStack = [];
var tempMatrix = new TransformMatrix();
var GraphicsWebGLRenderer = function(renderer, src, camera, parentMatrix) {
if (src.commandBuffer.length === 0) {
return;
}
camera.addToRenderList(src);
var pipeline = renderer.pipelines.set(src.pipeline, src);
renderer.pipelines.preBatch(src);
var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc;
var currentMatrix = tempMatrix.loadIdentity();
var commands = src.commandBuffer;
var alpha = camera.alpha * src.alpha;
var lineWidth = 1;
var fillTint = pipeline.fillTint;
var strokeTint = pipeline.strokeTint;
var tx = 0;
var ty = 0;
var ta = 0;
var iterStep = 0.01;
var PI2 = Math.PI * 2;
var cmd;
var path = [];
var pathIndex = 0;
var pathOpen = true;
var lastPath = null;
var getTint = Utils.getTintAppendFloatAlpha;
for (var cmdIndex = 0; cmdIndex < commands.length; cmdIndex++) {
cmd = commands[cmdIndex];
switch (cmd) {
case Commands.BEGIN_PATH: {
path.length = 0;
lastPath = null;
pathOpen = true;
break;
}
case Commands.CLOSE_PATH: {
pathOpen = false;
if (lastPath && lastPath.points.length) {
lastPath.points.push(lastPath.points[0]);
}
break;
}
case Commands.FILL_PATH: {
for (pathIndex = 0; pathIndex < path.length; pathIndex++) {
pipeline.batchFillPath(
path[pathIndex].points,
currentMatrix,
calcMatrix
);
}
break;
}
case Commands.STROKE_PATH: {
for (pathIndex = 0; pathIndex < path.length; pathIndex++) {
pipeline.batchStrokePath(
path[pathIndex].points,
lineWidth,
pathOpen,
currentMatrix,
calcMatrix
);
}
break;
}
case Commands.LINE_STYLE: {
lineWidth = commands[++cmdIndex];
var strokeColor = commands[++cmdIndex];
var strokeAlpha = commands[++cmdIndex] * alpha;
var strokeTintColor = getTint(strokeColor, strokeAlpha);
strokeTint.TL = strokeTintColor;
strokeTint.TR = strokeTintColor;
strokeTint.BL = strokeTintColor;
strokeTint.BR = strokeTintColor;
break;
}
case Commands.FILL_STYLE: {
var fillColor = commands[++cmdIndex];
var fillAlpha = commands[++cmdIndex] * alpha;
var fillTintColor = getTint(fillColor, fillAlpha);
fillTint.TL = fillTintColor;
fillTint.TR = fillTintColor;
fillTint.BL = fillTintColor;
fillTint.BR = fillTintColor;
break;
}
case Commands.GRADIENT_FILL_STYLE: {
var alphaTL = commands[++cmdIndex] * alpha;
var alphaTR = commands[++cmdIndex] * alpha;
var alphaBL = commands[++cmdIndex] * alpha;
var alphaBR = commands[++cmdIndex] * alpha;
fillTint.TL = getTint(commands[++cmdIndex], alphaTL);
fillTint.TR = getTint(commands[++cmdIndex], alphaTR);
fillTint.BL = getTint(commands[++cmdIndex], alphaBL);
fillTint.BR = getTint(commands[++cmdIndex], alphaBR);
break;
}
case Commands.GRADIENT_LINE_STYLE: {
lineWidth = commands[++cmdIndex];
var gradientLineAlpha = commands[++cmdIndex] * alpha;
strokeTint.TL = getTint(commands[++cmdIndex], gradientLineAlpha);
strokeTint.TR = getTint(commands[++cmdIndex], gradientLineAlpha);
strokeTint.BL = getTint(commands[++cmdIndex], gradientLineAlpha);
strokeTint.BR = getTint(commands[++cmdIndex], gradientLineAlpha);
break;
}
case Commands.ARC: {
var iteration = 0;
var x = commands[++cmdIndex];
var y = commands[++cmdIndex];
var radius = commands[++cmdIndex];
var startAngle = commands[++cmdIndex];
var endAngle = commands[++cmdIndex];
var anticlockwise = commands[++cmdIndex];
var overshoot = commands[++cmdIndex];
endAngle -= startAngle;
if (anticlockwise) {
if (endAngle < -PI2) {
endAngle = -PI2;
} else if (endAngle > 0) {
endAngle = -PI2 + endAngle % PI2;
}
} else if (endAngle > PI2) {
endAngle = PI2;
} else if (endAngle < 0) {
endAngle = PI2 + endAngle % PI2;
}
if (lastPath === null) {
lastPath = new Path(x + Math.cos(startAngle) * radius, y + Math.sin(startAngle) * radius, lineWidth);
path.push(lastPath);
iteration += iterStep;
}
while (iteration < 1 + overshoot) {
ta = endAngle * iteration + startAngle;
tx = x + Math.cos(ta) * radius;
ty = y + Math.sin(ta) * radius;
lastPath.points.push(new Point(tx, ty, lineWidth));
iteration += iterStep;
}
ta = endAngle + startAngle;
tx = x + Math.cos(ta) * radius;
ty = y + Math.sin(ta) * radius;
lastPath.points.push(new Point(tx, ty, lineWidth));
break;
}
case Commands.FILL_RECT: {
pipeline.batchFillRect(
commands[++cmdIndex],
commands[++cmdIndex],
commands[++cmdIndex],
commands[++cmdIndex],
currentMatrix,
calcMatrix
);
break;
}
case Commands.FILL_TRIANGLE: {
pipeline.batchFillTriangle(
commands[++cmdIndex],
commands[++cmdIndex],
commands[++cmdIndex],
commands[++cmdIndex],
commands[++cmdIndex],
commands[++cmdIndex],
currentMatrix,
calcMatrix
);
break;
}
case Commands.STROKE_TRIANGLE: {
pipeline.batchStrokeTriangle(
commands[++cmdIndex],
commands[++cmdIndex],
commands[++cmdIndex],
commands[++cmdIndex],
commands[++cmdIndex],
commands[++cmdIndex],
lineWidth,
currentMatrix,
calcMatrix
);
break;
}
case Commands.LINE_TO: {
if (lastPath !== null) {
lastPath.points.push(new Point(commands[++cmdIndex], commands[++cmdIndex], lineWidth));
} else {
lastPath = new Path(commands[++cmdIndex], commands[++cmdIndex], lineWidth);
path.push(lastPath);
}
break;
}
case Commands.MOVE_TO: {
lastPath = new Path(commands[++cmdIndex], commands[++cmdIndex], lineWidth);
path.push(lastPath);
break;
}
case Commands.SAVE: {
matrixStack.push(currentMatrix.copyToArray());
break;
}
case Commands.RESTORE: {
currentMatrix.copyFromArray(matrixStack.pop());
break;
}
case Commands.TRANSLATE: {
x = commands[++cmdIndex];
y = commands[++cmdIndex];
currentMatrix.translate(x, y);
break;
}
case Commands.SCALE: {
x = commands[++cmdIndex];
y = commands[++cmdIndex];
currentMatrix.scale(x, y);
break;
}
case Commands.ROTATE: {
currentMatrix.rotate(commands[++cmdIndex]);
break;
}
}
}
renderer.pipelines.postBatch(src);
};
module2.exports = GraphicsWebGLRenderer;
}
),
/***/
26479: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Actions = __webpack_require__2(61061);
var Class = __webpack_require__2(83419);
var Events = __webpack_require__2(51708);
var EventEmitter = __webpack_require__2(50792);
var GetAll = __webpack_require__2(46710);
var GetFastValue = __webpack_require__2(95540);
var GetValue = __webpack_require__2(35154);
var HasValue = __webpack_require__2(97022);
var IsPlainObject = __webpack_require__2(41212);
var Range = __webpack_require__2(88492);
var Set = __webpack_require__2(35072);
var Sprite = __webpack_require__2(68287);
var Group = new Class({
Extends: EventEmitter,
initialize: function Group2(scene, children, config) {
EventEmitter.call(this);
if (config) {
if (children && !Array.isArray(children)) {
children = [children];
}
} else if (Array.isArray(children)) {
if (IsPlainObject(children[0])) {
config = children;
children = null;
}
} else if (IsPlainObject(children)) {
config = children;
children = null;
}
this.scene = scene;
this.children = new Set();
this.isParent = true;
this.type = "Group";
this.classType = GetFastValue(config, "classType", Sprite);
this.name = GetFastValue(config, "name", "");
this.active = GetFastValue(config, "active", true);
this.maxSize = GetFastValue(config, "maxSize", -1);
this.defaultKey = GetFastValue(config, "defaultKey", null);
this.defaultFrame = GetFastValue(config, "defaultFrame", null);
this.runChildUpdate = GetFastValue(config, "runChildUpdate", false);
this.createCallback = GetFastValue(config, "createCallback", null);
this.removeCallback = GetFastValue(config, "removeCallback", null);
this.createMultipleCallback = GetFastValue(config, "createMultipleCallback", null);
this.internalCreateCallback = GetFastValue(config, "internalCreateCallback", null);
this.internalRemoveCallback = GetFastValue(config, "internalRemoveCallback", null);
if (children) {
this.addMultiple(children);
}
if (config) {
this.createMultiple(config);
}
this.on(Events.ADDED_TO_SCENE, this.addedToScene, this);
this.on(Events.REMOVED_FROM_SCENE, this.removedFromScene, this);
},
// Overrides Game Object method
addedToScene: function() {
this.scene.sys.updateList.add(this);
},
// Overrides Game Object method
removedFromScene: function() {
this.scene.sys.updateList.remove(this);
},
/**
* Creates a new Game Object and adds it to this group, unless the group {@link Phaser.GameObjects.Group#isFull is full}.
*
* Calls {@link Phaser.GameObjects.Group#createCallback}.
*
* @method Phaser.GameObjects.Group#create
* @since 3.0.0
*
* @param {number} [x=0] - The horizontal position of the new Game Object in the world.
* @param {number} [y=0] - The vertical position of the new Game Object in the world.
* @param {string} [key=defaultKey] - The texture key of the new Game Object.
* @param {(string|number)} [frame=defaultFrame] - The texture frame of the new Game Object.
* @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of the new Game Object.
* @param {boolean} [active=true] - The {@link Phaser.GameObjects.GameObject#active} state of the new Game Object.
*
* @return {any} The new Game Object (usually a Sprite, etc.).
*/
create: function(x, y, key, frame, visible, active) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (key === void 0) {
key = this.defaultKey;
}
if (frame === void 0) {
frame = this.defaultFrame;
}
if (visible === void 0) {
visible = true;
}
if (active === void 0) {
active = true;
}
if (this.isFull()) {
return null;
}
var child = new this.classType(this.scene, x, y, key, frame);
child.addToDisplayList(this.scene.sys.displayList);
child.addToUpdateList();
child.visible = visible;
child.setActive(active);
this.add(child);
return child;
},
/**
* Creates several Game Objects and adds them to this group.
*
* If the group becomes {@link Phaser.GameObjects.Group#isFull}, no further Game Objects are created.
*
* Calls {@link Phaser.GameObjects.Group#createMultipleCallback} and {@link Phaser.GameObjects.Group#createCallback}.
*
* @method Phaser.GameObjects.Group#createMultiple
* @since 3.0.0
*
* @param {Phaser.Types.GameObjects.Group.GroupCreateConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig[]} config - Creation settings. This can be a single configuration object or an array of such objects, which will be applied in turn.
*
* @return {any[]} The newly created Game Objects.
*/
createMultiple: function(config) {
if (this.isFull()) {
return [];
}
if (!Array.isArray(config)) {
config = [config];
}
var output = [];
if (config[0].key) {
for (var i = 0; i < config.length; i++) {
var entries = this.createFromConfig(config[i]);
output = output.concat(entries);
}
}
return output;
},
/**
* A helper for {@link Phaser.GameObjects.Group#createMultiple}.
*
* @method Phaser.GameObjects.Group#createFromConfig
* @since 3.0.0
*
* @param {Phaser.Types.GameObjects.Group.GroupCreateConfig} options - Creation settings.
*
* @return {any[]} The newly created Game Objects.
*/
createFromConfig: function(options) {
if (this.isFull()) {
return [];
}
this.classType = GetFastValue(options, "classType", this.classType);
var key = GetFastValue(options, "key", void 0);
var frame = GetFastValue(options, "frame", null);
var visible = GetFastValue(options, "visible", true);
var active = GetFastValue(options, "active", true);
var entries = [];
if (key === void 0) {
return entries;
} else {
if (!Array.isArray(key)) {
key = [key];
}
if (!Array.isArray(frame)) {
frame = [frame];
}
}
var repeat = GetFastValue(options, "repeat", 0);
var randomKey = GetFastValue(options, "randomKey", false);
var randomFrame = GetFastValue(options, "randomFrame", false);
var yoyo = GetFastValue(options, "yoyo", false);
var quantity = GetFastValue(options, "quantity", false);
var frameQuantity = GetFastValue(options, "frameQuantity", 1);
var max = GetFastValue(options, "max", 0);
var range = Range(key, frame, {
max,
qty: quantity ? quantity : frameQuantity,
random: randomKey,
randomB: randomFrame,
repeat,
yoyo
});
if (options.createCallback) {
this.createCallback = options.createCallback;
}
if (options.removeCallback) {
this.removeCallback = options.removeCallback;
}
if (options.internalCreateCallback) {
this.internalCreateCallback = options.internalCreateCallback;
}
if (options.internalRemoveCallback) {
this.internalRemoveCallback = options.internalRemoveCallback;
}
for (var c = 0; c < range.length; c++) {
var created = this.create(0, 0, range[c].a, range[c].b, visible, active);
if (!created) {
break;
}
entries.push(created);
}
if (HasValue(options, "setXY")) {
var x = GetValue(options, "setXY.x", 0);
var y = GetValue(options, "setXY.y", 0);
var stepX = GetValue(options, "setXY.stepX", 0);
var stepY = GetValue(options, "setXY.stepY", 0);
Actions.SetXY(entries, x, y, stepX, stepY);
}
if (HasValue(options, "setRotation")) {
var rotation = GetValue(options, "setRotation.value", 0);
var stepRotation = GetValue(options, "setRotation.step", 0);
Actions.SetRotation(entries, rotation, stepRotation);
}
if (HasValue(options, "setScale")) {
var scaleX = GetValue(options, "setScale.x", 1);
var scaleY = GetValue(options, "setScale.y", scaleX);
var stepScaleX = GetValue(options, "setScale.stepX", 0);
var stepScaleY = GetValue(options, "setScale.stepY", 0);
Actions.SetScale(entries, scaleX, scaleY, stepScaleX, stepScaleY);
}
if (HasValue(options, "setOrigin")) {
var originX = GetValue(options, "setOrigin.x", 0.5);
var originY = GetValue(options, "setOrigin.y", originX);
var stepOriginX = GetValue(options, "setOrigin.stepX", 0);
var stepOriginY = GetValue(options, "setOrigin.stepY", 0);
Actions.SetOrigin(entries, originX, originY, stepOriginX, stepOriginY);
}
if (HasValue(options, "setAlpha")) {
var alpha = GetValue(options, "setAlpha.value", 1);
var stepAlpha = GetValue(options, "setAlpha.step", 0);
Actions.SetAlpha(entries, alpha, stepAlpha);
}
if (HasValue(options, "setDepth")) {
var depth = GetValue(options, "setDepth.value", 0);
var stepDepth = GetValue(options, "setDepth.step", 0);
Actions.SetDepth(entries, depth, stepDepth);
}
if (HasValue(options, "setScrollFactor")) {
var scrollFactorX = GetValue(options, "setScrollFactor.x", 1);
var scrollFactorY = GetValue(options, "setScrollFactor.y", scrollFactorX);
var stepScrollFactorX = GetValue(options, "setScrollFactor.stepX", 0);
var stepScrollFactorY = GetValue(options, "setScrollFactor.stepY", 0);
Actions.SetScrollFactor(entries, scrollFactorX, scrollFactorY, stepScrollFactorX, stepScrollFactorY);
}
var hitArea = GetFastValue(options, "hitArea", null);
var hitAreaCallback = GetFastValue(options, "hitAreaCallback", null);
if (hitArea) {
Actions.SetHitArea(entries, hitArea, hitAreaCallback);
}
var grid = GetFastValue(options, "gridAlign", false);
if (grid) {
Actions.GridAlign(entries, grid);
}
if (this.createMultipleCallback) {
this.createMultipleCallback.call(this, entries);
}
return entries;
},
/**
* Updates any group members, if {@link Phaser.GameObjects.Group#runChildUpdate} is enabled.
*
* @method Phaser.GameObjects.Group#preUpdate
* @since 3.0.0
*
* @param {number} time - The current timestamp.
* @param {number} delta - The delta time elapsed since the last frame.
*/
preUpdate: function(time, delta) {
if (!this.runChildUpdate || this.children.size === 0) {
return;
}
var temp = this.children.entries.slice();
for (var i = 0; i < temp.length; i++) {
var item = temp[i];
if (item.active) {
item.update(time, delta);
}
}
},
/**
* Adds a Game Object to this group.
*
* Calls {@link Phaser.GameObjects.Group#createCallback}.
*
* @method Phaser.GameObjects.Group#add
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} child - The Game Object to add.
* @param {boolean} [addToScene=false] - Also add the Game Object to the scene.
*
* @return {this} This Group object.
*/
add: function(child, addToScene) {
if (addToScene === void 0) {
addToScene = false;
}
if (this.isFull()) {
return this;
}
this.children.set(child);
if (this.internalCreateCallback) {
this.internalCreateCallback.call(this, child);
}
if (this.createCallback) {
this.createCallback.call(this, child);
}
if (addToScene) {
child.addToDisplayList(this.scene.sys.displayList);
child.addToUpdateList();
}
child.on(Events.DESTROY, this.remove, this);
return this;
},
/**
* Adds several Game Objects to this group.
*
* Calls {@link Phaser.GameObjects.Group#createCallback}.
*
* @method Phaser.GameObjects.Group#addMultiple
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject[]} children - The Game Objects to add.
* @param {boolean} [addToScene=false] - Also add the Game Objects to the scene.
*
* @return {this} This group.
*/
addMultiple: function(children, addToScene) {
if (addToScene === void 0) {
addToScene = false;
}
if (Array.isArray(children)) {
for (var i = 0; i < children.length; i++) {
this.add(children[i], addToScene);
}
}
return this;
},
/**
* Removes a member of this Group and optionally removes it from the Scene and / or destroys it.
*
* Calls {@link Phaser.GameObjects.Group#removeCallback}.
*
* @method Phaser.GameObjects.Group#remove
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} child - The Game Object to remove.
* @param {boolean} [removeFromScene=false] - Optionally remove the Group member from the Scene it belongs to.
* @param {boolean} [destroyChild=false] - Optionally call destroy on the removed Group member.
*
* @return {this} This Group object.
*/
remove: function(child, removeFromScene, destroyChild) {
if (removeFromScene === void 0) {
removeFromScene = false;
}
if (destroyChild === void 0) {
destroyChild = false;
}
if (!this.children.contains(child)) {
return this;
}
this.children.delete(child);
if (this.internalRemoveCallback) {
this.internalRemoveCallback.call(this, child);
}
if (this.removeCallback) {
this.removeCallback.call(this, child);
}
child.off(Events.DESTROY, this.remove, this);
if (destroyChild) {
child.destroy();
} else if (removeFromScene) {
child.removeFromDisplayList();
child.removeFromUpdateList();
}
return this;
},
/**
* Removes all members of this Group and optionally removes them from the Scene and / or destroys them.
*
* Does not call {@link Phaser.GameObjects.Group#removeCallback}.
*
* @method Phaser.GameObjects.Group#clear
* @since 3.0.0
*
* @param {boolean} [removeFromScene=false] - Optionally remove each Group member from the Scene.
* @param {boolean} [destroyChild=false] - Optionally call destroy on the removed Group members.
*
* @return {this} This group.
*/
clear: function(removeFromScene, destroyChild) {
if (removeFromScene === void 0) {
removeFromScene = false;
}
if (destroyChild === void 0) {
destroyChild = false;
}
var children = this.children;
for (var i = 0; i < children.size; i++) {
var gameObject = children.entries[i];
gameObject.off(Events.DESTROY, this.remove, this);
if (destroyChild) {
gameObject.destroy();
} else if (removeFromScene) {
gameObject.removeFromDisplayList();
gameObject.removeFromUpdateList();
}
}
this.children.clear();
return this;
},
/**
* Tests if a Game Object is a member of this group.
*
* @method Phaser.GameObjects.Group#contains
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} child - A Game Object.
*
* @return {boolean} True if the Game Object is a member of this group.
*/
contains: function(child) {
return this.children.contains(child);
},
/**
* All members of the group.
*
* @method Phaser.GameObjects.Group#getChildren
* @since 3.0.0
*
* @return {Phaser.GameObjects.GameObject[]} The group members.
*/
getChildren: function() {
return this.children.entries;
},
/**
* The number of members of the group.
*
* @method Phaser.GameObjects.Group#getLength
* @since 3.0.0
*
* @return {number}
*/
getLength: function() {
return this.children.size;
},
/**
* Returns all children in this Group that match the given criteria based on the `property` and `value` arguments.
*
* For example: `getMatching('visible', true)` would return only children that have their `visible` property set.
*
* Optionally, you can specify a start and end index. For example if the Group has 100 elements,
* and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only
* the first 50.
*
* @method Phaser.GameObjects.Group#getMatching
* @since 3.50.0
*
* @param {string} [property] - The property to test on each array element.
* @param {*} [value] - The value to test the property against. Must pass a strict (`===`) comparison check.
* @param {number} [startIndex] - An optional start index to search from.
* @param {number} [endIndex] - An optional end index to search to.
*
* @return {any[]} An array of matching Group members. The array will be empty if nothing matched.
*/
getMatching: function(property, value, startIndex, endIndex) {
return GetAll(this.children.entries, property, value, startIndex, endIndex);
},
/**
* Scans the Group, from top to bottom, for the first member that has an {@link Phaser.GameObjects.GameObject#active} state matching the argument,
* assigns `x` and `y`, and returns the member.
*
* If no matching member is found and `createIfNull` is true and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`.
* Unless a new member is created, `key`, `frame`, and `visible` are ignored.
*
* @method Phaser.GameObjects.Group#getFirst
* @since 3.0.0
*
* @param {boolean} [state=false] - The {@link Phaser.GameObjects.GameObject#active} value to match.
* @param {boolean} [createIfNull=false] - Create a new Game Object if no matching members are found, using the following arguments.
* @param {number} [x] - The horizontal position of the Game Object in the world.
* @param {number} [y] - The vertical position of the Game Object in the world.
* @param {string} [key=defaultKey] - The texture key assigned to a new Game Object (if one is created).
* @param {(string|number)} [frame=defaultFrame] - A texture frame assigned to a new Game Object (if one is created).
* @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created).
*
* @return {?any} The first matching group member, or a newly created member, or null.
*/
getFirst: function(state, createIfNull, x, y, key, frame, visible) {
return this.getHandler(true, 1, state, createIfNull, x, y, key, frame, visible);
},
/**
* Scans the Group, from top to bottom, for the nth member that has an {@link Phaser.GameObjects.GameObject#active} state matching the argument,
* assigns `x` and `y`, and returns the member.
*
* If no matching member is found and `createIfNull` is true and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`.
* Unless a new member is created, `key`, `frame`, and `visible` are ignored.
*
* @method Phaser.GameObjects.Group#getFirstNth
* @since 3.6.0
*
* @param {number} nth - The nth matching Group member to search for.
* @param {boolean} [state=false] - The {@link Phaser.GameObjects.GameObject#active} value to match.
* @param {boolean} [createIfNull=false] - Create a new Game Object if no matching members are found, using the following arguments.
* @param {number} [x] - The horizontal position of the Game Object in the world.
* @param {number} [y] - The vertical position of the Game Object in the world.
* @param {string} [key=defaultKey] - The texture key assigned to a new Game Object (if one is created).
* @param {(string|number)} [frame=defaultFrame] - A texture frame assigned to a new Game Object (if one is created).
* @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created).
*
* @return {?any} The first matching group member, or a newly created member, or null.
*/
getFirstNth: function(nth, state, createIfNull, x, y, key, frame, visible) {
return this.getHandler(true, nth, state, createIfNull, x, y, key, frame, visible);
},
/**
* Scans the Group for the last member that has an {@link Phaser.GameObjects.GameObject#active} state matching the argument,
* assigns `x` and `y`, and returns the member.
*
* If no matching member is found and `createIfNull` is true and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`.
* Unless a new member is created, `key`, `frame`, and `visible` are ignored.
*
* @method Phaser.GameObjects.Group#getLast
* @since 3.6.0
*
* @param {boolean} [state=false] - The {@link Phaser.GameObjects.GameObject#active} value to match.
* @param {boolean} [createIfNull=false] - Create a new Game Object if no matching members are found, using the following arguments.
* @param {number} [x] - The horizontal position of the Game Object in the world.
* @param {number} [y] - The vertical position of the Game Object in the world.
* @param {string} [key=defaultKey] - The texture key assigned to a new Game Object (if one is created).
* @param {(string|number)} [frame=defaultFrame] - A texture frame assigned to a new Game Object (if one is created).
* @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created).
*
* @return {?any} The first matching group member, or a newly created member, or null.
*/
getLast: function(state, createIfNull, x, y, key, frame, visible) {
return this.getHandler(false, 1, state, createIfNull, x, y, key, frame, visible);
},
/**
* Scans the Group for the last nth member that has an {@link Phaser.GameObjects.GameObject#active} state matching the argument,
* assigns `x` and `y`, and returns the member.
*
* If no matching member is found and `createIfNull` is true and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`.
* Unless a new member is created, `key`, `frame`, and `visible` are ignored.
*
* @method Phaser.GameObjects.Group#getLastNth
* @since 3.6.0
*
* @param {number} nth - The nth matching Group member to search for.
* @param {boolean} [state=false] - The {@link Phaser.GameObjects.GameObject#active} value to match.
* @param {boolean} [createIfNull=false] - Create a new Game Object if no matching members are found, using the following arguments.
* @param {number} [x] - The horizontal position of the Game Object in the world.
* @param {number} [y] - The vertical position of the Game Object in the world.
* @param {string} [key=defaultKey] - The texture key assigned to a new Game Object (if one is created).
* @param {(string|number)} [frame=defaultFrame] - A texture frame assigned to a new Game Object (if one is created).
* @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created).
*
* @return {?any} The first matching group member, or a newly created member, or null.
*/
getLastNth: function(nth, state, createIfNull, x, y, key, frame, visible) {
return this.getHandler(false, nth, state, createIfNull, x, y, key, frame, visible);
},
/**
* Scans the group for the last member that has an {@link Phaser.GameObjects.GameObject#active} state matching the argument,
* assigns `x` and `y`, and returns the member.
*
* If no matching member is found and `createIfNull` is true and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`.
* Unless a new member is created, `key`, `frame`, and `visible` are ignored.
*
* @method Phaser.GameObjects.Group#getHandler
* @private
* @since 3.6.0
*
* @param {boolean} forwards - Search front to back or back to front?
* @param {number} nth - Stop matching after nth successful matches.
* @param {boolean} [state=false] - The {@link Phaser.GameObjects.GameObject#active} value to match.
* @param {boolean} [createIfNull=false] - Create a new Game Object if no matching members are found, using the following arguments.
* @param {number} [x] - The horizontal position of the Game Object in the world.
* @param {number} [y] - The vertical position of the Game Object in the world.
* @param {string} [key=defaultKey] - The texture key assigned to a new Game Object (if one is created).
* @param {(string|number)} [frame=defaultFrame] - A texture frame assigned to a new Game Object (if one is created).
* @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created).
*
* @return {?any} The first matching group member, or a newly created member, or null.
*/
getHandler: function(forwards, nth, state, createIfNull, x, y, key, frame, visible) {
if (state === void 0) {
state = false;
}
if (createIfNull === void 0) {
createIfNull = false;
}
var gameObject;
var i;
var total = 0;
var children = this.children.entries;
if (forwards) {
for (i = 0; i < children.length; i++) {
gameObject = children[i];
if (gameObject.active === state) {
total++;
if (total === nth) {
break;
}
} else {
gameObject = null;
}
}
} else {
for (i = children.length - 1; i >= 0; i--) {
gameObject = children[i];
if (gameObject.active === state) {
total++;
if (total === nth) {
break;
}
} else {
gameObject = null;
}
}
}
if (gameObject) {
if (typeof x === "number") {
gameObject.x = x;
}
if (typeof y === "number") {
gameObject.y = y;
}
return gameObject;
}
if (createIfNull) {
return this.create(x, y, key, frame, visible);
} else {
return null;
}
},
/**
* Scans the group for the first member that has an {@link Phaser.GameObjects.GameObject#active} state set to `false`,
* assigns `x` and `y`, and returns the member.
*
* If no inactive member is found and the group isn't full then it will create a new Game Object using `x`, `y`, `key`, `frame`, and `visible`.
* The new Game Object will have its active state set to `true`.
* Unless a new member is created, `key`, `frame`, and `visible` are ignored.
*
* @method Phaser.GameObjects.Group#get
* @since 3.0.0
*
* @param {number} [x] - The horizontal position of the Game Object in the world.
* @param {number} [y] - The vertical position of the Game Object in the world.
* @param {string} [key=defaultKey] - The texture key assigned to a new Game Object (if one is created).
* @param {(string|number)} [frame=defaultFrame] - A texture frame assigned to a new Game Object (if one is created).
* @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created).
*
* @return {?any} The first inactive group member, or a newly created member, or null.
*/
get: function(x, y, key, frame, visible) {
return this.getFirst(false, true, x, y, key, frame, visible);
},
/**
* Scans the group for the first member that has an {@link Phaser.GameObjects.GameObject#active} state set to `true`,
* assigns `x` and `y`, and returns the member.
*
* If no active member is found and `createIfNull` is `true` and the group isn't full then it will create a new one using `x`, `y`, `key`, `frame`, and `visible`.
* Unless a new member is created, `key`, `frame`, and `visible` are ignored.
*
* @method Phaser.GameObjects.Group#getFirstAlive
* @since 3.0.0
*
* @param {boolean} [createIfNull=false] - Create a new Game Object if no matching members are found, using the following arguments.
* @param {number} [x] - The horizontal position of the Game Object in the world.
* @param {number} [y] - The vertical position of the Game Object in the world.
* @param {string} [key=defaultKey] - The texture key assigned to a new Game Object (if one is created).
* @param {(string|number)} [frame=defaultFrame] - A texture frame assigned to a new Game Object (if one is created).
* @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created).
*
* @return {any} The first active group member, or a newly created member, or null.
*/
getFirstAlive: function(createIfNull, x, y, key, frame, visible) {
return this.getFirst(true, createIfNull, x, y, key, frame, visible);
},
/**
* Scans the group for the first member that has an {@link Phaser.GameObjects.GameObject#active} state set to `false`,
* assigns `x` and `y`, and returns the member.
*
* If no inactive member is found and `createIfNull` is `true` and the group isn't full then it will create a new one using `x`, `y`, `key`, `frame`, and `visible`.
* The new Game Object will have an active state set to `true`.
* Unless a new member is created, `key`, `frame`, and `visible` are ignored.
*
* @method Phaser.GameObjects.Group#getFirstDead
* @since 3.0.0
*
* @param {boolean} [createIfNull=false] - Create a new Game Object if no matching members are found, using the following arguments.
* @param {number} [x] - The horizontal position of the Game Object in the world.
* @param {number} [y] - The vertical position of the Game Object in the world.
* @param {string} [key=defaultKey] - The texture key assigned to a new Game Object (if one is created).
* @param {(string|number)} [frame=defaultFrame] - A texture frame assigned to a new Game Object (if one is created).
* @param {boolean} [visible=true] - The {@link Phaser.GameObjects.Components.Visible#visible} state of a new Game Object (if one is created).
*
* @return {any} The first inactive group member, or a newly created member, or null.
*/
getFirstDead: function(createIfNull, x, y, key, frame, visible) {
return this.getFirst(false, createIfNull, x, y, key, frame, visible);
},
/**
* {@link Phaser.Animations.AnimationState#play Plays} an animation for all members of this group.
*
* @method Phaser.GameObjects.Group#playAnimation
* @since 3.0.0
*
* @param {string} key - The string-based key of the animation to play.
* @param {string} [startFrame=0] - Optionally start the animation playing from this frame index.
*
* @return {this} This Group object.
*/
playAnimation: function(key, startFrame) {
Actions.PlayAnimation(this.children.entries, key, startFrame);
return this;
},
/**
* Whether this group's size at its {@link Phaser.GameObjects.Group#maxSize maximum}.
*
* @method Phaser.GameObjects.Group#isFull
* @since 3.0.0
*
* @return {boolean} True if the number of members equals {@link Phaser.GameObjects.Group#maxSize}.
*/
isFull: function() {
if (this.maxSize === -1) {
return false;
} else {
return this.children.size >= this.maxSize;
}
},
/**
* Counts the number of active (or inactive) group members.
*
* @method Phaser.GameObjects.Group#countActive
* @since 3.0.0
*
* @param {boolean} [value=true] - Count active (true) or inactive (false) group members.
*
* @return {number} The number of group members with an active state matching the `active` argument.
*/
countActive: function(value) {
if (value === void 0) {
value = true;
}
var total = 0;
for (var i = 0; i < this.children.size; i++) {
if (this.children.entries[i].active === value) {
total++;
}
}
return total;
},
/**
* Counts the number of in-use (active) group members.
*
* @method Phaser.GameObjects.Group#getTotalUsed
* @since 3.0.0
*
* @return {number} The number of group members with an active state of true.
*/
getTotalUsed: function() {
return this.countActive();
},
/**
* The difference of {@link Phaser.GameObjects.Group#maxSize} and the number of active group members.
*
* This represents the number of group members that could be created or reactivated before reaching the size limit.
*
* @method Phaser.GameObjects.Group#getTotalFree
* @since 3.0.0
*
* @return {number} maxSize minus the number of active group numbers; or a large number (if maxSize is -1).
*/
getTotalFree: function() {
var used = this.getTotalUsed();
var capacity = this.maxSize === -1 ? 999999999999 : this.maxSize;
return capacity - used;
},
/**
* Sets the `active` property of this Group.
* When active, this Group runs its `preUpdate` method.
*
* @method Phaser.GameObjects.Group#setActive
* @since 3.24.0
*
* @param {boolean} value - True if this Group should be set as active, false if not.
*
* @return {this} This Group object.
*/
setActive: function(value) {
this.active = value;
return this;
},
/**
* Sets the `name` property of this Group.
* The `name` property is not populated by Phaser and is presented for your own use.
*
* @method Phaser.GameObjects.Group#setName
* @since 3.24.0
*
* @param {string} value - The name to be given to this Group.
*
* @return {this} This Group object.
*/
setName: function(value) {
this.name = value;
return this;
},
/**
* Sets the property as defined in `key` of each group member to the given value.
*
* @method Phaser.GameObjects.Group#propertyValueSet
* @since 3.21.0
*
* @param {string} key - The property to be updated.
* @param {number} value - The amount to set the property to.
* @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter.
* @param {number} [index=0] - An optional offset to start searching from within the items array.
* @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning.
*
* @return {this} This Group object.
*/
propertyValueSet: function(key, value, step, index, direction) {
Actions.PropertyValueSet(this.children.entries, key, value, step, index, direction);
return this;
},
/**
* Adds the given value to the property as defined in `key` of each group member.
*
* @method Phaser.GameObjects.Group#propertyValueInc
* @since 3.21.0
*
* @param {string} key - The property to be updated.
* @param {number} value - The amount to set the property to.
* @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter.
* @param {number} [index=0] - An optional offset to start searching from within the items array.
* @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning.
*
* @return {this} This Group object.
*/
propertyValueInc: function(key, value, step, index, direction) {
Actions.PropertyValueInc(this.children.entries, key, value, step, index, direction);
return this;
},
/**
* Sets the x of each group member.
*
* @method Phaser.GameObjects.Group#setX
* @since 3.21.0
*
* @param {number} value - The amount to set the property to.
* @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter.
*
* @return {this} This Group object.
*/
setX: function(value, step) {
Actions.SetX(this.children.entries, value, step);
return this;
},
/**
* Sets the y of each group member.
*
* @method Phaser.GameObjects.Group#setY
* @since 3.21.0
*
* @param {number} value - The amount to set the property to.
* @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter.
*
* @return {this} This Group object.
*/
setY: function(value, step) {
Actions.SetY(this.children.entries, value, step);
return this;
},
/**
* Sets the x, y of each group member.
*
* @method Phaser.GameObjects.Group#setXY
* @since 3.21.0
*
* @param {number} x - The amount to set the `x` property to.
* @param {number} [y=x] - The amount to set the `y` property to. If `undefined` or `null` it uses the `x` value.
* @param {number} [stepX=0] - This is added to the `x` amount, multiplied by the iteration counter.
* @param {number} [stepY=0] - This is added to the `y` amount, multiplied by the iteration counter.
*
* @return {this} This Group object.
*/
setXY: function(x, y, stepX, stepY) {
Actions.SetXY(this.children.entries, x, y, stepX, stepY);
return this;
},
/**
* Adds the given value to the x of each group member.
*
* @method Phaser.GameObjects.Group#incX
* @since 3.21.0
*
* @param {number} value - The amount to be added to the `x` property.
* @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter.
*
* @return {this} This Group object.
*/
incX: function(value, step) {
Actions.IncX(this.children.entries, value, step);
return this;
},
/**
* Adds the given value to the y of each group member.
*
* @method Phaser.GameObjects.Group#incY
* @since 3.21.0
*
* @param {number} value - The amount to be added to the `y` property.
* @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter.
*
* @return {this} This Group object.
*/
incY: function(value, step) {
Actions.IncY(this.children.entries, value, step);
return this;
},
/**
* Adds the given value to the x, y of each group member.
*
* @method Phaser.GameObjects.Group#incXY
* @since 3.21.0
*
* @param {number} x - The amount to be added to the `x` property.
* @param {number} [y=x] - The amount to be added to the `y` property. If `undefined` or `null` it uses the `x` value.
* @param {number} [stepX=0] - This is added to the `x` amount, multiplied by the iteration counter.
* @param {number} [stepY=0] - This is added to the `y` amount, multiplied by the iteration counter.
*
* @return {this} This Group object.
*/
incXY: function(x, y, stepX, stepY) {
Actions.IncXY(this.children.entries, x, y, stepX, stepY);
return this;
},
/**
* Iterate through the group members changing the position of each element to be that of the element that came before
* it in the array (or after it if direction = 1)
*
* The first group member position is set to x/y.
*
* @method Phaser.GameObjects.Group#shiftPosition
* @since 3.21.0
*
* @param {number} x - The x coordinate to place the first item in the array at.
* @param {number} y - The y coordinate to place the first item in the array at.
* @param {number} [direction=0] - The iteration direction. 0 = first to last and 1 = last to first.
*
* @return {this} This Group object.
*/
shiftPosition: function(x, y, direction) {
Actions.ShiftPosition(this.children.entries, x, y, direction);
return this;
},
/**
* Sets the angle of each group member.
*
* @method Phaser.GameObjects.Group#angle
* @since 3.21.0
*
* @param {number} value - The amount to set the angle to, in degrees.
* @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter.
*
* @return {this} This Group object.
*/
angle: function(value, step) {
Actions.Angle(this.children.entries, value, step);
return this;
},
/**
* Sets the rotation of each group member.
*
* @method Phaser.GameObjects.Group#rotate
* @since 3.21.0
*
* @param {number} value - The amount to set the rotation to, in radians.
* @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter.
*
* @return {this} This Group object.
*/
rotate: function(value, step) {
Actions.Rotate(this.children.entries, value, step);
return this;
},
/**
* Rotates each group member around the given point by the given angle.
*
* @method Phaser.GameObjects.Group#rotateAround
* @since 3.21.0
*
* @param {Phaser.Types.Math.Vector2Like} point - Any object with public `x` and `y` properties.
* @param {number} angle - The angle to rotate by, in radians.
*
* @return {this} This Group object.
*/
rotateAround: function(point, angle) {
Actions.RotateAround(this.children.entries, point, angle);
return this;
},
/**
* Rotates each group member around the given point by the given angle and distance.
*
* @method Phaser.GameObjects.Group#rotateAroundDistance
* @since 3.21.0
*
* @param {Phaser.Types.Math.Vector2Like} point - Any object with public `x` and `y` properties.
* @param {number} angle - The angle to rotate by, in radians.
* @param {number} distance - The distance from the point of rotation in pixels.
*
* @return {this} This Group object.
*/
rotateAroundDistance: function(point, angle, distance) {
Actions.RotateAroundDistance(this.children.entries, point, angle, distance);
return this;
},
/**
* Sets the alpha of each group member.
*
* @method Phaser.GameObjects.Group#setAlpha
* @since 3.21.0
*
* @param {number} value - The amount to set the alpha to.
* @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter.
*
* @return {this} This Group object.
*/
setAlpha: function(value, step) {
Actions.SetAlpha(this.children.entries, value, step);
return this;
},
/**
* Sets the tint of each group member.
*
* @method Phaser.GameObjects.Group#setTint
* @since 3.21.0
*
* @param {number} topLeft - The tint being applied to top-left corner of item. If other parameters are given no value, this tint will be applied to whole item.
* @param {number} [topRight] - The tint to be applied to top-right corner of item.
* @param {number} [bottomLeft] - The tint to be applied to the bottom-left corner of item.
* @param {number} [bottomRight] - The tint to be applied to the bottom-right corner of item.
*
* @return {this} This Group object.
*/
setTint: function(topLeft, topRight, bottomLeft, bottomRight) {
Actions.SetTint(this.children.entries, topLeft, topRight, bottomLeft, bottomRight);
return this;
},
/**
* Sets the originX, originY of each group member.
*
* @method Phaser.GameObjects.Group#setOrigin
* @since 3.21.0
*
* @param {number} originX - The amount to set the `originX` property to.
* @param {number} [originY] - The amount to set the `originY` property to. If `undefined` or `null` it uses the `originX` value.
* @param {number} [stepX=0] - This is added to the `originX` amount, multiplied by the iteration counter.
* @param {number} [stepY=0] - This is added to the `originY` amount, multiplied by the iteration counter.
*
* @return {this} This Group object.
*/
setOrigin: function(originX, originY, stepX, stepY) {
Actions.SetOrigin(this.children.entries, originX, originY, stepX, stepY);
return this;
},
/**
* Sets the scaleX of each group member.
*
* @method Phaser.GameObjects.Group#scaleX
* @since 3.21.0
*
* @param {number} value - The amount to set the property to.
* @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter.
*
* @return {this} This Group object.
*/
scaleX: function(value, step) {
Actions.ScaleX(this.children.entries, value, step);
return this;
},
/**
* Sets the scaleY of each group member.
*
* @method Phaser.GameObjects.Group#scaleY
* @since 3.21.0
*
* @param {number} value - The amount to set the property to.
* @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter.
*
* @return {this} This Group object.
*/
scaleY: function(value, step) {
Actions.ScaleY(this.children.entries, value, step);
return this;
},
/**
* Sets the scaleX, scaleY of each group member.
*
* @method Phaser.GameObjects.Group#scaleXY
* @since 3.21.0
*
* @param {number} scaleX - The amount to be added to the `scaleX` property.
* @param {number} [scaleY] - The amount to be added to the `scaleY` property. If `undefined` or `null` it uses the `scaleX` value.
* @param {number} [stepX=0] - This is added to the `scaleX` amount, multiplied by the iteration counter.
* @param {number} [stepY=0] - This is added to the `scaleY` amount, multiplied by the iteration counter.
*
* @return {this} This Group object.
*/
scaleXY: function(scaleX, scaleY, stepX, stepY) {
Actions.ScaleXY(this.children.entries, scaleX, scaleY, stepX, stepY);
return this;
},
/**
* Sets the depth of each group member.
*
* @method Phaser.GameObjects.Group#setDepth
* @since 3.0.0
*
* @param {number} value - The amount to set the property to.
* @param {number} [step=0] - This is added to the `value` amount, multiplied by the iteration counter.
*
* @return {this} This Group object.
*/
setDepth: function(value, step) {
Actions.SetDepth(this.children.entries, value, step);
return this;
},
/**
* Sets the blendMode of each group member.
*
* @method Phaser.GameObjects.Group#setBlendMode
* @since 3.21.0
*
* @param {number} value - The amount to set the property to.
*
* @return {this} This Group object.
*/
setBlendMode: function(value) {
Actions.SetBlendMode(this.children.entries, value);
return this;
},
/**
* Passes all group members to the Input Manager to enable them for input with identical areas and callbacks.
*
* @method Phaser.GameObjects.Group#setHitArea
* @since 3.21.0
*
* @param {*} hitArea - Either an input configuration object, or a geometric shape that defines the hit area for the Game Object. If not specified a Rectangle will be used.
* @param {Phaser.Types.Input.HitAreaCallback} hitAreaCallback - A callback to be invoked when the Game Object is interacted with. If you provide a shape you must also provide a callback.
*
* @return {this} This Group object.
*/
setHitArea: function(hitArea, hitAreaCallback) {
Actions.SetHitArea(this.children.entries, hitArea, hitAreaCallback);
return this;
},
/**
* Shuffles the group members in place.
*
* @method Phaser.GameObjects.Group#shuffle
* @since 3.21.0
*
* @return {this} This Group object.
*/
shuffle: function() {
Actions.Shuffle(this.children.entries);
return this;
},
/**
* Deactivates a member of this group.
*
* @method Phaser.GameObjects.Group#kill
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - A member of this group.
*/
kill: function(gameObject) {
if (this.children.contains(gameObject)) {
gameObject.setActive(false);
}
},
/**
* Deactivates and hides a member of this group.
*
* @method Phaser.GameObjects.Group#killAndHide
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - A member of this group.
*/
killAndHide: function(gameObject) {
if (this.children.contains(gameObject)) {
gameObject.setActive(false);
gameObject.setVisible(false);
}
},
/**
* Sets the visible of each group member.
*
* @method Phaser.GameObjects.Group#setVisible
* @since 3.21.0
*
* @param {boolean} value - The value to set the property to.
* @param {number} [index=0] - An optional offset to start searching from within the items array.
* @param {number} [direction=1] - The direction to iterate through the array. 1 is from beginning to end, -1 from end to beginning.
*
* @return {this} This Group object.
*/
setVisible: function(value, index, direction) {
Actions.SetVisible(this.children.entries, value, index, direction);
return this;
},
/**
* Toggles (flips) the visible state of each member of this group.
*
* @method Phaser.GameObjects.Group#toggleVisible
* @since 3.0.0
*
* @return {this} This Group object.
*/
toggleVisible: function() {
Actions.ToggleVisible(this.children.entries);
return this;
},
/**
* Empties this Group of all children and removes it from the Scene.
*
* Does not call {@link Phaser.GameObjects.Group#removeCallback}.
*
* Children of this Group will _not_ be removed from the Scene by calling this method
* unless you specify the `removeFromScene` parameter.
*
* Children of this Group will also _not_ be destroyed by calling this method
* unless you specify the `destroyChildren` parameter.
*
* @method Phaser.GameObjects.Group#destroy
* @since 3.0.0
*
* @param {boolean} [destroyChildren=false] - Also {@link Phaser.GameObjects.GameObject#destroy} each Group member.
* @param {boolean} [removeFromScene=false] - Optionally remove each Group member from the Scene.
*/
destroy: function(destroyChildren, removeFromScene) {
if (destroyChildren === void 0) {
destroyChildren = false;
}
if (removeFromScene === void 0) {
removeFromScene = false;
}
if (!this.scene || this.ignoreDestroy) {
return;
}
this.emit(Events.DESTROY, this);
this.removeAllListeners();
this.scene.sys.updateList.remove(this);
this.clear(removeFromScene, destroyChildren);
this.scene = void 0;
this.children = void 0;
}
});
module2.exports = Group;
}
),
/***/
94975: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var GameObjectCreator = __webpack_require__2(44603);
var Group = __webpack_require__2(26479);
GameObjectCreator.register("group", function(config) {
return new Group(this.scene, null, config);
});
}
),
/***/
3385: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var Group = __webpack_require__2(26479);
var GameObjectFactory = __webpack_require__2(39429);
GameObjectFactory.register("group", function(children, config) {
return this.updateList.add(new Group(this.scene, children, config));
});
}
),
/***/
88571: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31401);
var GameObject = __webpack_require__2(95643);
var ImageRender = __webpack_require__2(59819);
var Image2 = new Class({
Extends: GameObject,
Mixins: [
Components.Alpha,
Components.BlendMode,
Components.Depth,
Components.Flip,
Components.GetBounds,
Components.Mask,
Components.Origin,
Components.Pipeline,
Components.PostPipeline,
Components.ScrollFactor,
Components.Size,
Components.TextureCrop,
Components.Tint,
Components.Transform,
Components.Visible,
ImageRender
],
initialize: function Image3(scene, x, y, texture, frame) {
GameObject.call(this, scene, "Image");
this._crop = this.resetCropObject();
this.setTexture(texture, frame);
this.setPosition(x, y);
this.setSizeToFrame();
this.setOriginFromFrame();
this.initPipeline();
this.initPostPipeline(true);
}
});
module2.exports = Image2;
}
),
/***/
40652: (
/***/
(module2) => {
var ImageCanvasRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
renderer.batchSprite(src, src.frame, camera, parentMatrix);
};
module2.exports = ImageCanvasRenderer;
}
),
/***/
82459: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var BuildGameObject = __webpack_require__2(25305);
var GameObjectCreator = __webpack_require__2(44603);
var GetAdvancedValue = __webpack_require__2(23568);
var Image2 = __webpack_require__2(88571);
GameObjectCreator.register("image", function(config, addToScene) {
if (config === void 0) {
config = {};
}
var key = GetAdvancedValue(config, "key", null);
var frame = GetAdvancedValue(config, "frame", null);
var image = new Image2(this.scene, 0, 0, key, frame);
if (addToScene !== void 0) {
config.add = addToScene;
}
BuildGameObject(this.scene, image, config);
return image;
});
}
),
/***/
2117: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var Image2 = __webpack_require__2(88571);
var GameObjectFactory = __webpack_require__2(39429);
GameObjectFactory.register("image", function(x, y, texture, frame) {
return this.displayList.add(new Image2(this.scene, x, y, texture, frame));
});
}
),
/***/
59819: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(99517);
}
if (true) {
renderCanvas = __webpack_require__2(40652);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
99517: (
/***/
(module2) => {
var ImageWebGLRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
this.pipeline.batchSprite(src, camera, parentMatrix);
};
module2.exports = ImageWebGLRenderer;
}
),
/***/
77856: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GameObjects = {
Events: __webpack_require__2(51708),
DisplayList: __webpack_require__2(8050),
GameObjectCreator: __webpack_require__2(44603),
GameObjectFactory: __webpack_require__2(39429),
UpdateList: __webpack_require__2(45027),
Components: __webpack_require__2(31401),
GetCalcMatrix: __webpack_require__2(91296),
BuildGameObject: __webpack_require__2(25305),
BuildGameObjectAnimation: __webpack_require__2(13059),
GameObject: __webpack_require__2(95643),
BitmapText: __webpack_require__2(22186),
Blitter: __webpack_require__2(6107),
Bob: __webpack_require__2(46590),
Container: __webpack_require__2(31559),
DOMElement: __webpack_require__2(3069),
DynamicBitmapText: __webpack_require__2(2638),
Extern: __webpack_require__2(42421),
Graphics: __webpack_require__2(43831),
Group: __webpack_require__2(26479),
Image: __webpack_require__2(88571),
Layer: __webpack_require__2(93595),
Particles: __webpack_require__2(18404),
PathFollower: __webpack_require__2(1159),
RenderTexture: __webpack_require__2(591),
RetroFont: __webpack_require__2(196),
Rope: __webpack_require__2(77757),
Sprite: __webpack_require__2(68287),
Text: __webpack_require__2(50171),
GetTextSize: __webpack_require__2(14220),
MeasureText: __webpack_require__2(79557),
TextStyle: __webpack_require__2(35762),
TileSprite: __webpack_require__2(20839),
Zone: __webpack_require__2(41481),
Video: __webpack_require__2(18471),
// Shapes
Shape: __webpack_require__2(17803),
Arc: __webpack_require__2(23629),
Curve: __webpack_require__2(89),
Ellipse: __webpack_require__2(19921),
Grid: __webpack_require__2(30479),
IsoBox: __webpack_require__2(61475),
IsoTriangle: __webpack_require__2(16933),
Line: __webpack_require__2(57847),
Polygon: __webpack_require__2(24949),
Rectangle: __webpack_require__2(74561),
Star: __webpack_require__2(55911),
Triangle: __webpack_require__2(36931),
// Game Object Factories
Factories: {
Blitter: __webpack_require__2(12709),
Container: __webpack_require__2(24961),
DOMElement: __webpack_require__2(2611),
DynamicBitmapText: __webpack_require__2(72566),
Extern: __webpack_require__2(56315),
Graphics: __webpack_require__2(1201),
Group: __webpack_require__2(3385),
Image: __webpack_require__2(2117),
Layer: __webpack_require__2(20005),
Particles: __webpack_require__2(676),
PathFollower: __webpack_require__2(90145),
RenderTexture: __webpack_require__2(60505),
Rope: __webpack_require__2(96819),
Sprite: __webpack_require__2(46409),
StaticBitmapText: __webpack_require__2(34914),
Text: __webpack_require__2(68005),
TileSprite: __webpack_require__2(91681),
Zone: __webpack_require__2(84175),
Video: __webpack_require__2(89025),
// Shapes
Arc: __webpack_require__2(42563),
Curve: __webpack_require__2(40511),
Ellipse: __webpack_require__2(1543),
Grid: __webpack_require__2(34137),
IsoBox: __webpack_require__2(3933),
IsoTriangle: __webpack_require__2(49803),
Line: __webpack_require__2(2481),
Polygon: __webpack_require__2(64827),
Rectangle: __webpack_require__2(87959),
Star: __webpack_require__2(93697),
Triangle: __webpack_require__2(45245)
},
Creators: {
Blitter: __webpack_require__2(9403),
Container: __webpack_require__2(77143),
DynamicBitmapText: __webpack_require__2(11164),
Graphics: __webpack_require__2(87079),
Group: __webpack_require__2(94975),
Image: __webpack_require__2(82459),
Layer: __webpack_require__2(25179),
Particles: __webpack_require__2(92730),
RenderTexture: __webpack_require__2(34495),
Rope: __webpack_require__2(26209),
Sprite: __webpack_require__2(15567),
StaticBitmapText: __webpack_require__2(57336),
Text: __webpack_require__2(71259),
TileSprite: __webpack_require__2(14167),
Zone: __webpack_require__2(95261),
Video: __webpack_require__2(11511)
}
};
if (true) {
GameObjects.Shader = __webpack_require__2(20071);
GameObjects.Mesh = __webpack_require__2(4703);
GameObjects.NineSlice = __webpack_require__2(28103);
GameObjects.PointLight = __webpack_require__2(80321);
GameObjects.Plane = __webpack_require__2(33663);
GameObjects.Factories.Shader = __webpack_require__2(74177);
GameObjects.Factories.Mesh = __webpack_require__2(9225);
GameObjects.Factories.NineSlice = __webpack_require__2(47521);
GameObjects.Factories.PointLight = __webpack_require__2(71255);
GameObjects.Factories.Plane = __webpack_require__2(30985);
GameObjects.Creators.Shader = __webpack_require__2(54935);
GameObjects.Creators.Mesh = __webpack_require__2(20527);
GameObjects.Creators.NineSlice = __webpack_require__2(28279);
GameObjects.Creators.PointLight = __webpack_require__2(39829);
GameObjects.Creators.Plane = __webpack_require__2(56015);
GameObjects.Light = __webpack_require__2(41432);
GameObjects.LightsManager = __webpack_require__2(61356);
GameObjects.LightsPlugin = __webpack_require__2(88992);
}
module2.exports = GameObjects;
}
),
/***/
93595: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BlendModes = __webpack_require__2(10312);
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31401);
var ComponentsToJSON = __webpack_require__2(53774);
var DataManager = __webpack_require__2(45893);
var EventEmitter = __webpack_require__2(50792);
var GameObjectEvents = __webpack_require__2(51708);
var List = __webpack_require__2(73162);
var Render = __webpack_require__2(33963);
var SceneEvents = __webpack_require__2(44594);
var StableSort = __webpack_require__2(19186);
var Layer = new Class({
Extends: List,
Mixins: [
Components.AlphaSingle,
Components.BlendMode,
Components.Depth,
Components.Mask,
Components.PostPipeline,
Components.Visible,
EventEmitter,
Render
],
initialize: function Layer2(scene, children) {
List.call(this, scene);
EventEmitter.call(this);
this.scene = scene;
this.displayList = null;
this.type = "Layer";
this.state = 0;
this.parentContainer = null;
this.name = "";
this.active = true;
this.tabIndex = -1;
this.data = null;
this.renderFlags = 15;
this.cameraFilter = 0;
this.input = null;
this.body = null;
this.ignoreDestroy = false;
this.systems = scene.sys;
this.events = scene.sys.events;
this.sortChildrenFlag = false;
this.addCallback = this.addChildCallback;
this.removeCallback = this.removeChildCallback;
this.initPostPipeline();
this.clearAlpha();
this.setBlendMode(BlendModes.SKIP_CHECK);
if (children) {
this.add(children);
}
scene.sys.queueDepthSort();
},
/**
* Sets the `active` property of this Game Object and returns this Game Object for further chaining.
* A Game Object with its `active` property set to `true` will be updated by the Scenes UpdateList.
*
* @method Phaser.GameObjects.Layer#setActive
* @since 3.50.0
*
* @param {boolean} value - True if this Game Object should be set as active, false if not.
*
* @return {this} This GameObject.
*/
setActive: function(value) {
this.active = value;
return this;
},
/**
* Sets the `name` property of this Game Object and returns this Game Object for further chaining.
* The `name` property is not populated by Phaser and is presented for your own use.
*
* @method Phaser.GameObjects.Layer#setName
* @since 3.50.0
*
* @param {string} value - The name to be given to this Game Object.
*
* @return {this} This GameObject.
*/
setName: function(value) {
this.name = value;
return this;
},
/**
* Sets the current state of this Game Object.
*
* Phaser itself will never modify the State of a Game Object, although plugins may do so.
*
* For example, a Game Object could change from a state of 'moving', to 'attacking', to 'dead'.
* The state value should typically be an integer (ideally mapped to a constant
* in your game code), but could also be a string. It is recommended to keep it light and simple.
* If you need to store complex data about your Game Object, look at using the Data Component instead.
*
* @method Phaser.GameObjects.Layer#setState
* @since 3.50.0
*
* @param {(number|string)} value - The state of the Game Object.
*
* @return {this} This GameObject.
*/
setState: function(value) {
this.state = value;
return this;
},
/**
* Adds a Data Manager component to this Game Object.
*
* @method Phaser.GameObjects.Layer#setDataEnabled
* @since 3.50.0
* @see Phaser.Data.DataManager
*
* @return {this} This GameObject.
*/
setDataEnabled: function() {
if (!this.data) {
this.data = new DataManager(this);
}
return this;
},
/**
* Allows you to store a key value pair within this Game Objects Data Manager.
*
* If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled
* before setting the value.
*
* If the key doesn't already exist in the Data Manager then it is created.
*
* ```javascript
* sprite.setData('name', 'Red Gem Stone');
* ```
*
* You can also pass in an object of key value pairs as the first argument:
*
* ```javascript
* sprite.setData({ name: 'Red Gem Stone', level: 2, owner: 'Link', gold: 50 });
* ```
*
* To get a value back again you can call `getData`:
*
* ```javascript
* sprite.getData('gold');
* ```
*
* Or you can access the value directly via the `values` property, where it works like any other variable:
*
* ```javascript
* sprite.data.values.gold += 50;
* ```
*
* When the value is first set, a `setdata` event is emitted from this Game Object.
*
* If the key already exists, a `changedata` event is emitted instead, along an event named after the key.
* For example, if you updated an existing key called `PlayerLives` then it would emit the event `changedata-PlayerLives`.
* These events will be emitted regardless if you use this method to set the value, or the direct `values` setter.
*
* Please note that the data keys are case-sensitive and must be valid JavaScript Object property strings.
* This means the keys `gold` and `Gold` are treated as two unique values within the Data Manager.
*
* @method Phaser.GameObjects.Layer#setData
* @since 3.50.0
*
* @param {(string|object)} key - The key to set the value for. Or an object of key value pairs. If an object the `data` argument is ignored.
* @param {*} [data] - The value to set for the given key. If an object is provided as the key this argument is ignored.
*
* @return {this} This GameObject.
*/
setData: function(key, value) {
if (!this.data) {
this.data = new DataManager(this);
}
this.data.set(key, value);
return this;
},
/**
* Increase a value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is increased from 0.
*
* If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled
* before setting the value.
*
* If the key doesn't already exist in the Data Manager then it is created.
*
* When the value is first set, a `setdata` event is emitted from this Game Object.
*
* @method Phaser.GameObjects.Layer#incData
* @since 3.50.0
*
* @param {(string|object)} key - The key to increase the value for.
* @param {*} [data] - The value to increase for the given key.
*
* @return {this} This GameObject.
*/
incData: function(key, value) {
if (!this.data) {
this.data = new DataManager(this);
}
this.data.inc(key, value);
return this;
},
/**
* Toggle a boolean value for the given key within this Game Objects Data Manager. If the key doesn't already exist in the Data Manager then it is toggled from false.
*
* If the Game Object has not been enabled for data (via `setDataEnabled`) then it will be enabled
* before setting the value.
*
* If the key doesn't already exist in the Data Manager then it is created.
*
* When the value is first set, a `setdata` event is emitted from this Game Object.
*
* @method Phaser.GameObjects.Layer#toggleData
* @since 3.50.0
*
* @param {(string|object)} key - The key to toggle the value for.
*
* @return {this} This GameObject.
*/
toggleData: function(key) {
if (!this.data) {
this.data = new DataManager(this);
}
this.data.toggle(key);
return this;
},
/**
* Retrieves the value for the given key in this Game Objects Data Manager, or undefined if it doesn't exist.
*
* You can also access values via the `values` object. For example, if you had a key called `gold` you can do either:
*
* ```javascript
* sprite.getData('gold');
* ```
*
* Or access the value directly:
*
* ```javascript
* sprite.data.values.gold;
* ```
*
* You can also pass in an array of keys, in which case an array of values will be returned:
*
* ```javascript
* sprite.getData([ 'gold', 'armor', 'health' ]);
* ```
*
* This approach is useful for destructuring arrays in ES6.
*
* @method Phaser.GameObjects.Layer#getData
* @since 3.50.0
*
* @param {(string|string[])} key - The key of the value to retrieve, or an array of keys.
*
* @return {*} The value belonging to the given key, or an array of values, the order of which will match the input array.
*/
getData: function(key) {
if (!this.data) {
this.data = new DataManager(this);
}
return this.data.get(key);
},
/**
* A Layer cannot be enabled for input.
*
* This method does nothing and is kept to ensure
* the Layer has the same shape as a Game Object.
*
* @method Phaser.GameObjects.Layer#setInteractive
* @since 3.51.0
*
* @return {this} This GameObject.
*/
setInteractive: function() {
return this;
},
/**
* A Layer cannot be enabled for input.
*
* This method does nothing and is kept to ensure
* the Layer has the same shape as a Game Object.
*
* @method Phaser.GameObjects.Layer#disableInteractive
* @since 3.51.0
*
* @return {this} This GameObject.
*/
disableInteractive: function() {
return this;
},
/**
* A Layer cannot be enabled for input.
*
* This method does nothing and is kept to ensure
* the Layer has the same shape as a Game Object.
*
* @method Phaser.GameObjects.Layer#removeInteractive
* @since 3.51.0
*
* @return {this} This GameObject.
*/
removeInteractive: function() {
return this;
},
/**
* This callback is invoked when this Game Object is added to a Scene.
*
* Can be overriden by custom Game Objects, but be aware of some Game Objects that
* will use this, such as Sprites, to add themselves into the Update List.
*
* You can also listen for the `ADDED_TO_SCENE` event from this Game Object.
*
* @method Phaser.GameObjects.Layer#addedToScene
* @since 3.50.0
*/
addedToScene: function() {
},
/**
* This callback is invoked when this Game Object is removed from a Scene.
*
* Can be overriden by custom Game Objects, but be aware of some Game Objects that
* will use this, such as Sprites, to removed themselves from the Update List.
*
* You can also listen for the `REMOVED_FROM_SCENE` event from this Game Object.
*
* @method Phaser.GameObjects.Layer#removedFromScene
* @since 3.50.0
*/
removedFromScene: function() {
},
/**
* To be overridden by custom GameObjects. Allows base objects to be used in a Pool.
*
* @method Phaser.GameObjects.Layer#update
* @since 3.50.0
*
* @param {...*} [args] - args
*/
update: function() {
},
/**
* Returns a JSON representation of the Game Object.
*
* @method Phaser.GameObjects.Layer#toJSON
* @since 3.50.0
*
* @return {Phaser.Types.GameObjects.JSONGameObject} A JSON representation of the Game Object.
*/
toJSON: function() {
return ComponentsToJSON(this);
},
/**
* Compares the renderMask with the renderFlags to see if this Game Object will render or not.
* Also checks the Game Object against the given Cameras exclusion list.
*
* @method Phaser.GameObjects.Layer#willRender
* @since 3.50.0
*
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to check against this Game Object.
*
* @return {boolean} True if the Game Object should be rendered, otherwise false.
*/
willRender: function(camera) {
return !(this.renderFlags !== 15 || this.list.length === 0 || this.cameraFilter !== 0 && this.cameraFilter & camera.id);
},
/**
* Returns an array containing the display list index of either this Game Object, or if it has one,
* its parent Container. It then iterates up through all of the parent containers until it hits the
* root of the display list (which is index 0 in the returned array).
*
* Used internally by the InputPlugin but also useful if you wish to find out the display depth of
* this Game Object and all of its ancestors.
*
* @method Phaser.GameObjects.Layer#getIndexList
* @since 3.51.0
*
* @return {number[]} An array of display list position indexes.
*/
getIndexList: function() {
var child = this;
var parent = this.parentContainer;
var indexes = [];
while (parent) {
indexes.unshift(parent.getIndex(child));
child = parent;
if (!parent.parentContainer) {
break;
} else {
parent = parent.parentContainer;
}
}
indexes.unshift(this.displayList.getIndex(child));
return indexes;
},
/**
* Internal method called from `List.addCallback`.
*
* @method Phaser.GameObjects.Layer#addChildCallback
* @private
* @fires Phaser.Scenes.Events#ADDED_TO_SCENE
* @fires Phaser.GameObjects.Events#ADDED_TO_SCENE
* @since 3.50.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was added to the list.
*/
addChildCallback: function(gameObject) {
var displayList = gameObject.displayList;
if (displayList && displayList !== this) {
gameObject.removeFromDisplayList();
}
if (!gameObject.displayList) {
this.queueDepthSort();
gameObject.displayList = this;
gameObject.emit(GameObjectEvents.ADDED_TO_SCENE, gameObject, this.scene);
this.events.emit(SceneEvents.ADDED_TO_SCENE, gameObject, this.scene);
}
},
/**
* Internal method called from `List.removeCallback`.
*
* @method Phaser.GameObjects.Layer#removeChildCallback
* @private
* @fires Phaser.Scenes.Events#REMOVED_FROM_SCENE
* @fires Phaser.GameObjects.Events#REMOVED_FROM_SCENE
* @since 3.50.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was removed from the list.
*/
removeChildCallback: function(gameObject) {
this.queueDepthSort();
gameObject.displayList = null;
gameObject.emit(GameObjectEvents.REMOVED_FROM_SCENE, gameObject, this.scene);
this.events.emit(SceneEvents.REMOVED_FROM_SCENE, gameObject, this.scene);
},
/**
* Force a sort of the display list on the next call to depthSort.
*
* @method Phaser.GameObjects.Layer#queueDepthSort
* @since 3.50.0
*/
queueDepthSort: function() {
this.sortChildrenFlag = true;
},
/**
* Immediately sorts the display list if the flag is set.
*
* @method Phaser.GameObjects.Layer#depthSort
* @since 3.50.0
*/
depthSort: function() {
if (this.sortChildrenFlag) {
StableSort(this.list, this.sortByDepth);
this.sortChildrenFlag = false;
}
},
/**
* Compare the depth of two Game Objects.
*
* @method Phaser.GameObjects.Layer#sortByDepth
* @since 3.50.0
*
* @param {Phaser.GameObjects.GameObject} childA - The first Game Object.
* @param {Phaser.GameObjects.GameObject} childB - The second Game Object.
*
* @return {number} The difference between the depths of each Game Object.
*/
sortByDepth: function(childA, childB) {
return childA._depth - childB._depth;
},
/**
* Returns a reference to the array which contains all Game Objects in this Layer.
*
* This is a reference, not a copy of it, so be very careful not to mutate it.
*
* @method Phaser.GameObjects.Layer#getChildren
* @since 3.50.0
*
* @return {Phaser.GameObjects.GameObject[]} An array of Game Objects within this Layer.
*/
getChildren: function() {
return this.list;
},
/**
* Adds this Layer to the given Display List.
*
* If no Display List is specified, it will default to the Display List owned by the Scene to which
* this Layer belongs.
*
* A Layer can only exist on one Display List at any given time, but may move freely between them.
*
* If this Layer is already on another Display List when this method is called, it will first
* be removed from it, before being added to the new list.
*
* You can query which list it is on by looking at the `Phaser.GameObjects.Layer#displayList` property.
*
* If a Layer isn't on any display list, it will not be rendered. If you just wish to temporarily
* disable it from rendering, consider using the `setVisible` method, instead.
*
* @method Phaser.GameObjects.Layer#addToDisplayList
* @fires Phaser.Scenes.Events#ADDED_TO_SCENE
* @fires Phaser.GameObjects.Events#ADDED_TO_SCENE
* @since 3.60.0
*
* @param {(Phaser.GameObjects.DisplayList|Phaser.GameObjects.Layer)} [displayList] - The Display List to add to. Defaults to the Scene Display List.
*
* @return {this} This Layer instance.
*/
addToDisplayList: function(displayList) {
if (displayList === void 0) {
displayList = this.scene.sys.displayList;
}
if (this.displayList && this.displayList !== displayList) {
this.removeFromDisplayList();
}
if (!displayList.exists(this)) {
this.displayList = displayList;
displayList.add(this, true);
displayList.queueDepthSort();
this.emit(GameObjectEvents.ADDED_TO_SCENE, this, this.scene);
displayList.events.emit(SceneEvents.ADDED_TO_SCENE, this, this.scene);
}
return this;
},
/**
* Removes this Layer from the Display List it is currently on.
*
* A Layer can only exist on one Display List at any given time, but may move freely removed
* and added back at a later stage.
*
* You can query which list it is on by looking at the `Phaser.GameObjects.GameObject#displayList` property.
*
* If a Layer isn't on any Display List, it will not be rendered. If you just wish to temporarily
* disable it from rendering, consider using the `setVisible` method, instead.
*
* @method Phaser.GameObjects.Layer#removeFromDisplayList
* @fires Phaser.Scenes.Events#REMOVED_FROM_SCENE
* @fires Phaser.GameObjects.Events#REMOVED_FROM_SCENE
* @since 3.60.0
*
* @return {this} This Layer instance.
*/
removeFromDisplayList: function() {
var displayList = this.displayList || this.scene.sys.displayList;
if (displayList.exists(this)) {
displayList.remove(this, true);
displayList.queueDepthSort();
this.displayList = null;
this.emit(GameObjectEvents.REMOVED_FROM_SCENE, this, this.scene);
displayList.events.emit(SceneEvents.REMOVED_FROM_SCENE, this, this.scene);
}
return this;
},
/**
* Destroys this Layer removing it from the Display List and Update List and
* severing all ties to parent resources.
*
* Also destroys all children of this Layer. If you do not wish for the
* children to be destroyed, you should move them from this Layer first.
*
* Use this to remove this Layer from your game if you don't ever plan to use it again.
* As long as no reference to it exists within your own code it should become free for
* garbage collection by the browser.
*
* If you just want to temporarily disable an object then look at using the
* Game Object Pool instead of destroying it, as destroyed objects cannot be resurrected.
*
* @method Phaser.GameObjects.Layer#destroy
* @fires Phaser.GameObjects.Events#DESTROY
* @since 3.50.0
*
* @param {boolean} [fromScene=false] - `True` if this Game Object is being destroyed by the Scene, `false` if not.
*/
destroy: function(fromScene) {
if (!this.scene || this.ignoreDestroy) {
return;
}
this.emit(GameObjectEvents.DESTROY, this);
var list = this.list;
while (list.length) {
list[0].destroy(fromScene);
}
this.removeAllListeners();
this.resetPostPipeline(true);
if (this.displayList) {
this.displayList.remove(this, true, false);
this.displayList.queueDepthSort();
}
if (this.data) {
this.data.destroy();
this.data = void 0;
}
this.active = false;
this.visible = false;
this.list = void 0;
this.scene = void 0;
this.displayList = void 0;
this.systems = void 0;
this.events = void 0;
}
/**
* Return an array listing the events for which the emitter has registered listeners.
*
* @method Phaser.GameObjects.Layer#eventNames
* @since 3.50.0
*
* @return {Array.<string|symbol>}
*/
/**
* Return the listeners registered for a given event.
*
* @method Phaser.GameObjects.Layer#listeners
* @since 3.50.0
*
* @param {(string|symbol)} event - The event name.
*
* @return {Function[]} The registered listeners.
*/
/**
* Return the number of listeners listening to a given event.
*
* @method Phaser.GameObjects.Layer#listenerCount
* @since 3.50.0
*
* @param {(string|symbol)} event - The event name.
*
* @return {number} The number of listeners.
*/
/**
* Calls each of the listeners registered for a given event.
*
* @method Phaser.GameObjects.Layer#emit
* @since 3.50.0
*
* @param {(string|symbol)} event - The event name.
* @param {...*} [args] - Additional arguments that will be passed to the event handler.
*
* @return {boolean} `true` if the event had listeners, else `false`.
*/
/**
* Add a listener for a given event.
*
* @method Phaser.GameObjects.Layer#on
* @since 3.50.0
*
* @param {(string|symbol)} event - The event name.
* @param {function} fn - The listener function.
* @param {*} [context=this] - The context to invoke the listener with.
*
* @return {this} This Layer instance.
*/
/**
* Add a listener for a given event.
*
* @method Phaser.GameObjects.Layer#addListener
* @since 3.50.0
*
* @param {(string|symbol)} event - The event name.
* @param {function} fn - The listener function.
* @param {*} [context=this] - The context to invoke the listener with.
*
* @return {this} This Layer instance.
*/
/**
* Add a one-time listener for a given event.
*
* @method Phaser.GameObjects.Layer#once
* @since 3.50.0
*
* @param {(string|symbol)} event - The event name.
* @param {function} fn - The listener function.
* @param {*} [context=this] - The context to invoke the listener with.
*
* @return {this} This Layer instance.
*/
/**
* Remove the listeners of a given event.
*
* @method Phaser.GameObjects.Layer#removeListener
* @since 3.50.0
*
* @param {(string|symbol)} event - The event name.
* @param {function} [fn] - Only remove the listeners that match this function.
* @param {*} [context] - Only remove the listeners that have this context.
* @param {boolean} [once] - Only remove one-time listeners.
*
* @return {this} This Layer instance.
*/
/**
* Remove the listeners of a given event.
*
* @method Phaser.GameObjects.Layer#off
* @since 3.50.0
*
* @param {(string|symbol)} event - The event name.
* @param {function} [fn] - Only remove the listeners that match this function.
* @param {*} [context] - Only remove the listeners that have this context.
* @param {boolean} [once] - Only remove one-time listeners.
*
* @return {this} This Layer instance.
*/
/**
* Remove all listeners, or those of the specified event.
*
* @method Phaser.GameObjects.Layer#removeAllListeners
* @since 3.50.0
*
* @param {(string|symbol)} [event] - The event name.
*
* @return {this} This Layer instance.
*/
});
module2.exports = Layer;
}
),
/***/
2956: (
/***/
(module2) => {
var LayerCanvasRenderer = function(renderer, layer, camera) {
var children = layer.list;
if (children.length === 0) {
return;
}
layer.depthSort();
var layerHasBlendMode = layer.blendMode !== -1;
if (!layerHasBlendMode) {
renderer.setBlendMode(0);
}
var alpha = layer._alpha;
if (layer.mask) {
layer.mask.preRenderCanvas(renderer, null, camera);
}
for (var i = 0; i < children.length; i++) {
var child = children[i];
if (!child.willRender(camera)) {
continue;
}
var childAlpha = child.alpha;
if (!layerHasBlendMode && child.blendMode !== renderer.currentBlendMode) {
renderer.setBlendMode(child.blendMode);
}
child.setAlpha(childAlpha * alpha);
child.renderCanvas(renderer, child, camera);
child.setAlpha(childAlpha);
}
if (layer.mask) {
layer.mask.postRenderCanvas(renderer);
}
};
module2.exports = LayerCanvasRenderer;
}
),
/***/
25179: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var BuildGameObject = __webpack_require__2(25305);
var Layer = __webpack_require__2(93595);
var GameObjectCreator = __webpack_require__2(44603);
var GetAdvancedValue = __webpack_require__2(23568);
GameObjectCreator.register("layer", function(config, addToScene) {
if (config === void 0) {
config = {};
}
var children = GetAdvancedValue(config, "children", null);
var layer = new Layer(this.scene, children);
if (addToScene !== void 0) {
config.add = addToScene;
}
BuildGameObject(this.scene, layer, config);
return layer;
});
}
),
/***/
20005: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var Layer = __webpack_require__2(93595);
var GameObjectFactory = __webpack_require__2(39429);
GameObjectFactory.register("layer", function(children) {
return this.displayList.add(new Layer(this.scene, children));
});
}
),
/***/
33963: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(15869);
}
if (true) {
renderCanvas = __webpack_require__2(2956);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
15869: (
/***/
(module2) => {
var LayerWebGLRenderer = function(renderer, layer, camera) {
var children = layer.list;
var childCount = children.length;
if (childCount === 0) {
return;
}
layer.depthSort();
renderer.pipelines.preBatch(layer);
var layerHasBlendMode = layer.blendMode !== -1;
if (!layerHasBlendMode) {
renderer.setBlendMode(0);
}
var alpha = layer.alpha;
for (var i = 0; i < childCount; i++) {
var child = children[i];
if (!child.willRender(camera)) {
continue;
}
var childAlphaTopLeft;
var childAlphaTopRight;
var childAlphaBottomLeft;
var childAlphaBottomRight;
if (child.alphaTopLeft !== void 0) {
childAlphaTopLeft = child.alphaTopLeft;
childAlphaTopRight = child.alphaTopRight;
childAlphaBottomLeft = child.alphaBottomLeft;
childAlphaBottomRight = child.alphaBottomRight;
} else {
var childAlpha = child.alpha;
childAlphaTopLeft = childAlpha;
childAlphaTopRight = childAlpha;
childAlphaBottomLeft = childAlpha;
childAlphaBottomRight = childAlpha;
}
if (!layerHasBlendMode && child.blendMode !== renderer.currentBlendMode) {
renderer.setBlendMode(child.blendMode);
}
var mask = child.mask;
if (mask) {
mask.preRenderWebGL(renderer, child, camera);
}
var type = child.type;
if (type !== renderer.currentType) {
renderer.newType = true;
renderer.currentType = type;
}
renderer.nextTypeMatch = i < childCount - 1 ? children[i + 1].type === renderer.currentType : false;
child.setAlpha(childAlphaTopLeft * alpha, childAlphaTopRight * alpha, childAlphaBottomLeft * alpha, childAlphaBottomRight * alpha);
child.renderWebGL(renderer, child, camera);
child.setAlpha(childAlphaTopLeft, childAlphaTopRight, childAlphaBottomLeft, childAlphaBottomRight);
if (mask) {
mask.postRenderWebGL(renderer, camera);
}
renderer.newType = false;
}
renderer.pipelines.postBatch(layer);
};
module2.exports = LayerWebGLRenderer;
}
),
/***/
41432: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Circle = __webpack_require__2(96503);
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31401);
var RGB = __webpack_require__2(51767);
var Utils = __webpack_require__2(70554);
var Light = new Class({
Extends: Circle,
Mixins: [
Components.Origin,
Components.ScrollFactor,
Components.Visible
],
initialize: function Light2(x, y, radius, r, g, b, intensity) {
Circle.call(this, x, y, radius);
this.color = new RGB(r, g, b);
this.intensity = intensity;
this.renderFlags = 15;
this.cameraFilter = 0;
this.setScrollFactor(1, 1);
this.setOrigin();
this.setDisplayOrigin(radius);
},
/**
* The width of this Light Game Object. This is the same as `Light.diameter`.
*
* @name Phaser.GameObjects.Light#displayWidth
* @type {number}
* @since 3.60.0
*/
displayWidth: {
get: function() {
return this.diameter;
},
set: function(value) {
this.diameter = value;
}
},
/**
* The height of this Light Game Object. This is the same as `Light.diameter`.
*
* @name Phaser.GameObjects.Light#displayHeight
* @type {number}
* @since 3.60.0
*/
displayHeight: {
get: function() {
return this.diameter;
},
set: function(value) {
this.diameter = value;
}
},
/**
* The width of this Light Game Object. This is the same as `Light.diameter`.
*
* @name Phaser.GameObjects.Light#width
* @type {number}
* @since 3.60.0
*/
width: {
get: function() {
return this.diameter;
},
set: function(value) {
this.diameter = value;
}
},
/**
* The height of this Light Game Object. This is the same as `Light.diameter`.
*
* @name Phaser.GameObjects.Light#height
* @type {number}
* @since 3.60.0
*/
height: {
get: function() {
return this.diameter;
},
set: function(value) {
this.diameter = value;
}
},
/**
* Compares the renderMask with the renderFlags to see if this Game Object will render or not.
* Also checks the Game Object against the given Cameras exclusion list.
*
* @method Phaser.GameObjects.Light#willRender
* @since 3.50.0
*
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to check against this Game Object.
*
* @return {boolean} True if the Game Object should be rendered, otherwise false.
*/
willRender: function(camera) {
return !(Light.RENDER_MASK !== this.renderFlags || this.cameraFilter !== 0 && this.cameraFilter & camera.id);
},
/**
* Set the color of the light from a single integer RGB value.
*
* @method Phaser.GameObjects.Light#setColor
* @since 3.0.0
*
* @param {number} rgb - The integer RGB color of the light.
*
* @return {this} This Light object.
*/
setColor: function(rgb) {
var color = Utils.getFloatsFromUintRGB(rgb);
this.color.set(color[0], color[1], color[2]);
return this;
},
/**
* Set the intensity of the light.
*
* @method Phaser.GameObjects.Light#setIntensity
* @since 3.0.0
*
* @param {number} intensity - The intensity of the light.
*
* @return {this} This Light object.
*/
setIntensity: function(intensity) {
this.intensity = intensity;
return this;
},
/**
* Set the radius of the light.
*
* @method Phaser.GameObjects.Light#setRadius
* @since 3.0.0
*
* @param {number} radius - The radius of the light.
*
* @return {this} This Light object.
*/
setRadius: function(radius) {
this.radius = radius;
return this;
}
});
Light.RENDER_MASK = 15;
module2.exports = Light;
}
),
/***/
61356: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CircleToRectangle = __webpack_require__2(81491);
var Class = __webpack_require__2(83419);
var DistanceBetween = __webpack_require__2(20339);
var Light = __webpack_require__2(41432);
var PointLight = __webpack_require__2(80321);
var RGB = __webpack_require__2(51767);
var SpliceOne = __webpack_require__2(19133);
var StableSort = __webpack_require__2(19186);
var Utils = __webpack_require__2(70554);
var LightsManager = new Class({
initialize: function LightsManager2() {
this.lights = [];
this.ambientColor = new RGB(0.1, 0.1, 0.1);
this.active = false;
this.maxLights = -1;
this.visibleLights = 0;
},
/**
* Creates a new Point Light Game Object and adds it to the Scene.
*
* Note: This method will only be available if the Point Light Game Object has been built into Phaser.
*
* The Point Light Game Object provides a way to add a point light effect into your game,
* without the expensive shader processing requirements of the traditional Light Game Object.
*
* The difference is that the Point Light renders using a custom shader, designed to give the
* impression of a point light source, of variable radius, intensity and color, in your game.
* However, unlike the Light Game Object, it does not impact any other Game Objects, or use their
* normal maps for calcuations. This makes them extremely fast to render compared to Lights
* and perfect for special effects, such as flickering torches or muzzle flashes.
*
* For maximum performance you should batch Point Light Game Objects together. This means
* ensuring they follow each other consecutively on the display list. Ideally, use a Layer
* Game Object and then add just Point Lights to it, so that it can batch together the rendering
* of the lights. You don't _have_ to do this, and if you've only a handful of Point Lights in
* your game then it's perfectly safe to mix them into the dislay list as normal. However, if
* you're using a large number of them, please consider how they are mixed into the display list.
*
* The renderer will automatically cull Point Lights. Those with a radius that does not intersect
* with the Camera will be skipped in the rendering list. This happens automatically and the
* culled state is refreshed every frame, for every camera.
*
* The origin of a Point Light is always 0.5 and it cannot be changed.
*
* Point Lights are a WebGL only feature and do not have a Canvas counterpart.
*
* @method Phaser.GameObjects.LightsManager#addPointLight
* @since 3.50.0
*
* @param {number} x - The horizontal position of this Point Light in the world.
* @param {number} y - The vertical position of this Point Light in the world.
* @param {number} [color=0xffffff] - The color of the Point Light, given as a hex value.
* @param {number} [radius=128] - The radius of the Point Light.
* @param {number} [intensity=1] - The intensity, or color blend, of the Point Light.
* @param {number} [attenuation=0.1] - The attenuation of the Point Light. This is the reduction of light from the center point.
*
* @return {Phaser.GameObjects.PointLight} The Game Object that was created.
*/
addPointLight: function(x, y, color, radius, intensity, attenuation) {
return this.systems.displayList.add(new PointLight(this.scene, x, y, color, radius, intensity, attenuation));
},
/**
* Enable the Lights Manager.
*
* @method Phaser.GameObjects.LightsManager#enable
* @since 3.0.0
*
* @return {this} This Lights Manager instance.
*/
enable: function() {
if (this.maxLights === -1) {
this.maxLights = this.systems.renderer.config.maxLights;
}
this.active = true;
return this;
},
/**
* Disable the Lights Manager.
*
* @method Phaser.GameObjects.LightsManager#disable
* @since 3.0.0
*
* @return {this} This Lights Manager instance.
*/
disable: function() {
this.active = false;
return this;
},
/**
* Get all lights that can be seen by the given Camera.
*
* It will automatically cull lights that are outside the world view of the Camera.
*
* If more lights are returned than supported by the pipeline, the lights are then culled
* based on the distance from the center of the camera. Only those closest are rendered.
*
* @method Phaser.GameObjects.LightsManager#getLights
* @since 3.50.0
*
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to cull Lights for.
*
* @return {Phaser.GameObjects.Light[]} The culled Lights.
*/
getLights: function(camera) {
var lights = this.lights;
var worldView = camera.worldView;
var visibleLights = [];
for (var i = 0; i < lights.length; i++) {
var light = lights[i];
if (light.willRender(camera) && CircleToRectangle(light, worldView)) {
visibleLights.push({
light,
distance: DistanceBetween(light.x, light.y, worldView.centerX, worldView.centerY)
});
}
}
if (visibleLights.length > this.maxLights) {
StableSort(visibleLights, this.sortByDistance);
visibleLights = visibleLights.slice(0, this.maxLights);
}
this.visibleLights = visibleLights.length;
return visibleLights;
},
sortByDistance: function(a, b) {
return a.distance >= b.distance;
},
/**
* Set the ambient light color.
*
* @method Phaser.GameObjects.LightsManager#setAmbientColor
* @since 3.0.0
*
* @param {number} rgb - The integer RGB color of the ambient light.
*
* @return {this} This Lights Manager instance.
*/
setAmbientColor: function(rgb) {
var color = Utils.getFloatsFromUintRGB(rgb);
this.ambientColor.set(color[0], color[1], color[2]);
return this;
},
/**
* Returns the maximum number of Lights allowed to appear at once.
*
* @method Phaser.GameObjects.LightsManager#getMaxVisibleLights
* @since 3.0.0
*
* @return {number} The maximum number of Lights allowed to appear at once.
*/
getMaxVisibleLights: function() {
return this.maxLights;
},
/**
* Get the number of Lights managed by this Lights Manager.
*
* @method Phaser.GameObjects.LightsManager#getLightCount
* @since 3.0.0
*
* @return {number} The number of Lights managed by this Lights Manager.
*/
getLightCount: function() {
return this.lights.length;
},
/**
* Add a Light.
*
* @method Phaser.GameObjects.LightsManager#addLight
* @since 3.0.0
*
* @param {number} [x=0] - The horizontal position of the Light.
* @param {number} [y=0] - The vertical position of the Light.
* @param {number} [radius=128] - The radius of the Light.
* @param {number} [rgb=0xffffff] - The integer RGB color of the light.
* @param {number} [intensity=1] - The intensity of the Light.
*
* @return {Phaser.GameObjects.Light} The Light that was added.
*/
addLight: function(x, y, radius, rgb, intensity) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (radius === void 0) {
radius = 128;
}
if (rgb === void 0) {
rgb = 16777215;
}
if (intensity === void 0) {
intensity = 1;
}
var color = Utils.getFloatsFromUintRGB(rgb);
var light = new Light(x, y, radius, color[0], color[1], color[2], intensity);
this.lights.push(light);
return light;
},
/**
* Remove a Light.
*
* @method Phaser.GameObjects.LightsManager#removeLight
* @since 3.0.0
*
* @param {Phaser.GameObjects.Light} light - The Light to remove.
*
* @return {this} This Lights Manager instance.
*/
removeLight: function(light) {
var index = this.lights.indexOf(light);
if (index >= 0) {
SpliceOne(this.lights, index);
}
return this;
},
/**
* Shut down the Lights Manager.
*
* Recycles all active Lights into the Light pool, resets ambient light color and clears the lists of Lights and
* culled Lights.
*
* @method Phaser.GameObjects.LightsManager#shutdown
* @since 3.0.0
*/
shutdown: function() {
this.lights.length = 0;
},
/**
* Destroy the Lights Manager.
*
* Cleans up all references by calling {@link Phaser.GameObjects.LightsManager#shutdown}.
*
* @method Phaser.GameObjects.LightsManager#destroy
* @since 3.0.0
*/
destroy: function() {
this.shutdown();
}
});
module2.exports = LightsManager;
}
),
/***/
88992: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var LightsManager = __webpack_require__2(61356);
var PluginCache = __webpack_require__2(37277);
var SceneEvents = __webpack_require__2(44594);
var LightsPlugin = new Class({
Extends: LightsManager,
initialize: function LightsPlugin2(scene) {
this.scene = scene;
this.systems = scene.sys;
if (!scene.sys.settings.isBooted) {
scene.sys.events.once(SceneEvents.BOOT, this.boot, this);
}
LightsManager.call(this);
},
/**
* Boot the Lights Plugin.
*
* @method Phaser.GameObjects.LightsPlugin#boot
* @since 3.0.0
*/
boot: function() {
var eventEmitter = this.systems.events;
eventEmitter.on(SceneEvents.SHUTDOWN, this.shutdown, this);
eventEmitter.on(SceneEvents.DESTROY, this.destroy, this);
},
/**
* Destroy the Lights Plugin.
*
* Cleans up all references.
*
* @method Phaser.GameObjects.LightsPlugin#destroy
* @since 3.0.0
*/
destroy: function() {
this.shutdown();
this.scene = void 0;
this.systems = void 0;
}
});
PluginCache.register("LightsPlugin", LightsPlugin, "lights");
module2.exports = LightsPlugin;
}
),
/***/
4703: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31401);
var DegToRad = __webpack_require__2(39506);
var Face = __webpack_require__2(83997);
var GameObject = __webpack_require__2(95643);
var GenerateObjVerts = __webpack_require__2(34684);
var GenerateVerts = __webpack_require__2(92515);
var GetCalcMatrix = __webpack_require__2(91296);
var Matrix4 = __webpack_require__2(37867);
var MeshRender = __webpack_require__2(29807);
var RadToDeg = __webpack_require__2(43396);
var StableSort = __webpack_require__2(19186);
var Vector3 = __webpack_require__2(25836);
var Vertex = __webpack_require__2(39318);
var Mesh = new Class({
Extends: GameObject,
Mixins: [
Components.AlphaSingle,
Components.BlendMode,
Components.Depth,
Components.Mask,
Components.Pipeline,
Components.PostPipeline,
Components.ScrollFactor,
Components.Size,
Components.Texture,
Components.Transform,
Components.Visible,
MeshRender
],
initialize: function Mesh2(scene, x, y, texture, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (texture === void 0) {
texture = "__WHITE";
}
GameObject.call(this, scene, "Mesh");
this.faces = [];
this.vertices = [];
this.tintFill = false;
this.debugCallback = null;
this.debugGraphic = null;
this.hideCCW = true;
this.modelPosition = new Vector3();
this.modelScale = new Vector3(1, 1, 1);
this.modelRotation = new Vector3();
this.dirtyCache = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
this.transformMatrix = new Matrix4();
this.viewPosition = new Vector3();
this.viewMatrix = new Matrix4();
this.projectionMatrix = new Matrix4();
this.totalRendered = 0;
this.totalFrame = 0;
this.ignoreDirtyCache = false;
this.fov;
this.displayOriginX = 0;
this.displayOriginY = 0;
var renderer = scene.sys.renderer;
this.setPosition(x, y);
this.setTexture(texture, frame);
this.setSize(renderer.width, renderer.height);
this.initPipeline();
this.initPostPipeline();
this.setPerspective(renderer.width, renderer.height);
if (vertices) {
this.addVertices(vertices, uvs, indicies, containsZ, normals, colors, alphas);
}
},
// Overrides Game Object method
addedToScene: function() {
this.scene.sys.updateList.add(this);
},
// Overrides Game Object method
removedFromScene: function() {
this.scene.sys.updateList.remove(this);
},
/**
* Translates the view position of this Mesh on the x axis by the given amount.
*
* @method Phaser.GameObjects.Mesh#panX
* @since 3.50.0
*
* @param {number} v - The amount to pan by.
*/
panX: function(v) {
this.viewPosition.addScale(Vector3.LEFT, v);
this.dirtyCache[10] = 1;
return this;
},
/**
* Translates the view position of this Mesh on the y axis by the given amount.
*
* @method Phaser.GameObjects.Mesh#panY
* @since 3.50.0
*
* @param {number} v - The amount to pan by.
*/
panY: function(v) {
this.viewPosition.y += Vector3.DOWN.y * v;
this.dirtyCache[10] = 1;
return this;
},
/**
* Translates the view position of this Mesh on the z axis by the given amount.
*
* As the default `panZ` value is 0, vertices with `z=0` (the default) need special
* care or else they will not display as they are "behind" the camera.
*
* Consider using `mesh.panZ(mesh.height / (2 * Math.tan(Math.PI / 16)))`,
* which will interpret vertex geometry 1:1 with pixel geometry (or see `setOrtho`).
*
* @method Phaser.GameObjects.Mesh#panZ
* @since 3.50.0
*
* @param {number} v - The amount to pan by.
*/
panZ: function(amount) {
this.viewPosition.z += amount;
this.dirtyCache[10] = 1;
return this;
},
/**
* Builds a new perspective projection matrix from the given values.
*
* These are also the initial projection matrix and parameters for `Mesh` (see `Mesh.panZ` for more discussion).
*
* See also `setOrtho`.
*
* @method Phaser.GameObjects.Mesh#setPerspective
* @since 3.50.0
*
* @param {number} width - The width of the projection matrix. Typically the same as the Mesh and/or Renderer.
* @param {number} height - The height of the projection matrix. Typically the same as the Mesh and/or Renderer.
* @param {number} [fov=45] - The field of view, in degrees.
* @param {number} [near=0.01] - The near value of the view.
* @param {number} [far=1000] - The far value of the view.
*/
setPerspective: function(width, height, fov, near, far) {
if (fov === void 0) {
fov = 45;
}
if (near === void 0) {
near = 0.01;
}
if (far === void 0) {
far = 1e3;
}
this.fov = fov;
this.projectionMatrix.perspective(DegToRad(fov), width / height, near, far);
this.dirtyCache[10] = 1;
this.dirtyCache[11] = 0;
return this;
},
/**
* Builds a new orthographic projection matrix from the given values.
*
* If using this mode you will often need to set `Mesh.hideCCW` to `false` as well.
*
* By default, calling this method with no parameters will set the scaleX value to
* match the renderer's aspect ratio. If you would like to render vertex positions 1:1
* to pixel positions, consider calling as `mesh.setOrtho(mesh.width, mesh.height)`.
*
* See also `setPerspective`.
*
* @method Phaser.GameObjects.Mesh#setOrtho
* @since 3.50.0
*
* @param {number} [scaleX=1] - The default horizontal scale in relation to the Mesh / Renderer dimensions.
* @param {number} [scaleY=1] - The default vertical scale in relation to the Mesh / Renderer dimensions.
* @param {number} [near=-1000] - The near value of the view.
* @param {number} [far=1000] - The far value of the view.
*/
setOrtho: function(scaleX, scaleY, near, far) {
if (scaleX === void 0) {
scaleX = this.scene.sys.renderer.getAspectRatio();
}
if (scaleY === void 0) {
scaleY = 1;
}
if (near === void 0) {
near = -1e3;
}
if (far === void 0) {
far = 1e3;
}
this.fov = 0;
this.projectionMatrix.ortho(-scaleX, scaleX, -scaleY, scaleY, near, far);
this.dirtyCache[10] = 1;
this.dirtyCache[11] = 1;
return this;
},
/**
* Iterates and destroys all current Faces in this Mesh, then resets the
* `faces` and `vertices` arrays.
*
* @method Phaser.GameObjects.Mesh#clear
* @since 3.50.0
*
* @return {this} This Mesh Game Object.
*/
clear: function() {
this.faces.forEach(function(face) {
face.destroy();
});
this.faces = [];
this.vertices = [];
return this;
},
/**
* This method will add the data from a triangulated Wavefront OBJ model file to this Mesh.
*
* The data should have been loaded via the OBJFile:
*
* ```javascript
* this.load.obj(key, url);
* ```
*
* Then use the same `key` as the first parameter to this method.
*
* Multiple Mesh Game Objects can use the same model data without impacting on each other.
*
* Make sure your 3D package has triangulated the model data prior to exporting it.
*
* You can add multiple models to a single Mesh, although they will act as one when
* moved or rotated. You can scale the model data, should it be too small, or too large, to see.
* You can also offset the vertices of the model via the `x`, `y` and `z` parameters.
*
* @method Phaser.GameObjects.Mesh#addVerticesFromObj
* @since 3.50.0
*
* @param {string} key - The key of the model data in the OBJ Cache to add to this Mesh.
* @param {number} [scale=1] - An amount to scale the model data by. Use this if the model has exported too small, or large, to see.
* @param {number} [x=0] - Translate the model x position by this amount.
* @param {number} [y=0] - Translate the model y position by this amount.
* @param {number} [z=0] - Translate the model z position by this amount.
* @param {number} [rotateX=0] - Rotate the model on the x axis by this amount, in radians.
* @param {number} [rotateY=0] - Rotate the model on the y axis by this amount, in radians.
* @param {number} [rotateZ=0] - Rotate the model on the z axis by this amount, in radians.
* @param {boolean} [zIsUp=true] - Is the z axis up (true), or is y axis up (false)?
*
* @return {this} This Mesh Game Object.
*/
addVerticesFromObj: function(key, scale, x, y, z, rotateX, rotateY, rotateZ, zIsUp) {
var data = this.scene.sys.cache.obj.get(key);
var parsedData;
if (data) {
parsedData = GenerateObjVerts(data, this, scale, x, y, z, rotateX, rotateY, rotateZ, zIsUp);
}
if (!parsedData || parsedData.verts.length === 0) {
console.warn("Mesh.addVerticesFromObj data empty:", key);
}
return this;
},
/**
* Compare the depth of two Faces.
*
* @method Phaser.GameObjects.Mesh#sortByDepth
* @since 3.50.0
*
* @param {Phaser.Geom.Mesh.Face} faceA - The first Face.
* @param {Phaser.Geom.Mesh.Face} faceB - The second Face.
*
* @return {number} The difference between the depths of each Face.
*/
sortByDepth: function(faceA, faceB) {
return faceA.depth - faceB.depth;
},
/**
* Runs a depth sort across all Faces in this Mesh, comparing their averaged depth.
*
* This is called automatically if you use any of the `rotate` methods, but you can
* also invoke it to sort the Faces should you manually position them.
*
* @method Phaser.GameObjects.Mesh#depthSort
* @since 3.50.0
*
* @return {this} This Mesh Game Object.
*/
depthSort: function() {
StableSort(this.faces, this.sortByDepth);
return this;
},
/**
* Adds a new Vertex into the vertices array of this Mesh.
*
* Just adding a vertex isn't enough to render it. You need to also
* make it part of a Face, with 3 Vertex instances per Face.
*
* @method Phaser.GameObjects.Mesh#addVertex
* @since 3.50.0
*
* @param {number} x - The x position of the vertex.
* @param {number} y - The y position of the vertex.
* @param {number} z - The z position of the vertex.
* @param {number} u - The UV u coordinate of the vertex.
* @param {number} v - The UV v coordinate of the vertex.
* @param {number} [color=0xffffff] - The color value of the vertex.
* @param {number} [alpha=1] - The alpha value of the vertex.
*
* @return {this} This Mesh Game Object.
*/
addVertex: function(x, y, z, u, v, color, alpha) {
var vert = new Vertex(x, y, z, u, v, color, alpha);
this.vertices.push(vert);
return vert;
},
/**
* Adds a new Face into the faces array of this Mesh.
*
* A Face consists of references to 3 Vertex instances, which must be provided.
*
* @method Phaser.GameObjects.Mesh#addFace
* @since 3.50.0
*
* @param {Phaser.Geom.Mesh.Vertex} vertex1 - The first vertex of the Face.
* @param {Phaser.Geom.Mesh.Vertex} vertex2 - The second vertex of the Face.
* @param {Phaser.Geom.Mesh.Vertex} vertex3 - The third vertex of the Face.
*
* @return {this} This Mesh Game Object.
*/
addFace: function(vertex1, vertex2, vertex3) {
var face = new Face(vertex1, vertex2, vertex3);
this.faces.push(face);
this.dirtyCache[9] = -1;
return face;
},
/**
* Adds new vertices to this Mesh by parsing the given data.
*
* This method will take vertex data in one of two formats, based on the `containsZ` parameter.
*
* If your vertex data are `x`, `y` pairs, then `containsZ` should be `false` (this is the default, and will result in `z=0` for each vertex).
*
* If your vertex data is groups of `x`, `y` and `z` values, then the `containsZ` parameter must be true.
*
* The `uvs` parameter is a numeric array consisting of `u` and `v` pairs.
*
* The `normals` parameter is a numeric array consisting of `x`, `y` vertex normal values and, if `containsZ` is true, `z` values as well.
*
* The `indicies` parameter is an optional array that, if given, is an indexed list of vertices to be added.
*
* The `colors` parameter is an optional array, or single value, that if given sets the color of each vertex created.
*
* The `alphas` parameter is an optional array, or single value, that if given sets the alpha of each vertex created.
*
* When providing indexed data it is assumed that _all_ of the arrays are indexed, not just the vertices.
*
* The following example will create a 256 x 256 sized quad using an index array:
*
* ```javascript
* let mesh = new Mesh(this); // Assuming `this` is a scene!
* const vertices = [
* -128, 128,
* 128, 128,
* -128, -128,
* 128, -128
* ];
*
* const uvs = [
* 0, 1,
* 1, 1,
* 0, 0,
* 1, 0
* ];
*
* const indices = [ 0, 2, 1, 2, 3, 1 ];
*
* mesh.addVertices(vertices, uvs, indicies);
* // Note: Otherwise the added points will be "behind" the camera! This value will project vertex `x` & `y` values 1:1 to pixel values.
* mesh.hideCCW = false;
* mesh.setOrtho(mesh.width, mesh.height);
* ```
*
* If the data is not indexed, it's assumed that the arrays all contain sequential data.
*
* @method Phaser.GameObjects.Mesh#addVertices
* @since 3.50.0
*
* @param {number[]} vertices - The vertices array. Either `xy` pairs, or `xyz` if the `containsZ` parameter is `true`.
* @param {number[]} uvs - The UVs pairs array.
* @param {number[]} [indicies] - Optional vertex indicies array. If you don't have one, pass `null` or an empty array.
* @param {boolean} [containsZ=false] - Does the vertices data include a `z` component? If not, it will be assumed `z=0`, see methods `panZ` or `setOrtho`.
* @param {number[]} [normals] - Optional vertex normals array. If you don't have one, pass `null` or an empty array.
* @param {number|number[]} [colors=0xffffff] - An array of colors, one per vertex, or a single color value applied to all vertices.
* @param {number|number[]} [alphas=1] - An array of alpha values, one per vertex, or a single alpha value applied to all vertices.
*
* @return {this} This Mesh Game Object.
*/
addVertices: function(vertices, uvs, indicies, containsZ, normals, colors, alphas) {
var result = GenerateVerts(vertices, uvs, indicies, containsZ, normals, colors, alphas);
if (result) {
this.faces = this.faces.concat(result.faces);
this.vertices = this.vertices.concat(result.vertices);
} else {
console.warn("Mesh.addVertices data empty or invalid");
}
this.dirtyCache[9] = -1;
return this;
},
/**
* Returns the total number of Faces in this Mesh Game Object.
*
* @method Phaser.GameObjects.Mesh#getFaceCount
* @since 3.50.0
*
* @return {number} The number of Faces in this Mesh Game Object.
*/
getFaceCount: function() {
return this.faces.length;
},
/**
* Returns the total number of Vertices in this Mesh Game Object.
*
* @method Phaser.GameObjects.Mesh#getVertexCount
* @since 3.50.0
*
* @return {number} The number of Vertices in this Mesh Game Object.
*/
getVertexCount: function() {
return this.vertices.length;
},
/**
* Returns the Face at the given index in this Mesh Game Object.
*
* @method Phaser.GameObjects.Mesh#getFace
* @since 3.50.0
*
* @param {number} index - The index of the Face to get.
*
* @return {Phaser.Geom.Mesh.Face} The Face at the given index, or `undefined` if index out of range.
*/
getFace: function(index) {
return this.faces[index];
},
/**
* Tests to see if _any_ face in this Mesh intersects with the given coordinates.
*
* The given position is translated through the matrix of this Mesh and the given Camera,
* before being compared against the vertices.
*
* @method Phaser.GameObjects.Mesh#hasFaceAt
* @since 3.60.0
*
* @param {number} x - The x position to check against.
* @param {number} y - The y position to check against.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The camera to pass the coordinates through. If not give, the default Scene Camera is used.
*
* @return {boolean} Returns `true` if _any_ face of this Mesh intersects with the given coordinate, otherwise `false`.
*/
hasFaceAt: function(x, y, camera) {
if (camera === void 0) {
camera = this.scene.sys.cameras.main;
}
var calcMatrix = GetCalcMatrix(this, camera).calc;
var faces = this.faces;
for (var i = 0; i < faces.length; i++) {
var face = faces[i];
if (face.contains(x, y, calcMatrix)) {
return true;
}
}
return false;
},
/**
* Return an array of Face objects from this Mesh that intersect with the given coordinates.
*
* The given position is translated through the matrix of this Mesh and the given Camera,
* before being compared against the vertices.
*
* If more than one Face intersects, they will all be returned in the array, but the array will
* be depth sorted first, so the first element will always be that closest to the camera.
*
* @method Phaser.GameObjects.Mesh#getFaceAt
* @since 3.50.0
*
* @param {number} x - The x position to check against.
* @param {number} y - The y position to check against.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The camera to pass the coordinates through. If not give, the default Scene Camera is used.
*
* @return {Phaser.Geom.Mesh.Face[]} An array of Face objects that intersect with the given point, ordered by depth.
*/
getFaceAt: function(x, y, camera) {
if (camera === void 0) {
camera = this.scene.sys.cameras.main;
}
var calcMatrix = GetCalcMatrix(this, camera).calc;
var faces = this.faces;
var results = [];
for (var i = 0; i < faces.length; i++) {
var face = faces[i];
if (face.contains(x, y, calcMatrix)) {
results.push(face);
}
}
return StableSort(results, this.sortByDepth);
},
/**
* This method enables rendering of the Mesh vertices to the given Graphics instance.
*
* If you enable this feature, you **must** call `Graphics.clear()` in your Scene `update`,
* otherwise the Graphics instance you provide to debug will fill-up with draw calls,
* eventually crashing the browser. This is not done automatically to allow you to debug
* draw multiple Mesh objects to a single Graphics instance.
*
* The Mesh class has a built-in debug rendering callback `Mesh.renderDebug`, however
* you can also provide your own callback to be used instead. Do this by setting the `callback` parameter.
*
* The callback is invoked _once per render_ and sent the following parameters:
*
* `callback(src, faces)`
*
* `src` is the Mesh instance being debugged.
* `faces` is an array of the Faces that were rendered.
*
* You can get the final drawn vertex position from a Face object like this:
*
* ```javascript
* let face = faces[i];
*
* let x0 = face.vertex1.tx;
* let y0 = face.vertex1.ty;
* let x1 = face.vertex2.tx;
* let y1 = face.vertex2.ty;
* let x2 = face.vertex3.tx;
* let y2 = face.vertex3.ty;
*
* graphic.strokeTriangle(x0, y0, x1, y1, x2, y2);
* ```
*
* If using your own callback you do not have to provide a Graphics instance to this method.
*
* To disable debug rendering, to either your own callback or the built-in one, call this method
* with no arguments.
*
* @method Phaser.GameObjects.Mesh#setDebug
* @since 3.50.0
*
* @param {Phaser.GameObjects.Graphics} [graphic] - The Graphic instance to render to if using the built-in callback.
* @param {function} [callback] - The callback to invoke during debug render. Leave as undefined to use the built-in callback.
*
* @return {this} This Game Object instance.
*/
setDebug: function(graphic, callback) {
this.debugGraphic = graphic;
if (!graphic && !callback) {
this.debugCallback = null;
} else if (!callback) {
this.debugCallback = this.renderDebug;
} else {
this.debugCallback = callback;
}
return this;
},
/**
* Checks if the transformation data in this mesh is dirty.
*
* This is used internally by the `preUpdate` step to determine if the vertices should
* be recalculated or not.
*
* @method Phaser.GameObjects.Mesh#isDirty
* @since 3.50.0
*
* @return {boolean} Returns `true` if the data of this mesh is dirty, otherwise `false`.
*/
isDirty: function() {
var position = this.modelPosition;
var rotation = this.modelRotation;
var scale = this.modelScale;
var dirtyCache = this.dirtyCache;
var px = position.x;
var py = position.y;
var pz = position.z;
var rx = rotation.x;
var ry = rotation.y;
var rz = rotation.z;
var sx = scale.x;
var sy = scale.y;
var sz = scale.z;
var faces = this.getFaceCount();
var pxCached = dirtyCache[0];
var pyCached = dirtyCache[1];
var pzCached = dirtyCache[2];
var rxCached = dirtyCache[3];
var ryCached = dirtyCache[4];
var rzCached = dirtyCache[5];
var sxCached = dirtyCache[6];
var syCached = dirtyCache[7];
var szCached = dirtyCache[8];
var fCached = dirtyCache[9];
dirtyCache[0] = px;
dirtyCache[1] = py;
dirtyCache[2] = pz;
dirtyCache[3] = rx;
dirtyCache[4] = ry;
dirtyCache[5] = rz;
dirtyCache[6] = sx;
dirtyCache[7] = sy;
dirtyCache[8] = sz;
dirtyCache[9] = faces;
return pxCached !== px || pyCached !== py || pzCached !== pz || rxCached !== rx || ryCached !== ry || rzCached !== rz || sxCached !== sx || syCached !== sy || szCached !== sz || fCached !== faces;
},
/**
* The Mesh update loop. The following takes place in this method:
*
* First, the `totalRendered` and `totalFrame` properties are set.
*
* If the view matrix of this Mesh isn't dirty, and the model position, rotate or scale properties are
* all clean, then the method returns at this point.
*
* Otherwise, if the viewPosition is dirty (i.e. from calling a method like `panZ`), then it will
* refresh the viewMatrix.
*
* After this, a new transformMatrix is built and it then iterates through all Faces in this
* Mesh, calling `transformCoordinatesLocal` on all of them. Internally, this updates every
* vertex, calculating its new transformed position, based on the new transform matrix.
*
* Finally, the faces are depth sorted.
*
* @method Phaser.GameObjects.Mesh#preUpdate
* @protected
* @since 3.50.0
*
* @param {number} time - The current timestamp.
* @param {number} delta - The delta time, in ms, elapsed since the last frame.
*/
preUpdate: function() {
this.totalRendered = this.totalFrame;
this.totalFrame = 0;
var dirty = this.dirtyCache;
if (!this.ignoreDirtyCache && !dirty[10] && !this.isDirty()) {
return;
}
var width = this.width;
var height = this.height;
var viewMatrix = this.viewMatrix;
var viewPosition = this.viewPosition;
if (dirty[10]) {
viewMatrix.identity();
viewMatrix.translate(viewPosition);
viewMatrix.invert();
dirty[10] = 0;
}
var transformMatrix = this.transformMatrix;
transformMatrix.setWorldMatrix(
this.modelRotation,
this.modelPosition,
this.modelScale,
this.viewMatrix,
this.projectionMatrix
);
var z = viewPosition.z;
var faces = this.faces;
for (var i = 0; i < faces.length; i++) {
faces[i].transformCoordinatesLocal(transformMatrix, width, height, z);
}
this.depthSort();
},
/**
* The built-in Mesh debug rendering method.
*
* See `Mesh.setDebug` for more details.
*
* @method Phaser.GameObjects.Mesh#renderDebug
* @since 3.50.0
*
* @param {Phaser.GameObjects.Mesh} src - The Mesh object being rendered.
* @param {Phaser.Geom.Mesh.Face[]} faces - An array of Faces.
*/
renderDebug: function(src, faces) {
var graphic = src.debugGraphic;
for (var i = 0; i < faces.length; i++) {
var face = faces[i];
var x0 = face.vertex1.tx;
var y0 = face.vertex1.ty;
var x1 = face.vertex2.tx;
var y1 = face.vertex2.ty;
var x2 = face.vertex3.tx;
var y2 = face.vertex3.ty;
graphic.strokeTriangle(x0, y0, x1, y1, x2, y2);
}
},
/**
* Handles the pre-destroy step for the Mesh, which removes the vertices and debug callbacks.
*
* @method Phaser.GameObjects.Mesh#preDestroy
* @private
* @since 3.50.0
*/
preDestroy: function() {
this.clear();
this.debugCallback = null;
this.debugGraphic = null;
},
/**
* Clears all tint values associated with this Game Object.
*
* Immediately sets the color values back to 0xffffff on all vertices,
* which results in no visible change to the texture.
*
* @method Phaser.GameObjects.Mesh#clearTint
* @webglOnly
* @since 3.60.0
*
* @return {this} This Game Object instance.
*/
clearTint: function() {
return this.setTint();
},
/**
* Pass this Mesh Game Object to the Input Manager to enable it for Input.
*
* Unlike other Game Objects, the Mesh Game Object uses its own special hit area callback, which you cannot override.
*
* @example
* mesh.setInteractive();
*
* @example
* mesh.setInteractive({ useHandCursor: true });
*
* @method Phaser.GameObjects.Mesh#setInteractive
* @since 3.60.0
*
* @param {(Phaser.Types.Input.InputConfiguration)} [config] - An input configuration object but it will ignore hitArea, hitAreaCallback and pixelPerfect with associated alphaTolerance properties.
*
* @return {this} This GameObject.
*/
setInteractive: function(config) {
if (config === void 0) {
config = {};
}
var hitAreaCallback = (function(area, x, y) {
var faces = this.faces;
for (var i = 0; i < faces.length; i++) {
var face = faces[i];
if (face.contains(x, y)) {
return true;
}
}
return false;
}).bind(this);
this.scene.sys.input.enable(this, config, hitAreaCallback);
return this;
},
/**
* Sets an additive tint on all vertices of this Mesh Game Object.
*
* The tint works by taking the pixel color values from the Game Objects texture, and then
* multiplying it by the color value of the tint.
*
* To modify the tint color once set, either call this method again with new values or use the
* `tint` property to set all colors at once.
*
* To remove a tint call `clearTint`.
*
* @method Phaser.GameObjects.Mesh#setTint
* @webglOnly
* @since 3.60.0
*
* @param {number} [tint=0xffffff] - The tint being applied to all vertices of this Mesh Game Object.
*
* @return {this} This Game Object instance.
*/
setTint: function(tint) {
if (tint === void 0) {
tint = 16777215;
}
var vertices = this.vertices;
for (var i = 0; i < vertices.length; i++) {
vertices[i].color = tint;
}
return this;
},
/**
* Scrolls the UV texture coordinates of all faces in this Mesh by
* adding the given x/y amounts to them.
*
* If you only wish to scroll one coordinate, pass a value of zero
* to the other.
*
* Use small values for scrolling. UVs are set from the range 0
* to 1, so you should increment (or decrement) them by suitably
* small values, such as 0.01.
*
* Due to a limitation in WebGL1 you can only UV scroll textures
* that are a power-of-two in size. Scrolling NPOT textures will
* work but will result in clamping the pixels to the edges.
*
* Note that if this Mesh is using a _frame_ from a texture atlas
* then you will be unable to UV scroll its texture.
*
* @method Phaser.GameObjects.Mesh#uvScroll
* @webglOnly
* @since 3.60.0
*
* @param {number} x - The amount to horizontally shift the UV coordinates by.
* @param {number} y - The amount to vertically shift the UV coordinates by.
*
* @return {this} This Game Object instance.
*/
uvScroll: function(x, y) {
var faces = this.faces;
for (var i = 0; i < faces.length; i++) {
faces[i].scrollUV(x, y);
}
return this;
},
/**
* Scales the UV texture coordinates of all faces in this Mesh by
* the exact given amounts.
*
* If you only wish to scale one coordinate, pass a value of one
* to the other.
*
* Due to a limitation in WebGL1 you can only UV scale textures
* that are a power-of-two in size. Scaling NPOT textures will
* work but will result in clamping the pixels to the edges if
* you scale beyond a value of 1. Scaling below 1 will work
* regardless of texture size.
*
* Note that if this Mesh is using a _frame_ from a texture atlas
* then you will be unable to UV scale its texture.
*
* @method Phaser.GameObjects.Mesh#uvScale
* @webglOnly
* @since 3.60.0
*
* @param {number} x - The amount to horizontally scale the UV coordinates by.
* @param {number} y - The amount to vertically scale the UV coordinates by.
*
* @return {this} This Game Object instance.
*/
uvScale: function(x, y) {
var faces = this.faces;
for (var i = 0; i < faces.length; i++) {
faces[i].scaleUV(x, y);
}
return this;
},
/**
* The tint value being applied to the whole of the Game Object.
* This property is a setter-only.
*
* @method Phaser.GameObjects.Mesh#tint
* @type {number}
* @webglOnly
* @since 3.60.0
*/
tint: {
set: function(value) {
this.setTint(value);
}
},
/**
* The x rotation of the Model in 3D space, as specified in degrees.
*
* If you need the value in radians use the `modelRotation.x` property directly.
*
* @method Phaser.GameObjects.Mesh#rotateX
* @type {number}
* @since 3.60.0
*/
rotateX: {
get: function() {
return RadToDeg(this.modelRotation.x);
},
set: function(value) {
this.modelRotation.x = DegToRad(value);
}
},
/**
* The y rotation of the Model in 3D space, as specified in degrees.
*
* If you need the value in radians use the `modelRotation.y` property directly.
*
* @method Phaser.GameObjects.Mesh#rotateY
* @type {number}
* @since 3.60.0
*/
rotateY: {
get: function() {
return RadToDeg(this.modelRotation.y);
},
set: function(value) {
this.modelRotation.y = DegToRad(value);
}
},
/**
* The z rotation of the Model in 3D space, as specified in degrees.
*
* If you need the value in radians use the `modelRotation.z` property directly.
*
* @method Phaser.GameObjects.Mesh#rotateZ
* @type {number}
* @since 3.60.0
*/
rotateZ: {
get: function() {
return RadToDeg(this.modelRotation.z);
},
set: function(value) {
this.modelRotation.z = DegToRad(value);
}
}
});
module2.exports = Mesh;
}
),
/***/
36488: (
/***/
(module2) => {
var MeshCanvasRenderer = function() {
};
module2.exports = MeshCanvasRenderer;
}
),
/***/
20527: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var BuildGameObject = __webpack_require__2(25305);
var GameObjectCreator = __webpack_require__2(44603);
var GetAdvancedValue = __webpack_require__2(23568);
var GetValue = __webpack_require__2(35154);
var Mesh = __webpack_require__2(4703);
GameObjectCreator.register("mesh", function(config, addToScene) {
if (config === void 0) {
config = {};
}
var key = GetAdvancedValue(config, "key", null);
var frame = GetAdvancedValue(config, "frame", null);
var vertices = GetValue(config, "vertices", []);
var uvs = GetValue(config, "uvs", []);
var indicies = GetValue(config, "indicies", []);
var containsZ = GetValue(config, "containsZ", false);
var normals = GetValue(config, "normals", []);
var colors = GetValue(config, "colors", 16777215);
var alphas = GetValue(config, "alphas", 1);
var mesh = new Mesh(this.scene, 0, 0, key, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas);
if (addToScene !== void 0) {
config.add = addToScene;
}
BuildGameObject(this.scene, mesh, config);
return mesh;
});
}
),
/***/
9225: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var Mesh = __webpack_require__2(4703);
var GameObjectFactory = __webpack_require__2(39429);
if (true) {
GameObjectFactory.register("mesh", function(x, y, texture, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas) {
return this.displayList.add(new Mesh(this.scene, x, y, texture, frame, vertices, uvs, indicies, containsZ, normals, colors, alphas));
});
}
}
),
/***/
29807: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(48833);
}
if (true) {
renderCanvas = __webpack_require__2(36488);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
48833: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetCalcMatrix = __webpack_require__2(91296);
var MeshWebGLRenderer = function(renderer, src, camera, parentMatrix) {
var faces = src.faces;
var totalFaces = faces.length;
if (totalFaces === 0) {
return;
}
camera.addToRenderList(src);
var pipeline = renderer.pipelines.set(src.pipeline, src);
var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc;
renderer.pipelines.preBatch(src);
var textureUnit = pipeline.setGameObject(src);
var F32 = pipeline.vertexViewF32;
var U32 = pipeline.vertexViewU32;
var vertexOffset = pipeline.vertexCount * pipeline.currentShader.vertexComponentCount - 1;
var tintEffect = src.tintFill;
var debugFaces = [];
var debugCallback = src.debugCallback;
var a = calcMatrix.a;
var b = calcMatrix.b;
var c = calcMatrix.c;
var d = calcMatrix.d;
var e = calcMatrix.e;
var f = calcMatrix.f;
var z = src.viewPosition.z;
var hideCCW = src.hideCCW;
var roundPixels = camera.roundPixels;
var alpha = camera.alpha * src.alpha;
var totalFacesRendered = 0;
for (var i = 0; i < totalFaces; i++) {
var face = faces[i];
if (!face.isInView(camera, hideCCW, z, alpha, a, b, c, d, e, f, roundPixels)) {
continue;
}
if (pipeline.shouldFlush(3)) {
pipeline.flush();
textureUnit = pipeline.setGameObject(src);
vertexOffset = pipeline.vertexCount * pipeline.currentShader.vertexComponentCount - 1;
}
vertexOffset = face.load(F32, U32, vertexOffset, textureUnit, tintEffect);
totalFacesRendered++;
pipeline.vertexCount += 3;
pipeline.currentBatch.count = pipeline.vertexCount - pipeline.currentBatch.start;
if (debugCallback) {
debugFaces.push(face);
}
}
src.totalFrame += totalFacesRendered;
if (debugCallback) {
debugCallback.call(src, src, debugFaces);
}
renderer.pipelines.postBatch(src);
};
module2.exports = MeshWebGLRenderer;
}
),
/***/
28103: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31401);
var GameObject = __webpack_require__2(95643);
var NineSliceRender = __webpack_require__2(78023);
var Vertex = __webpack_require__2(39318);
var NineSlice = new Class({
Extends: GameObject,
Mixins: [
Components.AlphaSingle,
Components.BlendMode,
Components.Depth,
Components.GetBounds,
Components.Mask,
Components.Origin,
Components.Pipeline,
Components.PostPipeline,
Components.ScrollFactor,
Components.Texture,
Components.Transform,
Components.Visible,
NineSliceRender
],
initialize: function NineSlice2(scene, x, y, texture, frame, width, height, leftWidth, rightWidth, topHeight, bottomHeight) {
GameObject.call(this, scene, "NineSlice");
this._width;
this._height;
this._originX = 0.5;
this._originY = 0.5;
this._sizeComponent = true;
this.vertices = [];
this.leftWidth;
this.rightWidth;
this.topHeight;
this.bottomHeight;
this.tint = 16777215;
this.tintFill = false;
var textureFrame = scene.textures.getFrame(texture, frame);
this.is3Slice = !topHeight && !bottomHeight;
if (textureFrame && textureFrame.scale9) {
this.is3Slice = textureFrame.is3Slice;
}
var size = this.is3Slice ? 18 : 54;
for (var i = 0; i < size; i++) {
this.vertices.push(new Vertex());
}
this.setPosition(x, y);
this.setTexture(texture, frame);
this.setSlices(width, height, leftWidth, rightWidth, topHeight, bottomHeight, false);
this.updateDisplayOrigin();
this.initPipeline();
this.initPostPipeline();
},
/**
* Resets the width, height and slices for this NineSlice Game Object.
*
* This allows you to modify the texture being used by this object and then reset the slice configuration,
* to avoid having to destroy this Game Object in order to use it for a different game element.
*
* Please note that you cannot change a 9-slice to a 3-slice or vice versa.
*
* @method Phaser.GameObjects.NineSlice#setSlices
* @since 3.60.0
*
* @param {number} [width=256] - The width of the Nine Slice Game Object. You can adjust the width post-creation.
* @param {number} [height=256] - The height of the Nine Slice Game Object. If this is a 3 slice object the height will be fixed to the height of the texture and cannot be changed.
* @param {number} [leftWidth=10] - The size of the left vertical column (A).
* @param {number} [rightWidth=10] - The size of the right vertical column (B).
* @param {number} [topHeight=0] - The size of the top horizontal row (C). Set to zero or undefined to create a 3 slice object.
* @param {number} [bottomHeight=0] - The size of the bottom horizontal row (D). Set to zero or undefined to create a 3 slice object.
* @param {boolean} [skipScale9=false] -If this Nine Slice was created from Texture Packer scale9 atlas data, set this property to use the given column sizes instead of those specified in the JSON.
*
* @return {this} This Game Object instance.
*/
setSlices: function(width, height, leftWidth, rightWidth, topHeight, bottomHeight, skipScale9) {
if (leftWidth === void 0) {
leftWidth = 10;
}
if (rightWidth === void 0) {
rightWidth = 10;
}
if (topHeight === void 0) {
topHeight = 0;
}
if (bottomHeight === void 0) {
bottomHeight = 0;
}
if (skipScale9 === void 0) {
skipScale9 = false;
}
var frame = this.frame;
var sliceChange = false;
if (this.is3Slice && skipScale9 && topHeight !== 0 && bottomHeight !== 0) {
sliceChange = true;
}
if (sliceChange) {
console.warn("Cannot change 9 slice to 3 slice");
} else {
if (frame && frame.scale9 && !skipScale9) {
var data = frame.data.scale9Borders;
var x = data.x;
var y = data.y;
leftWidth = x;
rightWidth = frame.width - data.w - x;
topHeight = y;
bottomHeight = frame.height - data.h - y;
if (width === void 0) {
width = frame.width;
}
if (height === void 0) {
height = frame.height;
}
} else {
if (width === void 0) {
width = 256;
}
if (height === void 0) {
height = 256;
}
}
this._width = width;
this._height = height;
this.leftWidth = leftWidth;
this.rightWidth = rightWidth;
this.topHeight = topHeight;
this.bottomHeight = bottomHeight;
if (this.is3Slice) {
height = frame.height;
this._height = height;
this.topHeight = height;
this.bottomHeight = 0;
}
this.updateVertices();
this.updateUVs();
}
return this;
},
/**
* Updates all of the vertice UV coordinates. This is called automatically
* when the NineSlice Game Object is created, or if the texture frame changes.
*
* Unlike with the `updateVertice` method, you do not need to call this
* method if the Nine Slice changes size. Only if it changes texture frame.
*
* @method Phaser.GameObjects.NineSlice#updateUVs
* @since 3.60.0
*/
updateUVs: function() {
var left = this.leftWidth;
var right = this.rightWidth;
var top = this.topHeight;
var bot = this.bottomHeight;
var width = this.frame.width;
var height = this.frame.height;
this.updateQuadUVs(0, 0, 0, left / width, top / height);
this.updateQuadUVs(6, left / width, 0, 1 - right / width, top / height);
this.updateQuadUVs(12, 1 - right / width, 0, 1, top / height);
if (!this.is3Slice) {
this.updateQuadUVs(18, 0, top / height, left / width, 1 - bot / height);
this.updateQuadUVs(24, left / width, top / height, 1 - right / width, 1 - bot / height);
this.updateQuadUVs(30, 1 - right / width, top / height, 1, 1 - bot / height);
this.updateQuadUVs(36, 0, 1 - bot / height, left / width, 1);
this.updateQuadUVs(42, left / width, 1 - bot / height, 1 - right / width, 1);
this.updateQuadUVs(48, 1 - right / width, 1 - bot / height, 1, 1);
}
},
/**
* Recalculates all of the vertices in this Nine Slice Game Object
* based on the `leftWidth`, `rightWidth`, `topHeight` and `bottomHeight`
* properties, combined with the Game Object size.
*
* This method is called automatically when this object is created
* or if it's origin is changed.
*
* You should not typically need to call this method directly, but it
* is left public should you find a need to modify one of those properties
* after creation.
*
* @method Phaser.GameObjects.NineSlice#updateVertices
* @since 3.60.0
*/
updateVertices: function() {
var left = this.leftWidth;
var right = this.rightWidth;
var top = this.topHeight;
var bot = this.bottomHeight;
var width = this.width;
var height = this.height;
this.updateQuad(0, -0.5, 0.5, -0.5 + left / width, 0.5 - top / height);
this.updateQuad(6, -0.5 + left / width, 0.5, 0.5 - right / width, 0.5 - top / height);
this.updateQuad(12, 0.5 - right / width, 0.5, 0.5, 0.5 - top / height);
if (!this.is3Slice) {
this.updateQuad(18, -0.5, 0.5 - top / height, -0.5 + left / width, -0.5 + bot / height);
this.updateQuad(24, -0.5 + left / width, 0.5 - top / height, 0.5 - right / width, -0.5 + bot / height);
this.updateQuad(30, 0.5 - right / width, 0.5 - top / height, 0.5, -0.5 + bot / height);
this.updateQuad(36, -0.5, -0.5 + bot / height, -0.5 + left / width, -0.5);
this.updateQuad(42, -0.5 + left / width, -0.5 + bot / height, 0.5 - right / width, -0.5);
this.updateQuad(48, 0.5 - right / width, -0.5 + bot / height, 0.5, -0.5);
}
},
/**
* Internally updates the position coordinates across all vertices of the
* given quad offset.
*
* You should not typically need to call this method directly, but it
* is left public should an extended class require it.
*
* @method Phaser.GameObjects.NineSlice#updateQuad
* @since 3.60.0
*
* @param {number} offset - The offset in the vertices array of the quad to update.
* @param {number} x1 - The top-left quad coordinate.
* @param {number} y1 - The top-left quad coordinate.
* @param {number} x2 - The bottom-right quad coordinate.
* @param {number} y2 - The bottom-right quad coordinate.
*/
updateQuad: function(offset, x1, y1, x2, y2) {
var width = this.width;
var height = this.height;
var originX = this.originX;
var originY = this.originY;
var verts = this.vertices;
verts[offset + 0].resize(x1, y1, width, height, originX, originY);
verts[offset + 1].resize(x1, y2, width, height, originX, originY);
verts[offset + 2].resize(x2, y1, width, height, originX, originY);
verts[offset + 3].resize(x1, y2, width, height, originX, originY);
verts[offset + 4].resize(x2, y2, width, height, originX, originY);
verts[offset + 5].resize(x2, y1, width, height, originX, originY);
},
/**
* Internally updates the UV coordinates across all vertices of the
* given quad offset, based on the frame size.
*
* You should not typically need to call this method directly, but it
* is left public should an extended class require it.
*
* @method Phaser.GameObjects.NineSlice#updateQuadUVs
* @since 3.60.0
*
* @param {number} offset - The offset in the vertices array of the quad to update.
* @param {number} u1 - The top-left UV coordinate.
* @param {number} v1 - The top-left UV coordinate.
* @param {number} u2 - The bottom-right UV coordinate.
* @param {number} v2 - The bottom-right UV coordinate.
*/
updateQuadUVs: function(offset, u1, v1, u2, v2) {
var verts = this.vertices;
var frame = this.frame;
var fu1 = frame.u0;
var fv1 = frame.v0;
var fu2 = frame.u1;
var fv2 = frame.v1;
if (fu1 !== 0 || fu2 !== 1) {
var udiff = fu2 - fu1;
u1 = fu1 + u1 * udiff;
u2 = fu1 + u2 * udiff;
}
if (fv1 !== 0 || fv2 !== 1) {
var vdiff = fv2 - fv1;
v1 = fv1 + v1 * vdiff;
v2 = fv1 + v2 * vdiff;
}
verts[offset + 0].setUVs(u1, v1);
verts[offset + 1].setUVs(u1, v2);
verts[offset + 2].setUVs(u2, v1);
verts[offset + 3].setUVs(u1, v2);
verts[offset + 4].setUVs(u2, v2);
verts[offset + 5].setUVs(u2, v1);
},
/**
* Clears all tint values associated with this Game Object.
*
* Immediately sets the color values back to 0xffffff and the tint type to 'additive',
* which results in no visible change to the texture.
*
* @method Phaser.GameObjects.NineSlice#clearTint
* @webglOnly
* @since 3.60.0
*
* @return {this} This Game Object instance.
*/
clearTint: function() {
this.setTint(16777215);
return this;
},
/**
* Sets an additive tint on this Game Object.
*
* The tint works by taking the pixel color values from the Game Objects texture, and then
* multiplying it by the color value of the tint.
*
* To modify the tint color once set, either call this method again with new values or use the
* `tint` property.
*
* To remove a tint call `clearTint`, or call this method with no parameters.
*
* To swap this from being an additive tint to a fill based tint set the property `tintFill` to `true`.
*
* @method Phaser.GameObjects.NineSlice#setTint
* @webglOnly
* @since 3.60.0
*
* @param {number} [color=0xffffff] - The tint being applied to the entire Game Object.
*
* @return {this} This Game Object instance.
*/
setTint: function(color) {
if (color === void 0) {
color = 16777215;
}
this.tint = color;
this.tintFill = false;
return this;
},
/**
* Sets a fill-based tint on this Game Object.
*
* Unlike an additive tint, a fill-tint literally replaces the pixel colors from the texture
* with those in the tint. You can use this for effects such as making a player flash 'white'
* if hit by something. The whole Game Object will be rendered in the given color.
*
* To modify the tint color once set, either call this method again with new values or use the
* `tint` property.
*
* To remove a tint call `clearTint`, or call this method with no parameters.
*
* To swap this from being a fill-tint to an additive tint set the property `tintFill` to `false`.
*
* @method Phaser.GameObjects.NineSlice#setTintFill
* @webglOnly
* @since 3.60.0
*
* @param {number} [color=0xffffff] - The tint being applied to the entire Game Object.
*
* @return {this} This Game Object instance.
*/
setTintFill: function(color) {
this.setTint(color);
this.tintFill = true;
return this;
},
/**
* Does this Game Object have a tint applied?
*
* It checks to see if the tint property is set to a value other than 0xffffff.
* This indicates that a Game Object is tinted.
*
* @name Phaser.GameObjects.NineSlice#isTinted
* @type {boolean}
* @webglOnly
* @readonly
* @since 3.60.0
*/
isTinted: {
get: function() {
return this.tint !== 16777215;
}
},
/**
* The displayed width of this Game Object.
*
* Setting this value will adjust the way in which this Nine Slice
* object scales horizontally, if configured to do so.
*
* The _minimum_ width this Game Object can be is the total of
* `leftWidth` + `rightWidth`. If you need to display this object
* at a smaller size, you can also scale it.
*
* @name Phaser.GameObjects.NineSlice#width
* @type {number}
* @since 3.60.0
*/
width: {
get: function() {
return this._width;
},
set: function(value) {
this._width = Math.max(value, this.leftWidth + this.rightWidth);
this.updateVertices();
}
},
/**
* The displayed height of this Game Object.
*
* Setting this value will adjust the way in which this Nine Slice
* object scales vertically, if configured to do so.
*
* The _minimum_ height this Game Object can be is the total of
* `topHeight` + `bottomHeight`. If you need to display this object
* at a smaller size, you can also scale it.
*
* If this is a 3-slice object, you can only stretch it horizontally
* and changing the height will be ignored.
*
* @name Phaser.GameObjects.NineSlice#height
* @type {number}
* @since 3.60.0
*/
height: {
get: function() {
return this._height;
},
set: function(value) {
if (!this.is3Slice) {
this._height = Math.max(value, this.topHeight + this.bottomHeight);
this.updateVertices();
}
}
},
/**
* The displayed width of this Game Object.
*
* This value takes into account the scale factor.
*
* Setting this value will adjust the Game Object's scale property.
*
* @name Phaser.GameObjects.NineSlice#displayWidth
* @type {number}
* @since 3.60.0
*/
displayWidth: {
get: function() {
return this.scaleX * this.width;
},
set: function(value) {
this.scaleX = value / this.width;
}
},
/**
* The displayed height of this Game Object.
*
* This value takes into account the scale factor.
*
* Setting this value will adjust the Game Object's scale property.
*
* @name Phaser.GameObjects.NineSlice#displayHeight
* @type {number}
* @since 3.60.0
*/
displayHeight: {
get: function() {
return this.scaleY * this.height;
},
set: function(value) {
this.scaleY = value / this.height;
}
},
/**
* Sets the size of this Game Object.
*
* For a Nine Slice Game Object this means it will be stretched (or shrunk) horizontally
* and vertically depending on the dimensions given to this method, in accordance with
* how it has been configured for the various corner sizes.
*
* If this is a 3-slice object, you can only stretch it horizontally
* and changing the height will be ignored.
*
* If you have enabled this Game Object for input, changing the size will also change the
* size of the hit area.
*
* @method Phaser.GameObjects.NineSlice#setSize
* @since 3.60.0
*
* @param {number} width - The width of this Game Object.
* @param {number} height - The height of this Game Object.
*
* @return {this} This Game Object instance.
*/
setSize: function(width, height) {
this.width = width;
this.height = height;
this.updateDisplayOrigin();
var input = this.input;
if (input && !input.customHitArea) {
input.hitArea.width = this.width;
input.hitArea.height = this.height;
}
return this;
},
/**
* Sets the display size of this Game Object.
*
* Calling this will adjust the scale.
*
* @method Phaser.GameObjects.NineSlice#setDisplaySize
* @since 3.60.0
*
* @param {number} width - The width of this Game Object.
* @param {number} height - The height of this Game Object.
*
* @return {this} This Game Object instance.
*/
setDisplaySize: function(width, height) {
this.displayWidth = width;
this.displayHeight = height;
return this;
},
/**
* The horizontal origin of this Game Object.
* The origin maps the relationship between the size and position of the Game Object.
* The default value is 0.5, meaning all Game Objects are positioned based on their center.
* Setting the value to 0 means the position now relates to the left of the Game Object.
*
* @name Phaser.GameObjects.NineSlice#originX
* @type {number}
* @since 3.60.0
*/
originX: {
get: function() {
return this._originX;
},
set: function(value) {
this._originX = value;
this.updateVertices();
}
},
/**
* The vertical origin of this Game Object.
* The origin maps the relationship between the size and position of the Game Object.
* The default value is 0.5, meaning all Game Objects are positioned based on their center.
* Setting the value to 0 means the position now relates to the top of the Game Object.
*
* @name Phaser.GameObjects.NineSlice#originY
* @type {number}
* @since 3.60.0
*/
originY: {
get: function() {
return this._originY;
},
set: function(value) {
this._originY = value;
this.updateVertices();
}
},
/**
* Sets the origin of this Game Object.
*
* The values are given in the range 0 to 1.
*
* @method Phaser.GameObjects.NineSlice#setOrigin
* @since 3.60.0
*
* @param {number} [x=0.5] - The horizontal origin value.
* @param {number} [y=x] - The vertical origin value. If not defined it will be set to the value of `x`.
*
* @return {this} This Game Object instance.
*/
setOrigin: function(x, y) {
if (x === void 0) {
x = 0.5;
}
if (y === void 0) {
y = x;
}
this._originX = x;
this._originY = y;
this.updateVertices();
return this.updateDisplayOrigin();
},
/**
* This method is included but does nothing for the Nine Slice Game Object,
* because the size of the object isn't based on the texture frame.
*
* You should not call this method.
*
* @method Phaser.GameObjects.NineSlice#setSizeToFrame
* @since 3.60.0
*
* @return {this} This Game Object instance.
*/
setSizeToFrame: function() {
if (this.is3Slice) {
var height = this.frame.height;
this._height = height;
this.topHeight = height;
this.bottomHeight = 0;
}
this.updateUVs();
return this;
},
/**
* Handles the pre-destroy step for the Nine Slice, which removes the vertices.
*
* @method Phaser.GameObjects.NineSlice#preDestroy
* @private
* @since 3.60.0
*/
preDestroy: function() {
this.vertices = [];
}
});
module2.exports = NineSlice;
}
),
/***/
28279: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var BuildGameObject = __webpack_require__2(25305);
var GameObjectCreator = __webpack_require__2(44603);
var GetAdvancedValue = __webpack_require__2(23568);
var GetValue = __webpack_require__2(35154);
var NineSlice = __webpack_require__2(28103);
GameObjectCreator.register("nineslice", function(config, addToScene) {
if (config === void 0) {
config = {};
}
var key = GetAdvancedValue(config, "key", null);
var frame = GetAdvancedValue(config, "frame", null);
var width = GetValue(config, "width", 256);
var height = GetValue(config, "height", 256);
var leftWidth = GetValue(config, "leftWidth", 10);
var rightWidth = GetValue(config, "rightWidth", 10);
var topHeight = GetValue(config, "topHeight", 0);
var bottomHeight = GetValue(config, "bottomHeight", 0);
var nineslice = new NineSlice(this.scene, 0, 0, key, frame, width, height, leftWidth, rightWidth, topHeight, bottomHeight);
if (addToScene !== void 0) {
config.add = addToScene;
}
BuildGameObject(this.scene, nineslice, config);
return nineslice;
});
}
),
/***/
47521: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var NineSlice = __webpack_require__2(28103);
var GameObjectFactory = __webpack_require__2(39429);
if (true) {
GameObjectFactory.register("nineslice", function(x, y, texture, frame, width, height, leftWidth, rightWidth, topHeight, bottomHeight) {
return this.displayList.add(new NineSlice(this.scene, x, y, texture, frame, width, height, leftWidth, rightWidth, topHeight, bottomHeight));
});
}
}
),
/***/
78023: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(52230);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
52230: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetCalcMatrix = __webpack_require__2(91296);
var Utils = __webpack_require__2(70554);
var NineSliceWebGLRenderer = function(renderer, src, camera, parentMatrix) {
var verts = src.vertices;
var totalVerts = verts.length;
if (totalVerts === 0) {
return;
}
camera.addToRenderList(src);
var pipeline = renderer.pipelines.set(src.pipeline, src);
var calcMatrix = GetCalcMatrix(src, camera, parentMatrix, false).calc;
renderer.pipelines.preBatch(src);
var textureUnit = pipeline.setGameObject(src);
var F32 = pipeline.vertexViewF32;
var U32 = pipeline.vertexViewU32;
var vertexOffset = pipeline.vertexCount * pipeline.currentShader.vertexComponentCount - 1;
var roundPixels = camera.roundPixels;
var tintEffect = src.tintFill;
var alpha = camera.alpha * src.alpha;
var color = Utils.getTintAppendFloatAlpha(src.tint, alpha);
var available = pipeline.vertexAvailable();
var flushCount = -1;
if (available < totalVerts) {
flushCount = available;
}
for (var i = 0; i < totalVerts; i++) {
var vert = verts[i];
if (i === flushCount) {
pipeline.flush();
textureUnit = pipeline.setGameObject(src);
vertexOffset = 0;
}
F32[++vertexOffset] = calcMatrix.getXRound(vert.vx, vert.vy, roundPixels);
F32[++vertexOffset] = calcMatrix.getYRound(vert.vx, vert.vy, roundPixels);
F32[++vertexOffset] = vert.u;
F32[++vertexOffset] = vert.v;
F32[++vertexOffset] = textureUnit;
F32[++vertexOffset] = tintEffect;
U32[++vertexOffset] = color;
pipeline.vertexCount++;
pipeline.currentBatch.count = pipeline.vertexCount - pipeline.currentBatch.start;
}
renderer.pipelines.postBatch(src);
};
module2.exports = NineSliceWebGLRenderer;
}
),
/***/
76472: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var EmitterOp = __webpack_require__2(44777);
var GetColor = __webpack_require__2(37589);
var GetEaseFunction = __webpack_require__2(6113);
var GetInterpolationFunction = __webpack_require__2(91389);
var IntegerToRGB = __webpack_require__2(90664);
var EmitterColorOp = new Class({
Extends: EmitterOp,
initialize: function EmitterColorOp2(key) {
EmitterOp.call(this, key, null, false);
this.active = false;
this.easeName = "Linear";
this.r = [];
this.g = [];
this.b = [];
},
/**
* Checks the type of `EmitterOp.propertyValue` to determine which
* method is required in order to return values from this op function.
*
* @method Phaser.GameObjects.Particles.EmitterColorOp#getMethod
* @since 3.60.0
*
* @return {number} A number between 0 and 9 which should be passed to `setMethods`.
*/
getMethod: function() {
return this.propertyValue === null ? 0 : 9;
},
/**
* Sets the EmitterColorOp method values, if in use.
*
* @method Phaser.GameObjects.Particles.EmitterColorOp#setMethods
* @since 3.60.0
*
* @return {this} This Emitter Op object.
*/
setMethods: function() {
var value = this.propertyValue;
var current = value;
var onEmit = this.defaultEmit;
var onUpdate = this.defaultUpdate;
if (this.method === 9) {
this.start = value[0];
this.ease = GetEaseFunction("Linear");
this.interpolation = GetInterpolationFunction("linear");
onEmit = this.easedValueEmit;
onUpdate = this.easeValueUpdate;
current = value[0];
this.active = true;
for (var i = 0; i < value.length; i++) {
var color = IntegerToRGB(value[i]);
this.r.push(color.r);
this.g.push(color.g);
this.b.push(color.b);
}
}
this.onEmit = onEmit;
this.onUpdate = onUpdate;
this.current = current;
return this;
},
/**
* Sets the Ease function to use for Color interpolation.
*
* @method Phaser.GameObjects.Particles.EmitterColorOp#setEase
* @since 3.60.0
*
* @param {string} ease - The string-based name of the Ease function to use.
*/
setEase: function(value) {
this.easeName = value;
this.ease = GetEaseFunction(value);
},
/**
* An `onEmit` callback for an eased property.
*
* It prepares the particle for easing by {@link Phaser.GameObjects.Particles.EmitterColorOp#easeValueUpdate}.
*
* @method Phaser.GameObjects.Particles.EmitterColorOp#easedValueEmit
* @since 3.60.0
*
* @param {Phaser.GameObjects.Particles.Particle} particle - The particle.
* @param {string} key - The name of the property.
*
* @return {number} {@link Phaser.GameObjects.Particles.EmitterColorOp#start}, as the new value of the property.
*/
easedValueEmit: function() {
this.current = this.start;
return this.start;
},
/**
* An `onUpdate` callback that returns an eased value between the
* {@link Phaser.GameObjects.Particles.EmitterColorOp#start} and {@link Phaser.GameObjects.Particles.EmitterColorOp#end}
* range.
*
* @method Phaser.GameObjects.Particles.EmitterColorOp#easeValueUpdate
* @since 3.60.0
*
* @param {Phaser.GameObjects.Particles.Particle} particle - The particle.
* @param {string} key - The name of the property.
* @param {number} t - The current normalized lifetime of the particle, between 0 (birth) and 1 (death).
*
* @return {number} The new value of the property.
*/
easeValueUpdate: function(particle, key, t) {
var v = this.ease(t);
var r = this.interpolation(this.r, v);
var g = this.interpolation(this.g, v);
var b = this.interpolation(this.b, v);
var current = GetColor(r, g, b);
this.current = current;
return current;
}
});
module2.exports = EmitterColorOp;
}
),
/***/
44777: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Between = __webpack_require__2(30976);
var Clamp = __webpack_require__2(45319);
var Class = __webpack_require__2(83419);
var FloatBetween = __webpack_require__2(99472);
var GetEaseFunction = __webpack_require__2(6113);
var GetFastValue = __webpack_require__2(95540);
var GetInterpolationFunction = __webpack_require__2(91389);
var SnapTo = __webpack_require__2(77720);
var Wrap = __webpack_require__2(15994);
var EmitterOp = new Class({
initialize: function EmitterOp2(key, defaultValue, emitOnly) {
if (emitOnly === void 0) {
emitOnly = false;
}
this.propertyKey = key;
this.propertyValue = defaultValue;
this.defaultValue = defaultValue;
this.steps = 0;
this.counter = 0;
this.yoyo = false;
this.direction = 0;
this.start = 0;
this.current = 0;
this.end = 0;
this.ease = null;
this.interpolation = null;
this.emitOnly = emitOnly;
this.onEmit = this.defaultEmit;
this.onUpdate = this.defaultUpdate;
this.active = true;
this.method = 0;
this._onEmit;
this._onUpdate;
},
/**
* Load the property from a Particle Emitter configuration object.
*
* Optionally accepts a new property key to use, replacing the current one.
*
* @method Phaser.GameObjects.Particles.EmitterOp#loadConfig
* @since 3.0.0
*
* @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig} [config] - Settings for the Particle Emitter that owns this property.
* @param {string} [newKey] - The new key to use for this property, if any.
*/
loadConfig: function(config, newKey) {
if (config === void 0) {
config = {};
}
if (newKey) {
this.propertyKey = newKey;
}
this.propertyValue = GetFastValue(
config,
this.propertyKey,
this.defaultValue
);
this.method = this.getMethod();
this.setMethods();
if (this.emitOnly) {
this.onUpdate = this.defaultUpdate;
}
},
/**
* Build a JSON representation of this Particle Emitter property.
*
* @method Phaser.GameObjects.Particles.EmitterOp#toJSON
* @since 3.0.0
*
* @return {object} A JSON representation of this Particle Emitter property.
*/
toJSON: function() {
return JSON.stringify(this.propertyValue);
},
/**
* Change the current value of the property and update its callback methods.
*
* @method Phaser.GameObjects.Particles.EmitterOp#onChange
* @since 3.0.0
*
* @param {number} value - The new numeric value of this property.
*
* @return {this} This Emitter Op object.
*/
onChange: function(value) {
var current;
switch (this.method) {
case 1:
case 3:
case 8:
current = value;
break;
case 2:
if (this.propertyValue.indexOf(value) >= 0) {
current = value;
}
break;
case 4:
var step = (this.end - this.start) / this.steps;
current = SnapTo(value, step);
this.counter = current;
break;
case 5:
case 6:
case 7:
current = Clamp(value, this.start, this.end);
break;
case 9:
current = this.start[0];
break;
}
this.current = current;
return this;
},
/**
* Checks the type of `EmitterOp.propertyValue` to determine which
* method is required in order to return values from this op function.
*
* @method Phaser.GameObjects.Particles.EmitterOp#getMethod
* @since 3.60.0
*
* @return {number} A number between 0 and 9 which should be passed to `setMethods`.
*/
getMethod: function() {
var value = this.propertyValue;
if (value === null) {
return 0;
}
var t = typeof value;
if (t === "number") {
return 1;
} else if (Array.isArray(value)) {
return 2;
} else if (t === "function") {
return 3;
} else if (t === "object") {
if (this.hasBoth(value, "start", "end")) {
if (this.has(value, "steps")) {
return 4;
} else {
return 5;
}
} else if (this.hasBoth(value, "min", "max")) {
return 6;
} else if (this.has(value, "random")) {
return 7;
} else if (this.hasEither(value, "onEmit", "onUpdate")) {
return 8;
} else if (this.hasEither(value, "values", "interpolation")) {
return 9;
}
}
return 0;
},
/**
* Update the {@link Phaser.GameObjects.Particles.EmitterOp#onEmit} and
* {@link Phaser.GameObjects.Particles.EmitterOp#onUpdate} callbacks based on the method returned
* from `getMethod`. The method is stored in the `EmitterOp.method` property
* and is a number between 0 and 9 inclusively.
*
* @method Phaser.GameObjects.Particles.EmitterOp#setMethods
* @since 3.0.0
*
* @return {this} This Emitter Op object.
*/
setMethods: function() {
var value = this.propertyValue;
var current = value;
var onEmit = this.defaultEmit;
var onUpdate = this.defaultUpdate;
switch (this.method) {
case 1:
onEmit = this.staticValueEmit;
break;
case 2:
onEmit = this.randomStaticValueEmit;
current = value[0];
break;
case 3:
this._onEmit = value;
onEmit = this.proxyEmit;
break;
case 4:
this.start = value.start;
this.end = value.end;
this.steps = value.steps;
this.counter = this.start;
this.yoyo = this.has(value, "yoyo") ? value.yoyo : false;
this.direction = 0;
onEmit = this.steppedEmit;
current = this.start;
break;
case 5:
this.start = value.start;
this.end = value.end;
var easeType = this.has(value, "ease") ? value.ease : "Linear";
this.ease = GetEaseFunction(easeType, value.easeParams);
onEmit = this.has(value, "random") && value.random ? this.randomRangedValueEmit : this.easedValueEmit;
onUpdate = this.easeValueUpdate;
current = this.start;
break;
case 6:
this.start = value.min;
this.end = value.max;
onEmit = this.has(value, "int") && value.int ? this.randomRangedIntEmit : this.randomRangedValueEmit;
current = this.start;
break;
case 7:
var rnd = value.random;
if (Array.isArray(rnd)) {
this.start = rnd[0];
this.end = rnd[1];
}
onEmit = this.randomRangedIntEmit;
current = this.start;
break;
case 8:
this._onEmit = this.has(value, "onEmit") ? value.onEmit : this.defaultEmit;
this._onUpdate = this.has(value, "onUpdate") ? value.onUpdate : this.defaultUpdate;
onEmit = this.proxyEmit;
onUpdate = this.proxyUpdate;
break;
case 9:
this.start = value.values;
var easeTypeI = this.has(value, "ease") ? value.ease : "Linear";
this.ease = GetEaseFunction(easeTypeI, value.easeParams);
this.interpolation = GetInterpolationFunction(value.interpolation);
onEmit = this.easedValueEmit;
onUpdate = this.easeValueUpdate;
current = this.start[0];
break;
}
this.onEmit = onEmit;
this.onUpdate = onUpdate;
this.current = current;
return this;
},
/**
* Check whether an object has the given property.
*
* @method Phaser.GameObjects.Particles.EmitterOp#has
* @since 3.0.0
*
* @param {object} object - The object to check.
* @param {string} key - The key of the property to look for in the object.
*
* @return {boolean} `true` if the property exists in the object, `false` otherwise.
*/
has: function(object, key) {
return object.hasOwnProperty(key);
},
/**
* Check whether an object has both of the given properties.
*
* @method Phaser.GameObjects.Particles.EmitterOp#hasBoth
* @since 3.0.0
*
* @param {object} object - The object to check.
* @param {string} key1 - The key of the first property to check the object for.
* @param {string} key2 - The key of the second property to check the object for.
*
* @return {boolean} `true` if both properties exist in the object, `false` otherwise.
*/
hasBoth: function(object, key1, key2) {
return object.hasOwnProperty(key1) && object.hasOwnProperty(key2);
},
/**
* Check whether an object has at least one of the given properties.
*
* @method Phaser.GameObjects.Particles.EmitterOp#hasEither
* @since 3.0.0
*
* @param {object} object - The object to check.
* @param {string} key1 - The key of the first property to check the object for.
* @param {string} key2 - The key of the second property to check the object for.
*
* @return {boolean} `true` if at least one of the properties exists in the object, `false` if neither exist.
*/
hasEither: function(object, key1, key2) {
return object.hasOwnProperty(key1) || object.hasOwnProperty(key2);
},
/**
* The returned value sets what the property will be at the START of the particles life, on emit.
*
* @method Phaser.GameObjects.Particles.EmitterOp#defaultEmit
* @since 3.0.0
*
* @param {Phaser.GameObjects.Particles.Particle} particle - The particle.
* @param {string} key - The name of the property.
* @param {number} [value] - The current value of the property.
*
* @return {number} The new value of the property.
*/
defaultEmit: function(particle, key, value) {
return value;
},
/**
* The returned value updates the property for the duration of the particles life.
*
* @method Phaser.GameObjects.Particles.EmitterOp#defaultUpdate
* @since 3.0.0
*
* @param {Phaser.GameObjects.Particles.Particle} particle - The particle.
* @param {string} key - The name of the property.
* @param {number} t - The current normalized lifetime of the particle, between 0 (birth) and 1 (death).
* @param {number} value - The current value of the property.
*
* @return {number} The new value of the property.
*/
defaultUpdate: function(particle, key, t, value) {
return value;
},
/**
* The returned value sets what the property will be at the START of the particles life, on emit.
*
* This method is only used when you have provided a custom emit callback.
*
* @method Phaser.GameObjects.Particles.EmitterOp#proxyEmit
* @since 3.60.0
*
* @param {Phaser.GameObjects.Particles.Particle} particle - The particle.
* @param {string} key - The name of the property.
* @param {number} [value] - The current value of the property.
*
* @return {number} The new value of the property.
*/
proxyEmit: function(particle, key, value) {
var result = this._onEmit(particle, key, value);
this.current = result;
return result;
},
/**
* The returned value updates the property for the duration of the particles life.
*
* This method is only used when you have provided a custom update callback.
*
* @method Phaser.GameObjects.Particles.EmitterOp#proxyUpdate
* @since 3.60.0
*
* @param {Phaser.GameObjects.Particles.Particle} particle - The particle.
* @param {string} key - The name of the property.
* @param {number} t - The current normalized lifetime of the particle, between 0 (birth) and 1 (death).
* @param {number} value - The current value of the property.
*
* @return {number} The new value of the property.
*/
proxyUpdate: function(particle, key, t, value) {
var result = this._onUpdate(particle, key, t, value);
this.current = result;
return result;
},
/**
* An `onEmit` callback that returns the current value of the property.
*
* @method Phaser.GameObjects.Particles.EmitterOp#staticValueEmit
* @since 3.0.0
*
* @return {number} The current value of the property.
*/
staticValueEmit: function() {
return this.current;
},
/**
* An `onUpdate` callback that returns the current value of the property.
*
* @method Phaser.GameObjects.Particles.EmitterOp#staticValueUpdate
* @since 3.0.0
*
* @return {number} The current value of the property.
*/
staticValueUpdate: function() {
return this.current;
},
/**
* An `onEmit` callback that returns a random value from the current value array.
*
* @method Phaser.GameObjects.Particles.EmitterOp#randomStaticValueEmit
* @since 3.0.0
*
* @return {number} The new value of the property.
*/
randomStaticValueEmit: function() {
var randomIndex = Math.floor(Math.random() * this.propertyValue.length);
this.current = this.propertyValue[randomIndex];
return this.current;
},
/**
* An `onEmit` callback that returns a value between the {@link Phaser.GameObjects.Particles.EmitterOp#start} and
* {@link Phaser.GameObjects.Particles.EmitterOp#end} range.
*
* @method Phaser.GameObjects.Particles.EmitterOp#randomRangedValueEmit
* @since 3.0.0
*
* @param {Phaser.GameObjects.Particles.Particle} particle - The particle.
* @param {string} key - The key of the property.
*
* @return {number} The new value of the property.
*/
randomRangedValueEmit: function(particle, key) {
var value = FloatBetween(this.start, this.end);
if (particle && particle.data[key]) {
particle.data[key].min = value;
particle.data[key].max = this.end;
}
this.current = value;
return value;
},
/**
* An `onEmit` callback that returns a value between the {@link Phaser.GameObjects.Particles.EmitterOp#start} and
* {@link Phaser.GameObjects.Particles.EmitterOp#end} range.
*
* @method Phaser.GameObjects.Particles.EmitterOp#randomRangedIntEmit
* @since 3.60.0
*
* @param {Phaser.GameObjects.Particles.Particle} particle - The particle.
* @param {string} key - The key of the property.
*
* @return {number} The new value of the property.
*/
randomRangedIntEmit: function(particle, key) {
var value = Between(this.start, this.end);
if (particle && particle.data[key]) {
particle.data[key].min = value;
particle.data[key].max = this.end;
}
this.current = value;
return value;
},
/**
* An `onEmit` callback that returns a stepped value between the
* {@link Phaser.GameObjects.Particles.EmitterOp#start} and {@link Phaser.GameObjects.Particles.EmitterOp#end}
* range.
*
* @method Phaser.GameObjects.Particles.EmitterOp#steppedEmit
* @since 3.0.0
*
* @return {number} The new value of the property.
*/
steppedEmit: function() {
var current = this.counter;
var next = current;
var step = (this.end - this.start) / this.steps;
if (this.yoyo) {
var over;
if (this.direction === 0) {
next += step;
if (next >= this.end) {
over = next - this.end;
next = this.end - over;
this.direction = 1;
}
} else {
next -= step;
if (next <= this.start) {
over = this.start - next;
next = this.start + over;
this.direction = 0;
}
}
this.counter = next;
} else {
this.counter = Wrap(next + step, this.start, this.end);
}
this.current = current;
return current;
},
/**
* An `onEmit` callback for an eased property.
*
* It prepares the particle for easing by {@link Phaser.GameObjects.Particles.EmitterOp#easeValueUpdate}.
*
* @method Phaser.GameObjects.Particles.EmitterOp#easedValueEmit
* @since 3.0.0
*
* @param {Phaser.GameObjects.Particles.Particle} particle - The particle.
* @param {string} key - The name of the property.
*
* @return {number} {@link Phaser.GameObjects.Particles.EmitterOp#start}, as the new value of the property.
*/
easedValueEmit: function(particle, key) {
if (particle && particle.data[key]) {
var data = particle.data[key];
data.min = this.start;
data.max = this.end;
}
this.current = this.start;
return this.start;
},
/**
* An `onUpdate` callback that returns an eased value between the
* {@link Phaser.GameObjects.Particles.EmitterOp#start} and {@link Phaser.GameObjects.Particles.EmitterOp#end}
* range.
*
* @method Phaser.GameObjects.Particles.EmitterOp#easeValueUpdate
* @since 3.0.0
*
* @param {Phaser.GameObjects.Particles.Particle} particle - The particle.
* @param {string} key - The name of the property.
* @param {number} t - The current normalized lifetime of the particle, between 0 (birth) and 1 (death).
*
* @return {number} The new value of the property.
*/
easeValueUpdate: function(particle, key, t) {
var data = particle.data[key];
var current;
var v = this.ease(t);
if (this.interpolation) {
current = this.interpolation(this.start, v);
} else {
current = (data.max - data.min) * v + data.min;
}
this.current = current;
return current;
},
/**
* Destroys this EmitterOp instance and all of its references.
*
* Called automatically when the ParticleEmitter that owns this
* EmitterOp is destroyed.
*
* @method Phaser.GameObjects.Particles.EmitterOp#destroy
* @since 3.60.0
*/
destroy: function() {
this.propertyValue = null;
this.defaultValue = null;
this.ease = null;
this.interpolation = null;
this._onEmit = null;
this._onUpdate = null;
}
});
module2.exports = EmitterOp;
}
),
/***/
24502: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var GetFastValue = __webpack_require__2(95540);
var ParticleProcessor = __webpack_require__2(20286);
var GravityWell = new Class({
Extends: ParticleProcessor,
initialize: function GravityWell2(x, y, power, epsilon, gravity) {
if (typeof x === "object") {
var config = x;
x = GetFastValue(config, "x", 0);
y = GetFastValue(config, "y", 0);
power = GetFastValue(config, "power", 0);
epsilon = GetFastValue(config, "epsilon", 100);
gravity = GetFastValue(config, "gravity", 50);
} else {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (power === void 0) {
power = 0;
}
if (epsilon === void 0) {
epsilon = 100;
}
if (gravity === void 0) {
gravity = 50;
}
}
ParticleProcessor.call(this, x, y, true);
this._gravity = gravity;
this._power = power * gravity;
this._epsilon = epsilon * epsilon;
},
/**
* Takes a Particle and updates it based on the properties of this Gravity Well.
*
* @method Phaser.GameObjects.Particles.GravityWell#update
* @since 3.0.0
*
* @param {Phaser.GameObjects.Particles.Particle} particle - The Particle to update.
* @param {number} delta - The delta time in ms.
* @param {number} step - The delta value divided by 1000.
*/
update: function(particle, delta) {
var x = this.x - particle.x;
var y = this.y - particle.y;
var dSq = x * x + y * y;
if (dSq === 0) {
return;
}
var d = Math.sqrt(dSq);
if (dSq < this._epsilon) {
dSq = this._epsilon;
}
var factor = this._power * delta / (dSq * d) * 100;
particle.velocityX += x * factor;
particle.velocityY += y * factor;
},
/**
* The minimum distance for which the gravity force is calculated.
*
* Defaults to 100.
*
* @name Phaser.GameObjects.Particles.GravityWell#epsilon
* @type {number}
* @since 3.0.0
*/
epsilon: {
get: function() {
return Math.sqrt(this._epsilon);
},
set: function(value) {
this._epsilon = value * value;
}
},
/**
* The strength of the gravity force - larger numbers produce a stronger force.
*
* Defaults to 0.
*
* @name Phaser.GameObjects.Particles.GravityWell#power
* @type {number}
* @since 3.0.0
*/
power: {
get: function() {
return this._power / this._gravity;
},
set: function(value) {
this._power = value * this._gravity;
}
},
/**
* The gravitational force of this Gravity Well.
*
* Defaults to 50.
*
* @name Phaser.GameObjects.Particles.GravityWell#gravity
* @type {number}
* @since 3.0.0
*/
gravity: {
get: function() {
return this._gravity;
},
set: function(value) {
var pwr = this.power;
this._gravity = value;
this.power = pwr;
}
}
});
module2.exports = GravityWell;
}
),
/***/
56480: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var AnimationState = __webpack_require__2(9674);
var Clamp = __webpack_require__2(45319);
var Class = __webpack_require__2(83419);
var DegToRad = __webpack_require__2(39506);
var Rectangle = __webpack_require__2(87841);
var RotateAround = __webpack_require__2(11520);
var Vector2 = __webpack_require__2(26099);
var Particle = new Class({
initialize: function Particle2(emitter) {
this.emitter = emitter;
this.texture = null;
this.frame = null;
this.x = 0;
this.y = 0;
this.worldPosition = new Vector2();
this.velocityX = 0;
this.velocityY = 0;
this.accelerationX = 0;
this.accelerationY = 0;
this.maxVelocityX = 1e4;
this.maxVelocityY = 1e4;
this.bounce = 0;
this.scaleX = 1;
this.scaleY = 1;
this.alpha = 1;
this.angle = 0;
this.rotation = 0;
this.tint = 16777215;
this.life = 1e3;
this.lifeCurrent = 1e3;
this.delayCurrent = 0;
this.holdCurrent = 0;
this.lifeT = 0;
this.data = {
tint: { min: 16777215, max: 16777215 },
alpha: { min: 1, max: 1 },
rotate: { min: 0, max: 0 },
scaleX: { min: 1, max: 1 },
scaleY: { min: 1, max: 1 },
x: { min: 0, max: 0 },
y: { min: 0, max: 0 },
accelerationX: { min: 0, max: 0 },
accelerationY: { min: 0, max: 0 },
maxVelocityX: { min: 0, max: 0 },
maxVelocityY: { min: 0, max: 0 },
moveToX: { min: 0, max: 0 },
moveToY: { min: 0, max: 0 },
bounce: { min: 0, max: 0 }
};
this.isCropped = false;
this.scene = emitter.scene;
this.anims = new AnimationState(this);
this.bounds = new Rectangle();
},
/**
* The Event Emitter proxy.
*
* Passes on all parameters to the `ParticleEmitter` to emit directly.
*
* @method Phaser.GameObjects.Particles.Particle#emit
* @since 3.60.0
*
* @param {(string|Symbol)} event - The event name.
* @param {any} [a1] - Optional argument 1.
* @param {any} [a2] - Optional argument 2.
* @param {any} [a3] - Optional argument 3.
* @param {any} [a4] - Optional argument 4.
* @param {any} [a5] - Optional argument 5.
*
* @return {boolean} `true` if the event had listeners, else `false`.
*/
emit: function(event, a1, a2, a3, a4, a5) {
return this.emitter.emit(event, a1, a2, a3, a4, a5);
},
/**
* Checks to see if this Particle is alive and updating.
*
* @method Phaser.GameObjects.Particles.Particle#isAlive
* @since 3.0.0
*
* @return {boolean} `true` if this Particle is alive and updating, otherwise `false`.
*/
isAlive: function() {
return this.lifeCurrent > 0;
},
/**
* Kills this particle. This sets the `lifeCurrent` value to 0, which forces
* the Particle to be removed the next time its parent Emitter runs an update.
*
* @method Phaser.GameObjects.Particles.Particle#kill
* @since 3.60.0
*/
kill: function() {
this.lifeCurrent = 0;
},
/**
* Sets the position of this particle to the given x/y coordinates.
*
* If the parameters are left undefined, it resets the particle back to 0x0.
*
* @method Phaser.GameObjects.Particles.Particle#setPosition
* @since 3.60.0
*
* @param {number} [x=0] - The x coordinate to set this Particle to.
* @param {number} [y=0] - The y coordinate to set this Particle to.
*/
setPosition: function(x, y) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
this.x = x;
this.y = y;
},
/**
* Starts this Particle from the given coordinates.
*
* @method Phaser.GameObjects.Particles.Particle#fire
* @since 3.0.0
*
* @param {number} [x] - The x coordinate to launch this Particle from.
* @param {number} [y] - The y coordinate to launch this Particle from.
*
* @return {boolean} `true` if the Particle is alive, or `false` if it was spawned inside a DeathZone.
*/
fire: function(x, y) {
var emitter = this.emitter;
var ops = emitter.ops;
var anim = emitter.getAnim();
if (anim) {
this.anims.play(anim);
} else {
this.frame = emitter.getFrame();
this.texture = this.frame.texture;
}
if (!this.frame) {
throw new Error("Particle has no texture frame");
}
emitter.getEmitZone(this);
if (x === void 0) {
this.x += ops.x.onEmit(this, "x");
} else if (ops.x.steps > 0) {
this.x += x + ops.x.onEmit(this, "x");
} else {
this.x += x;
}
if (y === void 0) {
this.y += ops.y.onEmit(this, "y");
} else if (ops.y.steps > 0) {
this.y += y + ops.y.onEmit(this, "y");
} else {
this.y += y;
}
this.life = ops.lifespan.onEmit(this, "lifespan");
this.lifeCurrent = this.life;
this.lifeT = 0;
this.delayCurrent = ops.delay.onEmit(this, "delay");
this.holdCurrent = ops.hold.onEmit(this, "hold");
this.scaleX = ops.scaleX.onEmit(this, "scaleX");
this.scaleY = ops.scaleY.active ? ops.scaleY.onEmit(this, "scaleY") : this.scaleX;
this.angle = ops.rotate.onEmit(this, "rotate");
this.rotation = DegToRad(this.angle);
emitter.worldMatrix.transformPoint(this.x, this.y, this.worldPosition);
if (this.delayCurrent === 0 && emitter.getDeathZone(this)) {
this.lifeCurrent = 0;
return false;
}
var sx = ops.speedX.onEmit(this, "speedX");
var sy = ops.speedY.active ? ops.speedY.onEmit(this, "speedY") : sx;
if (emitter.radial) {
var rad = DegToRad(ops.angle.onEmit(this, "angle"));
this.velocityX = Math.cos(rad) * Math.abs(sx);
this.velocityY = Math.sin(rad) * Math.abs(sy);
} else if (emitter.moveTo) {
var mx = ops.moveToX.onEmit(this, "moveToX");
var my = ops.moveToY.onEmit(this, "moveToY");
var lifeS = this.life / 1e3;
this.velocityX = (mx - this.x) / lifeS;
this.velocityY = (my - this.y) / lifeS;
} else {
this.velocityX = sx;
this.velocityY = sy;
}
if (emitter.acceleration) {
this.accelerationX = ops.accelerationX.onEmit(this, "accelerationX");
this.accelerationY = ops.accelerationY.onEmit(this, "accelerationY");
}
this.maxVelocityX = ops.maxVelocityX.onEmit(this, "maxVelocityX");
this.maxVelocityY = ops.maxVelocityY.onEmit(this, "maxVelocityY");
this.bounce = ops.bounce.onEmit(this, "bounce");
this.alpha = ops.alpha.onEmit(this, "alpha");
if (ops.color.active) {
this.tint = ops.color.onEmit(this, "tint");
} else {
this.tint = ops.tint.onEmit(this, "tint");
}
return true;
},
/**
* The main update method for this Particle.
*
* Updates its life values, computes the velocity and repositions the Particle.
*
* @method Phaser.GameObjects.Particles.Particle#update
* @since 3.0.0
*
* @param {number} delta - The delta time in ms.
* @param {number} step - The delta value divided by 1000.
* @param {Phaser.GameObjects.Particles.ParticleProcessor[]} processors - An array of all active Particle Processors.
*
* @return {boolean} Returns `true` if this Particle has now expired and should be removed, otherwise `false` if still active.
*/
update: function(delta, step, processors) {
if (this.lifeCurrent <= 0) {
if (this.holdCurrent > 0) {
this.holdCurrent -= delta;
return this.holdCurrent <= 0;
} else {
return true;
}
}
if (this.delayCurrent > 0) {
this.delayCurrent -= delta;
return false;
}
this.anims.update(0, delta);
var emitter = this.emitter;
var ops = emitter.ops;
var t = 1 - this.lifeCurrent / this.life;
this.lifeT = t;
this.x = ops.x.onUpdate(this, "x", t, this.x);
this.y = ops.y.onUpdate(this, "y", t, this.y);
if (emitter.moveTo) {
var mx = ops.moveToX.onUpdate(this, "moveToX", t, emitter.moveToX);
var my = ops.moveToY.onUpdate(this, "moveToY", t, emitter.moveToY);
var lifeS = this.lifeCurrent / 1e3;
this.velocityX = (mx - this.x) / lifeS;
this.velocityY = (my - this.y) / lifeS;
}
this.computeVelocity(emitter, delta, step, processors, t);
this.scaleX = ops.scaleX.onUpdate(this, "scaleX", t, this.scaleX);
if (ops.scaleY.active) {
this.scaleY = ops.scaleY.onUpdate(this, "scaleY", t, this.scaleY);
} else {
this.scaleY = this.scaleX;
}
this.angle = ops.rotate.onUpdate(this, "rotate", t, this.angle);
this.rotation = DegToRad(this.angle);
if (emitter.getDeathZone(this)) {
this.lifeCurrent = 0;
return true;
}
this.alpha = Clamp(ops.alpha.onUpdate(this, "alpha", t, this.alpha), 0, 1);
if (ops.color.active) {
this.tint = ops.color.onUpdate(this, "color", t, this.tint);
} else {
this.tint = ops.tint.onUpdate(this, "tint", t, this.tint);
}
this.lifeCurrent -= delta;
return this.lifeCurrent <= 0 && this.holdCurrent <= 0;
},
/**
* An internal method that calculates the velocity of the Particle and
* its world position. It also runs it against any active Processors
* that are set on the Emitter.
*
* @method Phaser.GameObjects.Particles.Particle#computeVelocity
* @since 3.0.0
*
* @param {Phaser.GameObjects.Particles.ParticleEmitter} emitter - The Emitter that is updating this Particle.
* @param {number} delta - The delta time in ms.
* @param {number} step - The delta value divided by 1000.
* @param {Phaser.GameObjects.Particles.ParticleProcessor[]} processors - An array of all active Particle Processors.
* @param {number} t - The current normalized lifetime of the particle, between 0 (birth) and 1 (death).
*/
computeVelocity: function(emitter, delta, step, processors, t) {
var ops = emitter.ops;
var vx = this.velocityX;
var vy = this.velocityY;
var ax = ops.accelerationX.onUpdate(this, "accelerationX", t, this.accelerationX);
var ay = ops.accelerationY.onUpdate(this, "accelerationY", t, this.accelerationY);
var mx = ops.maxVelocityX.onUpdate(this, "maxVelocityX", t, this.maxVelocityX);
var my = ops.maxVelocityY.onUpdate(this, "maxVelocityY", t, this.maxVelocityY);
this.bounce = ops.bounce.onUpdate(this, "bounce", t, this.bounce);
vx += emitter.gravityX * step + ax * step;
vy += emitter.gravityY * step + ay * step;
vx = Clamp(vx, -mx, mx);
vy = Clamp(vy, -my, my);
this.velocityX = vx;
this.velocityY = vy;
this.x += vx * step;
this.y += vy * step;
emitter.worldMatrix.transformPoint(this.x, this.y, this.worldPosition);
for (var i = 0; i < processors.length; i++) {
var processor = processors[i];
if (processor.active) {
processor.update(this, delta, step, t);
}
}
},
/**
* This is a NOOP method and does nothing when called.
*
* @method Phaser.GameObjects.Particles.Particle#setSizeToFrame
* @since 3.60.0
*/
setSizeToFrame: function() {
},
/**
* Gets the bounds of this particle as a Geometry Rectangle, factoring in any
* transforms of the parent emitter and anything else above it in the display list.
*
* Once calculated the bounds can be accessed via the `Particle.bounds` property.
*
* @method Phaser.GameObjects.Particles.Particle#getBounds
* @since 3.60.0
*
* @param {Phaser.GameObjects.Components.TransformMatrix} [matrix] - Optional transform matrix to apply to this particle.
*
* @return {Phaser.Geom.Rectangle} A Rectangle containing the transformed bounds of this particle.
*/
getBounds: function(matrix) {
if (matrix === void 0) {
matrix = this.emitter.getWorldTransformMatrix();
}
var sx = Math.abs(matrix.scaleX) * this.scaleX;
var sy = Math.abs(matrix.scaleY) * this.scaleY;
var x = this.x;
var y = this.y;
var rotation = this.rotation;
var width = this.frame.width * sx / 2;
var height = this.frame.height * sy / 2;
var bounds = this.bounds;
var topLeft = new Vector2(x - width, y - height);
var topRight = new Vector2(x + width, y - height);
var bottomLeft = new Vector2(x - width, y + height);
var bottomRight = new Vector2(x + width, y + height);
if (rotation !== 0) {
RotateAround(topLeft, x, y, rotation);
RotateAround(topRight, x, y, rotation);
RotateAround(bottomLeft, x, y, rotation);
RotateAround(bottomRight, x, y, rotation);
}
matrix.transformPoint(topLeft.x, topLeft.y, topLeft);
matrix.transformPoint(topRight.x, topRight.y, topRight);
matrix.transformPoint(bottomLeft.x, bottomLeft.y, bottomLeft);
matrix.transformPoint(bottomRight.x, bottomRight.y, bottomRight);
bounds.x = Math.min(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x);
bounds.y = Math.min(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y);
bounds.width = Math.max(topLeft.x, topRight.x, bottomLeft.x, bottomRight.x) - bounds.x;
bounds.height = Math.max(topLeft.y, topRight.y, bottomLeft.y, bottomRight.y) - bounds.y;
return bounds;
},
/**
* Destroys this Particle.
*
* @method Phaser.GameObjects.Particles.Particle#destroy
* @since 3.60.0
*/
destroy: function() {
this.anims.destroy();
this.anims = null;
this.emitter = null;
this.texture = null;
this.frame = null;
this.scene = null;
}
});
module2.exports = Particle;
}
),
/***/
69601: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var ParticleProcessor = __webpack_require__2(20286);
var Rectangle = __webpack_require__2(87841);
var ParticleBounds = new Class({
Extends: ParticleProcessor,
initialize: function ParticleBounds2(x, y, width, height, collideLeft, collideRight, collideTop, collideBottom) {
if (collideLeft === void 0) {
collideLeft = true;
}
if (collideRight === void 0) {
collideRight = true;
}
if (collideTop === void 0) {
collideTop = true;
}
if (collideBottom === void 0) {
collideBottom = true;
}
ParticleProcessor.call(this, x, y, true);
this.bounds = new Rectangle(x, y, width, height);
this.collideLeft = collideLeft;
this.collideRight = collideRight;
this.collideTop = collideTop;
this.collideBottom = collideBottom;
},
/**
* Takes a Particle and updates it against the bounds.
*
* @method Phaser.GameObjects.Particles.ParticleBounds#update
* @since 3.0.0
*
* @param {Phaser.GameObjects.Particles.Particle} particle - The Particle to update.
*/
update: function(particle) {
var bounds = this.bounds;
var bounce = -particle.bounce;
var pos = particle.worldPosition;
if (pos.x < bounds.x && this.collideLeft) {
particle.x += bounds.x - pos.x;
particle.velocityX *= bounce;
} else if (pos.x > bounds.right && this.collideRight) {
particle.x -= pos.x - bounds.right;
particle.velocityX *= bounce;
}
if (pos.y < bounds.y && this.collideTop) {
particle.y += bounds.y - pos.y;
particle.velocityY *= bounce;
} else if (pos.y > bounds.bottom && this.collideBottom) {
particle.y -= pos.y - bounds.bottom;
particle.velocityY *= bounce;
}
}
});
module2.exports = ParticleBounds;
}
),
/***/
31600: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31401);
var ComponentsToJSON = __webpack_require__2(53774);
var CopyFrom = __webpack_require__2(43459);
var DeathZone = __webpack_require__2(26388);
var EdgeZone = __webpack_require__2(19909);
var EmitterColorOp = __webpack_require__2(76472);
var EmitterOp = __webpack_require__2(44777);
var Events = __webpack_require__2(20696);
var GameObject = __webpack_require__2(95643);
var GetFastValue = __webpack_require__2(95540);
var GetRandom = __webpack_require__2(26546);
var GravityWell = __webpack_require__2(24502);
var HasAny = __webpack_require__2(1985);
var HasValue = __webpack_require__2(97022);
var Inflate = __webpack_require__2(86091);
var List = __webpack_require__2(73162);
var MergeRect = __webpack_require__2(20074);
var MergeRight = __webpack_require__2(269);
var Particle = __webpack_require__2(56480);
var ParticleBounds = __webpack_require__2(69601);
var RandomZone = __webpack_require__2(68875);
var Rectangle = __webpack_require__2(87841);
var RectangleToRectangle = __webpack_require__2(59996);
var Remove = __webpack_require__2(72905);
var Render = __webpack_require__2(90668);
var StableSort = __webpack_require__2(19186);
var TransformMatrix = __webpack_require__2(61340);
var Vector2 = __webpack_require__2(26099);
var Wrap = __webpack_require__2(15994);
var configFastMap = [
"active",
"advance",
"blendMode",
"colorEase",
"deathCallback",
"deathCallbackScope",
"duration",
"emitCallback",
"emitCallbackScope",
"follow",
"frequency",
"gravityX",
"gravityY",
"maxAliveParticles",
"maxParticles",
"name",
"emitting",
"particleBringToTop",
"particleClass",
"radial",
"sortCallback",
"sortOrderAsc",
"sortProperty",
"stopAfter",
"tintFill",
"timeScale",
"trackVisible",
"visible"
];
var configOpMap = [
"accelerationX",
"accelerationY",
"alpha",
"angle",
"bounce",
"color",
"delay",
"hold",
"lifespan",
"maxVelocityX",
"maxVelocityY",
"moveToX",
"moveToY",
"quantity",
"rotate",
"scaleX",
"scaleY",
"speedX",
"speedY",
"tint",
"x",
"y"
];
var ParticleEmitter = new Class({
Extends: GameObject,
Mixins: [
Components.AlphaSingle,
Components.BlendMode,
Components.Depth,
Components.Mask,
Components.Pipeline,
Components.PostPipeline,
Components.ScrollFactor,
Components.Texture,
Components.Transform,
Components.Visible,
Render
],
initialize: function ParticleEmitter2(scene, x, y, texture, config) {
GameObject.call(this, scene, "ParticleEmitter");
this.particleClass = Particle;
this.config = null;
this.ops = {
accelerationX: new EmitterOp("accelerationX", 0),
accelerationY: new EmitterOp("accelerationY", 0),
alpha: new EmitterOp("alpha", 1),
angle: new EmitterOp("angle", { min: 0, max: 360 }, true),
bounce: new EmitterOp("bounce", 0),
color: new EmitterColorOp("color"),
delay: new EmitterOp("delay", 0, true),
hold: new EmitterOp("hold", 0, true),
lifespan: new EmitterOp("lifespan", 1e3, true),
maxVelocityX: new EmitterOp("maxVelocityX", 1e4),
maxVelocityY: new EmitterOp("maxVelocityY", 1e4),
moveToX: new EmitterOp("moveToX", 0),
moveToY: new EmitterOp("moveToY", 0),
quantity: new EmitterOp("quantity", 1, true),
rotate: new EmitterOp("rotate", 0),
scaleX: new EmitterOp("scaleX", 1),
scaleY: new EmitterOp("scaleY", 1),
speedX: new EmitterOp("speedX", 0, true),
speedY: new EmitterOp("speedY", 0, true),
tint: new EmitterOp("tint", 16777215),
x: new EmitterOp("x", 0),
y: new EmitterOp("y", 0)
};
this.radial = true;
this.gravityX = 0;
this.gravityY = 0;
this.acceleration = false;
this.moveTo = false;
this.emitCallback = null;
this.emitCallbackScope = null;
this.deathCallback = null;
this.deathCallbackScope = null;
this.maxParticles = 0;
this.maxAliveParticles = 0;
this.stopAfter = 0;
this.duration = 0;
this.frequency = 0;
this.emitting = true;
this.particleBringToTop = true;
this.timeScale = 1;
this.emitZones = [];
this.deathZones = [];
this.viewBounds = null;
this.follow = null;
this.followOffset = new Vector2();
this.trackVisible = false;
this.frames = [];
this.randomFrame = true;
this.frameQuantity = 1;
this.anims = [];
this.randomAnim = true;
this.animQuantity = 1;
this.dead = [];
this.alive = [];
this.counters = new Float32Array(10);
this.skipping = false;
this.worldMatrix = new TransformMatrix();
this.sortProperty = "";
this.sortOrderAsc = true;
this.sortCallback = this.depthSortCallback;
this.processors = new List(this);
this.tintFill = false;
this.initPipeline();
this.initPostPipeline();
this.setPosition(x, y);
this.setTexture(texture);
if (config) {
this.setConfig(config);
}
},
// Overrides Game Object method
addedToScene: function() {
this.scene.sys.updateList.add(this);
},
// Overrides Game Object method
removedFromScene: function() {
this.scene.sys.updateList.remove(this);
},
/**
* Takes an Emitter Configuration file and resets this Emitter, using any
* properties defined in the config to then set it up again.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#setConfig
* @since 3.60.0
*
* @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig} config - Settings for this emitter.
*
* @return {this} This Particle Emitter.
*/
setConfig: function(config) {
if (!config) {
return this;
}
this.config = config;
var i = 0;
var key = "";
var ops = this.ops;
for (i = 0; i < configOpMap.length; i++) {
key = configOpMap[i];
ops[key].loadConfig(config);
}
for (i = 0; i < configFastMap.length; i++) {
key = configFastMap[i];
if (HasValue(config, key)) {
this[key] = GetFastValue(config, key);
}
}
this.acceleration = this.accelerationX !== 0 || this.accelerationY !== 0;
this.moveTo = this.moveToX !== 0 && this.moveToY !== 0;
if (HasValue(config, "speed")) {
ops.speedX.loadConfig(config, "speed");
ops.speedY.active = false;
}
if (HasAny(config, ["speedX", "speedY"]) || this.moveTo) {
this.radial = false;
}
if (HasValue(config, "scale")) {
ops.scaleX.loadConfig(config, "scale");
ops.scaleY.active = false;
}
if (HasValue(config, "callbackScope")) {
var callbackScope = GetFastValue(config, "callbackScope", null);
this.emitCallbackScope = callbackScope;
this.deathCallbackScope = callbackScope;
}
if (HasValue(config, "emitZone")) {
this.addEmitZone(config.emitZone);
}
if (HasValue(config, "deathZone")) {
this.addDeathZone(config.deathZone);
}
if (HasValue(config, "bounds")) {
var bounds = this.addParticleBounds(config.bounds);
bounds.collideLeft = GetFastValue(config, "collideLeft", true);
bounds.collideRight = GetFastValue(config, "collideRight", true);
bounds.collideTop = GetFastValue(config, "collideTop", true);
bounds.collideBottom = GetFastValue(config, "collideBottom", true);
}
if (HasValue(config, "followOffset")) {
this.followOffset.setFromObject(GetFastValue(config, "followOffset", 0));
}
if (HasValue(config, "texture")) {
this.setTexture(config.texture);
}
if (HasValue(config, "frame")) {
this.setEmitterFrame(config.frame);
} else if (HasValue(config, "anim")) {
this.setAnim(config.anim);
}
if (HasValue(config, "reserve")) {
this.reserve(config.reserve);
}
if (HasValue(config, "advance")) {
this.fastForward(config.advance);
}
this.resetCounters(this.frequency, this.emitting);
if (this.emitting) {
this.emit(Events.START, this);
}
return this;
},
/**
* Takes an existing Emitter Configuration file and updates this Emitter.
* Existing properties are overriden while new properties are added. The
* updated configuration is then passed to the `setConfig` method to reset
* the Emitter with the updated configuration.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#updateConfig
* @since 3.85.0
*
* @param {Phaser.Types.GameObjects.Particles.ParticleEmitterConfig} config - Settings for this emitter.
*
* @return {this} This Particle Emitter.
*/
updateConfig: function(config) {
if (config) {
if (!this.config) {
this.setConfig(config);
} else {
this.setConfig(MergeRight(this.config, config));
}
}
return this;
},
/**
* Creates a description of this emitter suitable for JSON serialization.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#toJSON
* @since 3.0.0
*
* @return {Phaser.Types.GameObjects.JSONGameObject} A JSON representation of the Game Object.
*/
toJSON: function() {
var output = ComponentsToJSON(this);
var i = 0;
var key = "";
for (i = 0; i < configFastMap.length; i++) {
key = configFastMap[i];
output[key] = this[key];
}
var ops = this.ops;
for (i = 0; i < configOpMap.length; i++) {
key = configOpMap[i];
if (ops[key]) {
output[key] = ops[key].toJSON();
}
}
if (!ops.speedY.active) {
delete output.speedX;
output.speed = ops.speedX.toJSON();
}
if (this.scaleX === this.scaleY) {
delete output.scaleX;
delete output.scaleY;
output.scale = ops.scaleX.toJSON();
}
return output;
},
/**
* Resets the internal counter trackers.
*
* You shouldn't ever need to call this directly.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#resetCounters
* @since 3.60.0
*
* @param {number} frequency - The frequency counter.
* @param {boolean} on - Set the complete flag.
*/
resetCounters: function(frequency, on) {
var counters = this.counters;
counters.fill(0);
counters[0] = frequency;
if (on) {
counters[5] = 1;
}
},
/**
* Continuously moves the particle origin to follow a Game Object's position.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#startFollow
* @since 3.0.0
*
* @param {Phaser.Types.Math.Vector2Like} target - The Object to follow.
* @param {number} [offsetX=0] - Horizontal offset of the particle origin from the Game Object.
* @param {number} [offsetY=0] - Vertical offset of the particle origin from the Game Object.
* @param {boolean} [trackVisible=false] - Whether the emitter's visible state will track the target's visible state.
*
* @return {this} This Particle Emitter.
*/
startFollow: function(target, offsetX, offsetY, trackVisible) {
if (offsetX === void 0) {
offsetX = 0;
}
if (offsetY === void 0) {
offsetY = 0;
}
if (trackVisible === void 0) {
trackVisible = false;
}
this.follow = target;
this.followOffset.set(offsetX, offsetY);
this.trackVisible = trackVisible;
return this;
},
/**
* Stops following a Game Object.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#stopFollow
* @since 3.0.0
*
* @return {this} This Particle Emitter.
*/
stopFollow: function() {
this.follow = null;
this.followOffset.set(0, 0);
this.trackVisible = false;
return this;
},
/**
* Chooses a texture frame from {@link Phaser.GameObjects.Particles.ParticleEmitter#frames}.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#getFrame
* @since 3.0.0
*
* @return {Phaser.Textures.Frame} The texture frame.
*/
getFrame: function() {
var frames = this.frames;
var len = frames.length;
var current;
if (len === 1) {
current = frames[0];
} else if (this.randomFrame) {
current = GetRandom(frames);
} else {
current = frames[this.currentFrame];
this.frameCounter++;
if (this.frameCounter === this.frameQuantity) {
this.frameCounter = 0;
this.currentFrame++;
if (this.currentFrame === len) {
this.currentFrame = 0;
}
}
}
return this.texture.get(current);
},
/**
* Sets a pattern for assigning texture frames to emitted particles. The `frames` configuration can be any of:
*
* frame: 0
* frame: 'red'
* frame: [ 0, 1, 2, 3 ]
* frame: [ 'red', 'green', 'blue', 'pink', 'white' ]
* frame: { frames: [ 'red', 'green', 'blue', 'pink', 'white' ], [cycle: bool], [quantity: int] }
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#setEmitterFrame
* @since 3.0.0
*
* @param {(array|string|number|Phaser.Types.GameObjects.Particles.ParticleEmitterFrameConfig)} frames - One or more texture frames, or a configuration object.
* @param {boolean} [pickRandom=true] - Whether frames should be assigned at random from `frames`.
* @param {number} [quantity=1] - The number of consecutive particles that will receive each frame.
*
* @return {this} This Particle Emitter.
*/
setEmitterFrame: function(frames, pickRandom, quantity) {
if (pickRandom === void 0) {
pickRandom = true;
}
if (quantity === void 0) {
quantity = 1;
}
this.randomFrame = pickRandom;
this.frameQuantity = quantity;
this.currentFrame = 0;
var t = typeof frames;
this.frames.length = 0;
if (Array.isArray(frames)) {
this.frames = this.frames.concat(frames);
} else if (t === "string" || t === "number") {
this.frames.push(frames);
} else if (t === "object") {
var frameConfig = frames;
frames = GetFastValue(frameConfig, "frames", null);
if (frames) {
this.frames = this.frames.concat(frames);
}
var isCycle = GetFastValue(frameConfig, "cycle", false);
this.randomFrame = isCycle ? false : true;
this.frameQuantity = GetFastValue(frameConfig, "quantity", quantity);
}
if (this.frames.length === 1) {
this.frameQuantity = 1;
this.randomFrame = false;
}
return this;
},
/**
* Chooses an animation from {@link Phaser.GameObjects.Particles.ParticleEmitter#anims}, if populated.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#getAnim
* @since 3.60.0
*
* @return {string} The animation to play, or `null` if there aren't any.
*/
getAnim: function() {
var anims = this.anims;
var len = anims.length;
if (len === 0) {
return null;
} else if (len === 1) {
return anims[0];
} else if (this.randomAnim) {
return GetRandom(anims);
} else {
var anim = anims[this.currentAnim];
this.animCounter++;
if (this.animCounter >= this.animQuantity) {
this.animCounter = 0;
this.currentAnim = Wrap(this.currentAnim + 1, 0, len);
}
return anim;
}
},
/**
* Sets a pattern for assigning animations to emitted particles. The `anims` configuration can be any of:
*
* anim: 'red'
* anim: [ 'red', 'green', 'blue', 'pink', 'white' ]
* anim: { anims: [ 'red', 'green', 'blue', 'pink', 'white' ], [cycle: bool], [quantity: int] }
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#setAnim
* @since 3.60.0
*
* @param {(string|string[]|Phaser.Types.GameObjects.Particles.ParticleEmitterAnimConfig)} anims - One or more animations, or a configuration object.
* @param {boolean} [pickRandom=true] - Whether animations should be assigned at random from `anims`. If a config object is given, this parameter is ignored.
* @param {number} [quantity=1] - The number of consecutive particles that will receive each animation. If a config object is given, this parameter is ignored.
*
* @return {this} This Particle Emitter.
*/
setAnim: function(anims, pickRandom, quantity) {
if (pickRandom === void 0) {
pickRandom = true;
}
if (quantity === void 0) {
quantity = 1;
}
this.randomAnim = pickRandom;
this.animQuantity = quantity;
this.currentAnim = 0;
var t = typeof anims;
this.anims.length = 0;
if (Array.isArray(anims)) {
this.anims = this.anims.concat(anims);
} else if (t === "string") {
this.anims.push(anims);
} else if (t === "object") {
var animConfig = anims;
anims = GetFastValue(animConfig, "anims", null);
if (anims) {
this.anims = this.anims.concat(anims);
}
var isCycle = GetFastValue(animConfig, "cycle", false);
this.randomAnim = isCycle ? false : true;
this.animQuantity = GetFastValue(animConfig, "quantity", quantity);
}
if (this.anims.length === 1) {
this.animQuantity = 1;
this.randomAnim = false;
}
return this;
},
/**
* Turns {@link Phaser.GameObjects.Particles.ParticleEmitter#radial} particle movement on or off.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#setRadial
* @since 3.0.0
*
* @param {boolean} [value=true] - Radial mode (true) or point mode (true).
*
* @return {this} This Particle Emitter.
*/
setRadial: function(value) {
if (value === void 0) {
value = true;
}
this.radial = value;
return this;
},
/**
* Creates a Particle Bounds processor and adds it to this Emitter.
*
* This processor will check to see if any of the active Particles hit
* the defined boundary, as specified by a Rectangle shape in world-space.
*
* If so, they are 'rebounded' back again by having their velocity adjusted.
*
* The strength of the rebound is controlled by the `Particle.bounce`
* property.
*
* You should be careful to ensure that you emit particles within a bounds,
* if set, otherwise it will lead to unpredictable visual results as the
* particles are hastily repositioned.
*
* The Particle Bounds processor is returned from this method. If you wish
* to modify the area you can directly change its `bounds` property, along
* with the `collideLeft` etc values.
*
* To disable the bounds you can either set its `active` property to `false`,
* or if you no longer require it, call `ParticleEmitter.removeParticleProcessor`.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#addParticleBounds
* @since 3.60.0
*
* @param {(number|Phaser.Types.GameObjects.Particles.ParticleEmitterBounds|Phaser.Types.GameObjects.Particles.ParticleEmitterBoundsAlt)} x - The x-coordinate of the left edge of the boundary, or an object representing a rectangle.
* @param {number} [y] - The y-coordinate of the top edge of the boundary.
* @param {number} [width] - The width of the boundary.
* @param {number} [height] - The height of the boundary.
* @param {boolean} [collideLeft=true] - Whether particles interact with the left edge of the bounds.
* @param {boolean} [collideRight=true] - Whether particles interact with the right edge of the bounds.
* @param {boolean} [collideTop=true] - Whether particles interact with the top edge of the bounds.
* @param {boolean} [collideBottom=true] - Whether particles interact with the bottom edge of the bounds.
*
* @return {Phaser.GameObjects.Particles.ParticleBounds} The Particle Bounds processor.
*/
addParticleBounds: function(x, y, width, height, collideLeft, collideRight, collideTop, collideBottom) {
if (typeof x === "object") {
var obj = x;
x = obj.x;
y = obj.y;
width = HasValue(obj, "w") ? obj.w : obj.width;
height = HasValue(obj, "h") ? obj.h : obj.height;
}
return this.addParticleProcessor(new ParticleBounds(x, y, width, height, collideLeft, collideRight, collideTop, collideBottom));
},
/**
* Sets the initial radial speed of emitted particles.
*
* Changes the emitter to radial mode.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#setParticleSpeed
* @since 3.60.0
*
* @param {number} x - The horizontal speed of the emitted Particles.
* @param {number} [y=x] - The vertical speed of emitted Particles. If not set it will use the `x` value.
*
* @return {this} This Particle Emitter.
*/
setParticleSpeed: function(x, y) {
if (y === void 0) {
y = x;
}
this.ops.speedX.onChange(x);
if (x === y) {
this.ops.speedY.active = false;
} else {
this.ops.speedY.onChange(y);
}
this.radial = true;
return this;
},
/**
* Sets the vertical and horizontal scale of the emitted particles.
*
* You can also set the scale of the entire emitter via `setScale`.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#setParticleScale
* @since 3.60.0
*
* @param {number} [x=1] - The horizontal scale of the emitted Particles.
* @param {number} [y=x] - The vertical scale of emitted Particles. If not set it will use the `x` value.
*
* @return {this} This Particle Emitter.
*/
setParticleScale: function(x, y) {
if (x === void 0) {
x = 1;
}
if (y === void 0) {
y = x;
}
this.ops.scaleX.onChange(x);
this.ops.scaleY.onChange(y);
return this;
},
/**
* Sets the gravity applied to emitted particles.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#setParticleGravity
* @since 3.60.0
*
* @param {number} x - Horizontal acceleration due to gravity, in pixels per second squared. Set to zero for no gravity.
* @param {number} y - Vertical acceleration due to gravity, in pixels per second squared. Set to zero for no gravity.
*
* @return {this} This Particle Emitter.
*/
setParticleGravity: function(x, y) {
this.gravityX = x;
this.gravityY = y;
return this;
},
/**
* Sets the opacity (alpha) of emitted particles.
*
* You can also set the alpha of the entire emitter via `setAlpha`.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#setParticleAlpha
* @since 3.60.0
*
* @param {(Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType|Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType)} value - A value between 0 (transparent) and 1 (opaque).
*
* @return {this} This Particle Emitter.
*/
setParticleAlpha: function(value) {
this.ops.alpha.onChange(value);
return this;
},
/**
* Sets the color tint of emitted particles.
*
* This is a WebGL only feature.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#setParticleTint
* @since 3.60.0
* @webglOnly
*
* @param {(Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType|Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType)} value - A value between 0 and 0xffffff.
*
* @return {this} This Particle Emitter.
*/
setParticleTint: function(value) {
this.ops.tint.onChange(value);
return this;
},
/**
* Sets the angle of a {@link Phaser.GameObjects.Particles.ParticleEmitter#radial} particle stream.
*
* The value is given in degrees using Phaser's right-handed coordinate system.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#setEmitterAngle
* @since 3.0.0
*
* @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The angle of the initial velocity of emitted particles, in degrees.
*
* @return {this} This Particle Emitter.
*/
setEmitterAngle: function(value) {
this.ops.angle.onChange(value);
return this;
},
/**
* Sets the lifespan of newly emitted particles in milliseconds.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#setParticleLifespan
* @since 3.60.0
*
* @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} value - The lifespan of a particle, in ms.
*
* @return {this} This Particle Emitter.
*/
setParticleLifespan: function(value) {
this.ops.lifespan.onChange(value);
return this;
},
/**
* Sets the number of particles released at each flow cycle or explosion.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#setQuantity
* @since 3.0.0
*
* @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} quantity - The number of particles to release at each flow cycle or explosion.
*
* @return {this} This Particle Emitter.
*/
setQuantity: function(quantity) {
this.quantity = quantity;
return this;
},
/**
* Sets the emitter's {@link Phaser.GameObjects.Particles.ParticleEmitter#frequency}
* and {@link Phaser.GameObjects.Particles.ParticleEmitter#quantity}.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#setFrequency
* @since 3.0.0
*
* @param {number} frequency - The time interval (>= 0) of each flow cycle, in ms; or -1 to put the emitter in explosion mode.
* @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} [quantity] - The number of particles to release at each flow cycle or explosion.
*
* @return {this} This Particle Emitter.
*/
setFrequency: function(frequency, quantity) {
this.frequency = frequency;
this.flowCounter = frequency > 0 ? frequency : 0;
if (quantity) {
this.quantity = quantity;
}
return this;
},
/**
* Adds a new Particle Death Zone to this Emitter.
*
* A particle is immediately killed as soon as its x/y coordinates intersect
* with any of the configured Death Zones.
*
* The `source` can be a Geometry Shape, such as a Circle, Rectangle or Triangle.
* Any valid object from the `Phaser.Geometry` namespace is allowed, as long as
* it supports a `contains` function. You can set the `type` to be either `onEnter`
* or `onLeave`.
*
* A single Death Zone instance can only exist once within this Emitter, but can belong
* to multiple Emitters.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#addDeathZone
* @since 3.60.0
*
* @param {Phaser.Types.GameObjects.Particles.DeathZoneObject|Phaser.Types.GameObjects.Particles.DeathZoneObject[]} config - A Death Zone configuration object, a Death Zone instance, a valid Geometry object or an array of them.
*
* @return {Phaser.GameObjects.Particles.Zones.DeathZone[]} An array of the Death Zones that were added to this Emitter.
*/
addDeathZone: function(config) {
if (!Array.isArray(config)) {
config = [config];
}
var zone;
var output = [];
for (var i = 0; i < config.length; i++) {
zone = config[i];
if (zone instanceof DeathZone) {
output.push(zone);
} else if (typeof zone.contains === "function") {
zone = new DeathZone(zone, true);
output.push(zone);
} else {
var type = GetFastValue(zone, "type", "onEnter");
var source = GetFastValue(zone, "source", null);
if (source && typeof source.contains === "function") {
var killOnEnter = type === "onEnter" ? true : false;
zone = new DeathZone(source, killOnEnter);
output.push(zone);
}
}
}
this.deathZones = this.deathZones.concat(output);
return output;
},
/**
* Removes the given Particle Death Zone from this Emitter.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#removeDeathZone
* @since 3.60.0
*
* @param {Phaser.GameObjects.Particles.Zones.DeathZone} zone - The Death Zone that should be removed from this Emitter.
*
* @return {this} This Particle Emitter.
*/
removeDeathZone: function(zone) {
Remove(this.deathZones, zone);
return this;
},
/**
* Clear all Death Zones from this Particle Emitter.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#clearDeathZones
* @since 3.70.0
*
* @return {this} This Particle Emitter.
*/
clearDeathZones: function() {
this.deathZones.length = 0;
return this;
},
/**
* Adds a new Particle Emission Zone to this Emitter.
*
* An {@link Phaser.Types.GameObjects.Particles.ParticleEmitterEdgeZoneConfig EdgeZone} places particles on its edges.
* Its {@link Phaser.Types.GameObjects.Particles.EdgeZoneSource source} can be a Curve, Path, Circle, Ellipse, Line, Polygon, Rectangle, or Triangle;
* or any object with a suitable {@link Phaser.Types.GameObjects.Particles.EdgeZoneSourceCallback getPoints} method.
*
* A {@link Phaser.Types.GameObjects.Particles.ParticleEmitterRandomZoneConfig RandomZone} places the particles randomly within its interior.
* Its {@link Phaser.GameObjects.Particles.Zones.RandomZone#source source} can be a Circle, Ellipse, Line, Polygon, Rectangle, or Triangle; or any object with a suitable {@link Phaser.Types.GameObjects.Particles.RandomZoneSourceCallback getRandomPoint} method.
*
* An Emission Zone can only exist once within this Emitter.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#addEmitZone
* @since 3.60.0
*
* @param {Phaser.Types.GameObjects.Particles.EmitZoneData|Phaser.Types.GameObjects.Particles.EmitZoneData[]} zone - An Emission Zone configuration object, a RandomZone or EdgeZone instance, or an array of them.
*
* @return {Phaser.Types.GameObjects.Particles.EmitZoneObject[]} An array of the Emission Zones that were added to this Emitter.
*/
addEmitZone: function(config) {
if (!Array.isArray(config)) {
config = [config];
}
var zone;
var output = [];
for (var i = 0; i < config.length; i++) {
zone = config[i];
if (zone instanceof RandomZone || zone instanceof EdgeZone) {
output.push(zone);
} else {
var source = GetFastValue(zone, "source", null);
if (source) {
var type = GetFastValue(zone, "type", "random");
if (type === "random" && typeof source.getRandomPoint === "function") {
zone = new RandomZone(source);
output.push(zone);
} else if (type === "edge" && typeof source.getPoints === "function") {
var quantity = GetFastValue(zone, "quantity", 1);
var stepRate = GetFastValue(zone, "stepRate", 0);
var yoyo = GetFastValue(zone, "yoyo", false);
var seamless = GetFastValue(zone, "seamless", true);
var total = GetFastValue(zone, "total", -1);
zone = new EdgeZone(source, quantity, stepRate, yoyo, seamless, total);
output.push(zone);
}
}
}
}
this.emitZones = this.emitZones.concat(output);
return output;
},
/**
* Removes the given Particle Emission Zone from this Emitter.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#removeEmitZone
* @since 3.60.0
*
* @param {Phaser.GameObjects.Particles.Zones.EdgeZone|Phaser.GameObjects.Particles.Zones.RandomZone} zone - The Emission Zone that should be removed from this Emitter.
*
* @return {this} This Particle Emitter.
*/
removeEmitZone: function(zone) {
Remove(this.emitZones, zone);
this.zoneIndex = 0;
return this;
},
/**
* Clear all Emission Zones from this Particle Emitter.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#clearEmitZones
* @since 3.70.0
*
* @return {this} This Particle Emitter.
*/
clearEmitZones: function() {
this.emitZones.length = 0;
this.zoneIndex = 0;
return this;
},
/**
* Takes the given particle and sets its x/y coordinates to match the next available
* emission zone, if any have been configured. This method is called automatically
* as part of the `Particle.fire` process.
*
* The Emit Zones are iterated in sequence. Once a zone has had a particle emitted
* from it, then the next zone is used and so on, in a loop.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#getEmitZone
* @since 3.60.0
*
* @param {Phaser.GameObjects.Particles.Particle} particle - The particle to set the emission zone for.
*/
getEmitZone: function(particle) {
var zones = this.emitZones;
var len = zones.length;
if (len === 0) {
return;
} else {
var zone = zones[this.zoneIndex];
zone.getPoint(particle);
if (zone.total > -1) {
this.zoneTotal++;
if (this.zoneTotal === zone.total) {
this.zoneTotal = 0;
this.zoneIndex++;
if (this.zoneIndex === len) {
this.zoneIndex = 0;
}
}
}
}
},
/**
* Takes the given particle and checks to see if any of the configured Death Zones
* will kill it and returns the result. This method is called automatically as part
* of the `Particle.update` process.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#getDeathZone
* @fires Phaser.GameObjects.Particles.Events#DEATH_ZONE
* @since 3.60.0
*
* @param {Phaser.GameObjects.Particles.Particle} particle - The particle to test against the Death Zones.
*
* @return {boolean} `true` if the particle should be killed, otherwise `false`.
*/
getDeathZone: function(particle) {
var zones = this.deathZones;
for (var i = 0; i < zones.length; i++) {
var zone = zones[i];
if (zone.willKill(particle)) {
this.emit(Events.DEATH_ZONE, this, particle, zone);
return true;
}
}
return false;
},
/**
* Changes the currently active Emission Zone. The zones should have already
* been added to this Emitter either via the emitter config, or the
* `addEmitZone` method.
*
* Call this method by passing either a numeric zone index value, or
* the zone instance itself.
*
* Prior to v3.60 an Emitter could only have a single Emit Zone and this
* method was how you set it. From 3.60 and up it now performs a different
* function and swaps between all available active zones.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#setEmitZone
* @since 3.0.0
*
* @param {number|Phaser.GameObjects.Particles.Zones.EdgeZone|Phaser.GameObjects.Particles.Zones.RandomZone} zone - The Emit Zone to set as the active zone.
*
* @return {this} This Particle Emitter.
*/
setEmitZone: function(zone) {
var index;
if (isFinite(zone)) {
index = zone;
} else {
index = this.emitZones.indexOf(zone);
}
if (index >= 0) {
this.zoneIndex = index;
}
return this;
},
/**
* Adds a Particle Processor, such as a Gravity Well, to this Emitter.
*
* It will start processing particles from the next update as long as its `active`
* property is set.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#addParticleProcessor
* @since 3.60.0
*
* @generic {Phaser.GameObjects.Particles.ParticleProcessor} T
* @param {T} processor - The Particle Processor to add to this Emitter Manager.
*
* @return {T} The Particle Processor that was added to this Emitter Manager.
*/
addParticleProcessor: function(processor) {
if (!this.processors.exists(processor)) {
if (processor.emitter) {
processor.emitter.removeParticleProcessor(processor);
}
this.processors.add(processor);
processor.emitter = this;
}
return processor;
},
/**
* Removes a Particle Processor from this Emitter.
*
* The Processor must belong to this Emitter to be removed.
*
* It is not destroyed when removed, allowing you to move it to another Emitter Manager,
* so if you no longer require it you should call its `destroy` method directly.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#removeParticleProcessor
* @since 3.60.0
*
* @generic {Phaser.GameObjects.Particles.ParticleProcessor} T
* @param {T} processor - The Particle Processor to remove from this Emitter Manager.
*
* @return {?T} The Particle Processor that was removed, or null if it could not be found.
*/
removeParticleProcessor: function(processor) {
if (this.processors.exists(processor)) {
this.processors.remove(processor, true);
processor.emitter = null;
}
return processor;
},
/**
* Gets all active Particle Processors.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#getProcessors
* @since 3.60.0
*
* @return {Phaser.GameObjects.Particles.ParticleProcessor[]} - An array of active Particle Processors.
*/
getProcessors: function() {
return this.processors.getAll("active", true);
},
/**
* Creates a new Gravity Well, adds it to this Emitter and returns a reference to it.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#createGravityWell
* @since 3.60.0
*
* @param {Phaser.Types.GameObjects.Particles.GravityWellConfig} config - Configuration settings for the Gravity Well to create.
*
* @return {Phaser.GameObjects.Particles.GravityWell} The Gravity Well that was created.
*/
createGravityWell: function(config) {
return this.addParticleProcessor(new GravityWell(config));
},
/**
* Creates inactive particles and adds them to this emitter's pool.
*
* If `ParticleEmitter.maxParticles` is set it will limit the
* value passed to this method to make sure it's not exceeded.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#reserve
* @since 3.0.0
*
* @param {number} count - The number of particles to create.
*
* @return {this} This Particle Emitter.
*/
reserve: function(count) {
var dead = this.dead;
if (this.maxParticles > 0) {
var total = this.getParticleCount();
if (total + count > this.maxParticles) {
count = this.maxParticles - (total + count);
}
}
for (var i = 0; i < count; i++) {
dead.push(new this.particleClass(this));
}
return this;
},
/**
* Gets the number of active (in-use) particles in this emitter.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#getAliveParticleCount
* @since 3.0.0
*
* @return {number} The number of particles with `active=true`.
*/
getAliveParticleCount: function() {
return this.alive.length;
},
/**
* Gets the number of inactive (available) particles in this emitter.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#getDeadParticleCount
* @since 3.0.0
*
* @return {number} The number of particles with `active=false`.
*/
getDeadParticleCount: function() {
return this.dead.length;
},
/**
* Gets the total number of particles in this emitter.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#getParticleCount
* @since 3.0.0
*
* @return {number} The number of particles, including both alive and dead.
*/
getParticleCount: function() {
return this.getAliveParticleCount() + this.getDeadParticleCount();
},
/**
* Whether this emitter is at either its hard-cap limit (maxParticles), if set, or
* the max allowed number of 'alive' particles (maxAliveParticles).
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#atLimit
* @since 3.0.0
*
* @return {boolean} Returns `true` if this Emitter is at its limit, or `false` if no limit, or below the `maxParticles` level.
*/
atLimit: function() {
if (this.maxParticles > 0 && this.getParticleCount() >= this.maxParticles) {
return true;
}
return this.maxAliveParticles > 0 && this.getAliveParticleCount() >= this.maxAliveParticles;
},
/**
* Sets a function to call for each newly emitted particle.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#onParticleEmit
* @since 3.0.0
*
* @param {Phaser.Types.GameObjects.Particles.ParticleEmitterCallback} callback - The function.
* @param {*} [context] - The calling context.
*
* @return {this} This Particle Emitter.
*/
onParticleEmit: function(callback, context) {
if (callback === void 0) {
this.emitCallback = null;
this.emitCallbackScope = null;
} else if (typeof callback === "function") {
this.emitCallback = callback;
if (context) {
this.emitCallbackScope = context;
}
}
return this;
},
/**
* Sets a function to call for each particle death.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#onParticleDeath
* @since 3.0.0
*
* @param {Phaser.Types.GameObjects.Particles.ParticleDeathCallback} callback - The function.
* @param {*} [context] - The function's calling context.
*
* @return {this} This Particle Emitter.
*/
onParticleDeath: function(callback, context) {
if (callback === void 0) {
this.deathCallback = null;
this.deathCallbackScope = null;
} else if (typeof callback === "function") {
this.deathCallback = callback;
if (context) {
this.deathCallbackScope = context;
}
}
return this;
},
/**
* Deactivates every particle in this emitter immediately.
*
* This particles are killed but do not emit an event or callback.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#killAll
* @since 3.0.0
*
* @return {this} This Particle Emitter.
*/
killAll: function() {
var dead = this.dead;
var alive = this.alive;
while (alive.length > 0) {
dead.push(alive.pop());
}
return this;
},
/**
* Calls a function for each active particle in this emitter. The function is
* sent two parameters: a reference to the Particle instance and to this Emitter.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#forEachAlive
* @since 3.0.0
*
* @param {Phaser.Types.GameObjects.Particles.ParticleEmitterCallback} callback - The function.
* @param {*} context - The functions calling context.
*
* @return {this} This Particle Emitter.
*/
forEachAlive: function(callback, context) {
var alive = this.alive;
var length = alive.length;
for (var i = 0; i < length; i++) {
callback.call(context, alive[i], this);
}
return this;
},
/**
* Calls a function for each inactive particle in this emitter.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#forEachDead
* @since 3.0.0
*
* @param {Phaser.Types.GameObjects.Particles.ParticleEmitterCallback} callback - The function.
* @param {*} context - The functions calling context.
*
* @return {this} This Particle Emitter.
*/
forEachDead: function(callback, context) {
var dead = this.dead;
var length = dead.length;
for (var i = 0; i < length; i++) {
callback.call(context, dead[i], this);
}
return this;
},
/**
* Turns {@link Phaser.GameObjects.Particles.ParticleEmitter#on} the emitter and resets the flow counter.
*
* If this emitter is in flow mode (frequency >= 0; the default), the particle flow will start (or restart).
*
* If this emitter is in explode mode (frequency = -1), nothing will happen.
* Use {@link Phaser.GameObjects.Particles.ParticleEmitter#explode} or {@link Phaser.GameObjects.Particles.ParticleEmitter#flow} instead.
*
* Calling this method will emit the `START` event.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#start
* @fires Phaser.GameObjects.Particles.Events#START
* @since 3.0.0
*
* @param {number} [advance=0] - Advance this number of ms in time through the emitter.
* @param {number} [duration=0] - Limit this emitter to only emit particles for the given number of ms. Setting this parameter will override any duration already set in the Emitter configuration object.
*
* @return {this} This Particle Emitter.
*/
start: function(advance, duration) {
if (advance === void 0) {
advance = 0;
}
if (!this.emitting) {
if (advance > 0) {
this.fastForward(advance);
}
this.emitting = true;
this.resetCounters(this.frequency, true);
if (duration !== void 0) {
this.duration = Math.abs(duration);
}
this.emit(Events.START, this);
}
return this;
},
/**
* Turns {@link Phaser.GameObjects.Particles.ParticleEmitter#emitting off} the emitter and
* stops it from emitting further particles. Currently alive particles will remain
* active until they naturally expire unless you set the `kill` parameter to `true`.
*
* Calling this method will emit the `STOP` event. When the final particle has
* expired the `COMPLETE` event will be emitted.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#stop
* @fires Phaser.GameObjects.Particles.Events#STOP
* @since 3.11.0
*
* @param {boolean} [kill=false] - Kill all particles immediately (true), or leave them to die after their lifespan expires? (false, the default)
*
* @return {this} This Particle Emitter.
*/
stop: function(kill) {
if (kill === void 0) {
kill = false;
}
if (this.emitting) {
this.emitting = false;
if (kill) {
this.killAll();
}
this.emit(Events.STOP, this);
}
return this;
},
/**
* {@link Phaser.GameObjects.Particles.ParticleEmitter#active Deactivates} the emitter.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#pause
* @since 3.0.0
*
* @return {this} This Particle Emitter.
*/
pause: function() {
this.active = false;
return this;
},
/**
* {@link Phaser.GameObjects.Particles.ParticleEmitter#active Activates} the emitter.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#resume
* @since 3.0.0
*
* @return {this} This Particle Emitter.
*/
resume: function() {
this.active = true;
return this;
},
/**
* Set the property by which active particles are sorted prior to be rendered.
*
* It allows you to control the rendering order of the particles.
*
* This can be any valid property of the `Particle` class, such as `y`, `alpha`
* or `lifeT`.
*
* The 'alive' particles array is sorted in place each game frame. Setting a
* sort property will override the `particleBringToTop` setting.
*
* If you wish to use your own sorting function, see `setSortCallback` instead.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#setSortProperty
* @since 3.60.0
*
* @param {string} [property] - The property on the `Particle` class to sort by.
* @param {boolean} [ascending=true] - Should the particles be sorted in ascending or descending order?
*
* @return {this} This Particle Emitter.
*/
setSortProperty: function(property, ascending) {
if (property === void 0) {
property = "";
}
if (ascending === void 0) {
ascending = this.true;
}
this.sortProperty = property;
this.sortOrderAsc = ascending;
this.sortCallback = this.depthSortCallback;
return this;
},
/**
* Sets a callback to be used to sort the particles before rendering each frame.
*
* This allows you to define your own logic and behavior in the callback.
*
* The callback will be sent two parameters: the two Particles being compared,
* and must adhere to the criteria of the `compareFn` in `Array.sort`:
*
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#description
*
* Call this method with no parameters to reset the sort callback.
*
* Setting your own callback will override both the `particleBringToTop` and
* `sortProperty` settings of this Emitter.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#setSortCallback
* @since 3.60.0
*
* @param {Phaser.Types.GameObjects.Particles.ParticleSortCallback} [callback] - The callback to invoke when the particles are sorted. Leave undefined to reset to the default.
*
* @return {this} This Particle Emitter.
*/
setSortCallback: function(callback) {
if (this.sortProperty !== "") {
callback = this.depthSortCallback;
} else {
callback = null;
}
this.sortCallback = callback;
return this;
},
/**
* Sorts active particles with {@link Phaser.GameObjects.Particles.ParticleEmitter#depthSortCallback}.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#depthSort
* @since 3.0.0
*
* @return {this} This Particle Emitter.
*/
depthSort: function() {
StableSort(this.alive, this.sortCallback.bind(this));
return this;
},
/**
* Calculates the difference of two particles, for sorting them by depth.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#depthSortCallback
* @since 3.0.0
*
* @param {object} a - The first particle.
* @param {object} b - The second particle.
*
* @return {number} The difference of a and b's y coordinates.
*/
depthSortCallback: function(a, b) {
var key = this.sortProperty;
if (this.sortOrderAsc) {
return a[key] - b[key];
} else {
return b[key] - a[key];
}
},
/**
* Puts the emitter in flow mode (frequency >= 0) and starts (or restarts) a particle flow.
*
* To resume a flow at the current frequency and quantity, use {@link Phaser.GameObjects.Particles.ParticleEmitter#start} instead.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#flow
* @fires Phaser.GameObjects.Particles.Events#START
* @since 3.0.0
*
* @param {number} frequency - The time interval (>= 0) of each flow cycle, in ms.
* @param {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType} [count=1] - The number of particles to emit at each flow cycle.
* @param {number} [stopAfter] - Stop this emitter from firing any more particles once this value is reached. Set to zero for unlimited. Setting this parameter will override any `stopAfter` value already set in the Emitter configuration object.
*
* @return {this} This Particle Emitter.
*/
flow: function(frequency, count, stopAfter) {
if (count === void 0) {
count = 1;
}
this.emitting = false;
this.frequency = frequency;
this.quantity = count;
if (stopAfter !== void 0) {
this.stopAfter = stopAfter;
}
return this.start();
},
/**
* Puts the emitter in explode mode (frequency = -1), stopping any current particle flow, and emits several particles all at once.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#explode
* @fires Phaser.GameObjects.Particles.Events#EXPLODE
* @since 3.0.0
*
* @param {number} [count=this.quantity] - The number of Particles to emit.
* @param {number} [x=this.x] - The x coordinate to emit the Particles from.
* @param {number} [y=this.x] - The y coordinate to emit the Particles from.
*
* @return {(Phaser.GameObjects.Particles.Particle|undefined)} The most recently emitted Particle, or `undefined` if the emitter is at its limit.
*/
explode: function(count, x, y) {
this.frequency = -1;
this.resetCounters(-1, true);
var particle = this.emitParticle(count, x, y);
this.emit(Events.EXPLODE, this, particle);
return particle;
},
/**
* Emits particles at the given position. If no position is given, it will
* emit from this Emitters current location.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#emitParticleAt
* @since 3.0.0
*
* @param {number} [x=this.x] - The x coordinate to emit the Particles from.
* @param {number} [y=this.x] - The y coordinate to emit the Particles from.
* @param {number} [count=this.quantity] - The number of Particles to emit.
*
* @return {(Phaser.GameObjects.Particles.Particle|undefined)} The most recently emitted Particle, or `undefined` if the emitter is at its limit.
*/
emitParticleAt: function(x, y, count) {
return this.emitParticle(count, x, y);
},
/**
* Emits particles at a given position (or the emitters current position).
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#emitParticle
* @since 3.0.0
*
* @param {number} [count=this.quantity] - The number of Particles to emit.
* @param {number} [x=this.x] - The x coordinate to emit the Particles from.
* @param {number} [y=this.x] - The y coordinate to emit the Particles from.
*
* @return {(Phaser.GameObjects.Particles.Particle|undefined)} The most recently emitted Particle, or `undefined` if the emitter is at its limit.
*
* @see Phaser.GameObjects.Particles.Particle#fire
*/
emitParticle: function(count, x, y) {
if (this.atLimit()) {
return;
}
if (count === void 0) {
count = this.ops.quantity.onEmit();
}
var dead = this.dead;
var stopAfter = this.stopAfter;
var followX = this.follow ? this.follow.x + this.followOffset.x : x;
var followY = this.follow ? this.follow.y + this.followOffset.y : y;
for (var i = 0; i < count; i++) {
var particle = dead.pop();
if (!particle) {
particle = new this.particleClass(this);
}
if (particle.fire(followX, followY)) {
if (this.particleBringToTop) {
this.alive.push(particle);
} else {
this.alive.unshift(particle);
}
if (this.emitCallback) {
this.emitCallback.call(this.emitCallbackScope, particle, this);
}
} else {
this.dead.push(particle);
}
if (stopAfter > 0) {
this.stopCounter++;
if (this.stopCounter >= stopAfter) {
break;
}
}
if (this.atLimit()) {
break;
}
}
return particle;
},
/**
* Fast forwards this Particle Emitter and all of its particles.
*
* Works by running the Emitter `preUpdate` handler in a loop until the `time`
* has been reached at `delta` steps per loop.
*
* All callbacks and emitter related events that would normally be fired
* will still be invoked.
*
* You can make an emitter 'fast forward' via the emitter config using the
* `advance` property. Set this value to the number of ms you wish the
* emitter to be fast-forwarded by. Or, call this method post-creation.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#fastForward
* @since 3.60.0
*
* @param {number} time - The number of ms to advance the Particle Emitter by.
* @param {number} [delta] - The amount of delta to use for each step. Defaults to 1000 / 60.
*
* @return {this} This Particle Emitter.
*/
fastForward: function(time, delta) {
if (delta === void 0) {
delta = 1e3 / 60;
}
var total = 0;
this.skipping = true;
while (total < Math.abs(time)) {
this.preUpdate(0, delta);
total += delta;
}
this.skipping = false;
return this;
},
/**
* Updates this emitter and its particles.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#preUpdate
* @fires Phaser.GameObjects.Particles.Events#COMPLETE
* @since 3.0.0
*
* @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout.
* @param {number} delta - The delta time, in ms, elapsed since the last frame.
*/
preUpdate: function(time, delta) {
delta *= this.timeScale;
var step = delta / 1e3;
if (this.trackVisible) {
this.visible = this.follow.visible;
}
this.getWorldTransformMatrix(this.worldMatrix);
var processors = this.getProcessors();
var particles = this.alive;
var dead = this.dead;
var i = 0;
var rip = [];
var length = particles.length;
for (i = 0; i < length; i++) {
var particle = particles[i];
if (particle.update(delta, step, processors)) {
rip.push({ index: i, particle });
}
}
length = rip.length;
if (length > 0) {
var deathCallback = this.deathCallback;
var deathCallbackScope = this.deathCallbackScope;
for (i = length - 1; i >= 0; i--) {
var entry = rip[i];
particles.splice(entry.index, 1);
dead.push(entry.particle);
if (deathCallback) {
deathCallback.call(deathCallbackScope, entry.particle);
}
entry.particle.setPosition();
}
}
if (!this.emitting && !this.skipping) {
if (this.completeFlag === 1 && particles.length === 0) {
this.completeFlag = 0;
this.emit(Events.COMPLETE, this);
}
return;
}
if (this.frequency === 0) {
this.emitParticle();
} else if (this.frequency > 0) {
this.flowCounter -= delta;
while (this.flowCounter <= 0) {
this.emitParticle();
this.flowCounter += this.frequency;
}
}
if (!this.skipping) {
if (this.duration > 0) {
this.elapsed += delta;
if (this.elapsed >= this.duration) {
this.stop();
}
}
if (this.stopAfter > 0 && this.stopCounter >= this.stopAfter) {
this.stop();
}
}
},
/**
* Takes either a Rectangle Geometry object or an Arcade Physics Body and tests
* to see if it intersects with any currently alive Particle in this Emitter.
*
* Overlapping particles are returned in an array, where you can perform further
* processing on them. If nothing overlaps then the array will be empty.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#overlap
* @since 3.60.0
*
* @param {(Phaser.Geom.Rectangle|Phaser.Physics.Arcade.Body)} target - A Rectangle or Arcade Physics Body to check for intersection against all alive particles.
*
* @return {Phaser.GameObjects.Particles.Particle[]} An array of Particles that overlap with the given target.
*/
overlap: function(target) {
var matrix = this.getWorldTransformMatrix();
var alive = this.alive;
var length = alive.length;
var output = [];
for (var i = 0; i < length; i++) {
var particle = alive[i];
if (RectangleToRectangle(target, particle.getBounds(matrix))) {
output.push(particle);
}
}
return output;
},
/**
* Returns a bounds Rectangle calculated from the bounds of all currently
* _active_ Particles in this Emitter. If this Emitter has only just been
* created and not yet rendered, then calling this method will return a Rectangle
* with a max safe integer for dimensions. Use the `advance` parameter to
* avoid this.
*
* Typically it takes a few seconds for a flow Emitter to 'warm up'. You can
* use the `advance` and `delta` parameters to force the Emitter to
* 'fast forward' in time to try and allow the bounds to be more accurate,
* as it will calculate the bounds based on the particle bounds across all
* timesteps, giving a better result.
*
* You can also use the `padding` parameter to increase the size of the
* bounds. Emitters with a lot of randomness in terms of direction or lifespan
* can often return a bounds smaller than their possible maximum. By using
* the `padding` (and `advance` if needed) you can help limit this.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#getBounds
* @since 3.60.0
*
* @param {number} [padding] - The amount of padding, in pixels, to add to the bounds Rectangle.
* @param {number} [advance] - The number of ms to advance the Particle Emitter by. Defaults to 0, i.e. not used.
* @param {number} [delta] - The amount of delta to use for each step. Defaults to 1000 / 60.
* @param {Phaser.Geom.Rectangle} [output] - The Rectangle to store the results in. If not given a new one will be created.
*
* @return {Phaser.Geom.Rectangle} A Rectangle containing the calculated bounds of this Emitter.
*/
getBounds: function(padding, advance, delta, output) {
if (padding === void 0) {
padding = 0;
}
if (advance === void 0) {
advance = 0;
}
if (delta === void 0) {
delta = 1e3 / 60;
}
if (output === void 0) {
output = new Rectangle();
}
var matrix = this.getWorldTransformMatrix();
var i;
var bounds;
var alive = this.alive;
var setFirst = false;
output.setTo(0, 0, 0, 0);
if (advance > 0) {
var total = 0;
this.skipping = true;
while (total < Math.abs(advance)) {
this.preUpdate(0, delta);
for (i = 0; i < alive.length; i++) {
bounds = alive[i].getBounds(matrix);
if (!setFirst) {
setFirst = true;
CopyFrom(bounds, output);
} else {
MergeRect(output, bounds);
}
}
total += delta;
}
this.skipping = false;
} else {
for (i = 0; i < alive.length; i++) {
bounds = alive[i].getBounds(matrix);
if (!setFirst) {
setFirst = true;
CopyFrom(bounds, output);
} else {
MergeRect(output, bounds);
}
}
}
if (padding > 0) {
Inflate(output, padding, padding);
}
return output;
},
/**
* Prints a warning to the console if you mistakenly call this function
* thinking it works the same way as Phaser v3.55.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#createEmitter
* @since 3.60.0
*/
createEmitter: function() {
throw new Error("createEmitter removed. See ParticleEmitter docs for info");
},
/**
* The x coordinate the particles are emitted from.
*
* This is relative to the Emitters x coordinate and that of any parent.
*
* Accessing this property should typically return a number.
* However, it can be set to any valid EmitterOp onEmit type.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#particleX
* @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType|Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType}
* @since 3.60.0
*/
particleX: {
get: function() {
return this.ops.x.current;
},
set: function(value) {
this.ops.x.onChange(value);
}
},
/**
* The y coordinate the particles are emitted from.
*
* This is relative to the Emitters x coordinate and that of any parent.
*
* Accessing this property should typically return a number.
* However, it can be set to any valid EmitterOp onEmit type.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#particleY
* @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType|Phaser.Types.GameObjects.Particles.EmitterOpOnUpdateType}
* @since 3.60.0
*/
particleY: {
get: function() {
return this.ops.y.current;
},
set: function(value) {
this.ops.y.onChange(value);
}
},
/**
* The horizontal acceleration applied to emitted particles, in pixels per second squared.
*
* Accessing this property should typically return a number.
* However, it can be set to any valid EmitterOp onEmit type.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#accelerationX
* @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType}
* @since 3.60.0
*/
accelerationX: {
get: function() {
return this.ops.accelerationX.current;
},
set: function(value) {
this.ops.accelerationX.onChange(value);
}
},
/**
* The vertical acceleration applied to emitted particles, in pixels per second squared.
*
* Accessing this property should typically return a number.
* However, it can be set to any valid EmitterOp onEmit type.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#accelerationY
* @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType}
* @since 3.60.0
*/
accelerationY: {
get: function() {
return this.ops.accelerationY.current;
},
set: function(value) {
this.ops.accelerationY.onChange(value);
}
},
/**
* The maximum horizontal velocity emitted particles can reach, in pixels per second squared.
*
* Accessing this property should typically return a number.
* However, it can be set to any valid EmitterOp onEmit type.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#maxVelocityX
* @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType}
* @since 3.60.0
* @default 10000
*/
maxVelocityX: {
get: function() {
return this.ops.maxVelocityX.current;
},
set: function(value) {
this.ops.maxVelocityX.onChange(value);
}
},
/**
* The maximum vertical velocity emitted particles can reach, in pixels per second squared.
*
* Accessing this property should typically return a number.
* However, it can be set to any valid EmitterOp onEmit type.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#maxVelocityY
* @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType}
* @since 3.60.0
* @default 10000
*/
maxVelocityY: {
get: function() {
return this.ops.maxVelocityY.current;
},
set: function(value) {
this.ops.maxVelocityY.onChange(value);
}
},
/**
* The initial speed of emitted particles, in pixels per second.
*
* If using this as a getter it will return the `speedX` value.
*
* If using it as a setter it will update both `speedX` and `speedY` to the
* given value.
*
* Accessing this property should typically return a number.
* However, it can be set to any valid EmitterOp onEmit type.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#speed
* @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType}
* @since 3.60.0
*/
speed: {
get: function() {
return this.ops.speedX.current;
},
set: function(value) {
this.ops.speedX.onChange(value);
this.ops.speedY.onChange(value);
}
},
/**
* The initial horizontal speed of emitted particles, in pixels per second.
*
* Accessing this property should typically return a number.
* However, it can be set to any valid EmitterOp onEmit type.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#speedX
* @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType}
* @since 3.60.0
*/
speedX: {
get: function() {
return this.ops.speedX.current;
},
set: function(value) {
this.ops.speedX.onChange(value);
}
},
/**
* The initial vertical speed of emitted particles, in pixels per second.
*
* Accessing this property should typically return a number.
* However, it can be set to any valid EmitterOp onEmit type.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#speedY
* @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType}
* @since 3.60.0
*/
speedY: {
get: function() {
return this.ops.speedY.current;
},
set: function(value) {
this.ops.speedY.onChange(value);
}
},
/**
* The x coordinate emitted particles move toward, when {@link Phaser.GameObjects.Particles.ParticleEmitter#moveTo} is true.
*
* Accessing this property should typically return a number.
* However, it can be set to any valid EmitterOp onEmit type.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#moveToX
* @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType}
* @since 3.60.0
*/
moveToX: {
get: function() {
return this.ops.moveToX.current;
},
set: function(value) {
this.ops.moveToX.onChange(value);
}
},
/**
* The y coordinate emitted particles move toward, when {@link Phaser.GameObjects.Particles.ParticleEmitter#moveTo} is true.
*
* Accessing this property should typically return a number.
* However, it can be set to any valid EmitterOp onEmit type.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#moveToY
* @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType}
* @since 3.60.0
*/
moveToY: {
get: function() {
return this.ops.moveToY.current;
},
set: function(value) {
this.ops.moveToY.onChange(value);
}
},
/**
* The amount of velocity particles will use when rebounding off the
* emitter bounds, if set. A value of 0 means no bounce. A value of 1
* means a full rebound.
*
* Accessing this property should typically return a number.
* However, it can be set to any valid EmitterOp onEmit type.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#bounce
* @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType}
* @since 3.60.0
*/
bounce: {
get: function() {
return this.ops.bounce.current;
},
set: function(value) {
this.ops.bounce.onChange(value);
}
},
/**
* The horizontal scale of emitted particles.
*
* This is relative to the Emitters scale and that of any parent.
*
* Accessing this property should typically return a number.
* However, it can be set to any valid EmitterOp onEmit type.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#particleScaleX
* @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType}
* @since 3.60.0
*/
particleScaleX: {
get: function() {
return this.ops.scaleX.current;
},
set: function(value) {
this.ops.scaleX.onChange(value);
}
},
/**
* The vertical scale of emitted particles.
*
* This is relative to the Emitters scale and that of any parent.
*
* Accessing this property should typically return a number.
* However, it can be set to any valid EmitterOp onEmit type.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#particleScaleY
* @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType}
* @since 3.60.0
*/
particleScaleY: {
get: function() {
return this.ops.scaleY.current;
},
set: function(value) {
this.ops.scaleY.onChange(value);
}
},
/**
* A color tint value that is applied to the texture of the emitted
* particle. The value should be given in hex format, i.e. 0xff0000
* for a red tint, and should not include the alpha channel.
*
* Tints are additive, meaning a tint value of white (0xffffff) will
* effectively reset the tint to nothing.
*
* Modify the `ParticleEmitter.tintFill` property to change between
* an additive and replacement tint mode.
*
* When you define the color via the Emitter config you should give
* it as an array of color values. The Particle will then interpolate
* through these colors over the course of its lifespan. Setting this
* will override any `tint` value that may also be given.
*
* This is a WebGL only feature.
*
* Accessing this property should typically return a number.
* However, it can be set to any valid EmitterOp onEmit type.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#particleColor
* @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType}
* @since 3.60.0
*/
particleColor: {
get: function() {
return this.ops.color.current;
},
set: function(value) {
this.ops.color.onChange(value);
}
},
/**
* Controls the easing function used when you have created an
* Emitter that uses the `color` property to interpolate the
* tint of Particles over their lifetime.
*
* Setting this has no effect if you haven't also applied a
* `particleColor` to this Emitter.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#colorEase
* @type {string}
* @since 3.60.0
*/
colorEase: {
get: function() {
return this.ops.color.easeName;
},
set: function(value) {
this.ops.color.setEase(value);
}
},
/**
* A color tint value that is applied to the texture of the emitted
* particle. The value should be given in hex format, i.e. 0xff0000
* for a red tint, and should not include the alpha channel.
*
* Tints are additive, meaning a tint value of white (0xffffff) will
* effectively reset the tint to nothing.
*
* Modify the `ParticleEmitter.tintFill` property to change between
* an additive and replacement tint mode.
*
* The `tint` value will be overriden if a `color` array is provided.
*
* This is a WebGL only feature.
*
* Accessing this property should typically return a number.
* However, it can be set to any valid EmitterOp onEmit type.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#particleTint
* @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType}
* @since 3.60.0
*/
particleTint: {
get: function() {
return this.ops.tint.current;
},
set: function(value) {
this.ops.tint.onChange(value);
}
},
/**
* The alpha value of the emitted particles. This is a value
* between 0 and 1. Particles with alpha zero are invisible
* and are therefore not rendered, but are still processed
* by the Emitter.
*
* Accessing this property should typically return a number.
* However, it can be set to any valid EmitterOp onEmit type.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#particleAlpha
* @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType}
* @since 3.60.0
*/
particleAlpha: {
get: function() {
return this.ops.alpha.current;
},
set: function(value) {
this.ops.alpha.onChange(value);
}
},
/**
* The lifespan of the emitted particles. This value is given
* in milliseconds and defaults to 1000ms (1 second). When a
* particle reaches this amount it is killed.
*
* Accessing this property should typically return a number.
* However, it can be set to any valid EmitterOp onEmit type.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#lifespan
* @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType}
* @since 3.60.0
*/
lifespan: {
get: function() {
return this.ops.lifespan.current;
},
set: function(value) {
this.ops.lifespan.onChange(value);
}
},
/**
* The angle at which the particles are emitted. The values are
* given in degrees. This allows you to control the direction
* of the emitter. If you wish instead to change the rotation
* of the particles themselves, see the `particleRotate` property.
*
* Accessing this property should typically return a number.
* However, it can be set to any valid EmitterOp onEmit type.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#particleAngle
* @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType}
* @since 3.60.0
*/
particleAngle: {
get: function() {
return this.ops.angle.current;
},
set: function(value) {
this.ops.angle.onChange(value);
}
},
/**
* The rotation (or angle) of each particle when it is emitted.
* The value is given in degrees and uses a right-handed
* coordinate system, where 0 degrees points to the right, 90 degrees
* points down and -90 degrees points up.
*
* Accessing this property should typically return a number.
* However, it can be set to any valid EmitterOp onEmit type.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#particleRotate
* @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType}
* @since 3.60.0
*/
particleRotate: {
get: function() {
return this.ops.rotate.current;
},
set: function(value) {
this.ops.rotate.onChange(value);
}
},
/**
* The number of particles that are emitted each time an emission
* occurs, i.e. from one 'explosion' or each frame in a 'flow' cycle.
*
* The default is 1.
*
* Accessing this property should typically return a number.
* However, it can be set to any valid EmitterOp onEmit type.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#quantity
* @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType}
* @see Phaser.GameObjects.Particles.ParticleEmitter#setFrequency
* @see Phaser.GameObjects.Particles.ParticleEmitter#setQuantity
* @since 3.60.0
*/
quantity: {
get: function() {
return this.ops.quantity.current;
},
set: function(value) {
this.ops.quantity.onChange(value);
}
},
/**
* The number of milliseconds to wait after emission before
* the particles start updating. This allows you to emit particles
* that appear 'static' or still on-screen and then, after this value,
* begin to move.
*
* Accessing this property should typically return a number.
* However, it can be set to any valid EmitterOp onEmit type.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#delay
* @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType}
* @since 3.60.0
*/
delay: {
get: function() {
return this.ops.delay.current;
},
set: function(value) {
this.ops.delay.onChange(value);
}
},
/**
* The number of milliseconds to wait after a particle has finished
* its life before it will be removed. This allows you to 'hold' a
* particle on the screen once it has reached its final state
* before it then vanishes.
*
* Note that all particle updates will cease, including changing
* alpha, scale, movement or animation.
*
* Accessing this property should typically return a number.
* However, it can be set to any valid EmitterOp onEmit type.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#hold
* @type {Phaser.Types.GameObjects.Particles.EmitterOpOnEmitType}
* @since 3.60.0
*/
hold: {
get: function() {
return this.ops.hold.current;
},
set: function(value) {
this.ops.hold.onChange(value);
}
},
/**
* The internal flow counter.
*
* Treat this property as read-only.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#flowCounter
* @type {number}
* @since 3.60.0
*/
flowCounter: {
get: function() {
return this.counters[0];
},
set: function(value) {
this.counters[0] = value;
}
},
/**
* The internal frame counter.
*
* Treat this property as read-only.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#frameCounter
* @type {number}
* @since 3.60.0
*/
frameCounter: {
get: function() {
return this.counters[1];
},
set: function(value) {
this.counters[1] = value;
}
},
/**
* The internal animation counter.
*
* Treat this property as read-only.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#animCounter
* @type {number}
* @since 3.60.0
*/
animCounter: {
get: function() {
return this.counters[2];
},
set: function(value) {
this.counters[2] = value;
}
},
/**
* The internal elasped counter.
*
* Treat this property as read-only.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#elapsed
* @type {number}
* @since 3.60.0
*/
elapsed: {
get: function() {
return this.counters[3];
},
set: function(value) {
this.counters[3] = value;
}
},
/**
* The internal stop counter.
*
* Treat this property as read-only.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#stopCounter
* @type {number}
* @since 3.60.0
*/
stopCounter: {
get: function() {
return this.counters[4];
},
set: function(value) {
this.counters[4] = value;
}
},
/**
* The internal complete flag.
*
* Treat this property as read-only.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#completeFlag
* @type {boolean}
* @since 3.60.0
*/
completeFlag: {
get: function() {
return this.counters[5];
},
set: function(value) {
this.counters[5] = value;
}
},
/**
* The internal zone index.
*
* Treat this property as read-only.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#zoneIndex
* @type {number}
* @since 3.60.0
*/
zoneIndex: {
get: function() {
return this.counters[6];
},
set: function(value) {
this.counters[6] = value;
}
},
/**
* The internal zone total.
*
* Treat this property as read-only.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#zoneTotal
* @type {number}
* @since 3.60.0
*/
zoneTotal: {
get: function() {
return this.counters[7];
},
set: function(value) {
this.counters[7] = value;
}
},
/**
* The current frame index.
*
* Treat this property as read-only.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#currentFrame
* @type {number}
* @since 3.60.0
*/
currentFrame: {
get: function() {
return this.counters[8];
},
set: function(value) {
this.counters[8] = value;
}
},
/**
* The current animation index.
*
* Treat this property as read-only.
*
* @name Phaser.GameObjects.Particles.ParticleEmitter#currentAnim
* @type {number}
* @since 3.60.0
*/
currentAnim: {
get: function() {
return this.counters[9];
},
set: function(value) {
this.counters[9] = value;
}
},
/**
* Destroys this Particle Emitter and all Particles it owns.
*
* @method Phaser.GameObjects.Particles.ParticleEmitter#preDestroy
* @since 3.60.0
*/
preDestroy: function() {
this.texture = null;
this.frames = null;
this.anims = null;
this.emitCallback = null;
this.emitCallbackScope = null;
this.deathCallback = null;
this.deathCallbackScope = null;
this.emitZones = null;
this.deathZones = null;
this.bounds = null;
this.follow = null;
this.counters = null;
var i;
var ops = this.ops;
for (i = 0; i < configOpMap.length; i++) {
var key = configOpMap[i];
ops[key].destroy();
}
for (i = 0; i < this.alive.length; i++) {
this.alive[i].destroy();
}
for (i = 0; i < this.dead.length; i++) {
this.dead[i].destroy();
}
this.ops = null;
this.alive = [];
this.dead = [];
this.worldMatrix.destroy();
}
});
module2.exports = ParticleEmitter;
}
),
/***/
9871: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var RectangleToRectangle = __webpack_require__2(59996);
var TransformMatrix = __webpack_require__2(61340);
var tempMatrix1 = new TransformMatrix();
var tempMatrix2 = new TransformMatrix();
var tempMatrix3 = new TransformMatrix();
var tempMatrix4 = new TransformMatrix();
var ParticleEmitterCanvasRenderer = function(renderer, emitter, camera, parentMatrix) {
var camMatrix = tempMatrix1;
var calcMatrix = tempMatrix2;
var particleMatrix = tempMatrix3;
var managerMatrix = tempMatrix4;
if (parentMatrix) {
managerMatrix.loadIdentity();
managerMatrix.multiply(parentMatrix);
managerMatrix.translate(emitter.x, emitter.y);
managerMatrix.rotate(emitter.rotation);
managerMatrix.scale(emitter.scaleX, emitter.scaleY);
} else {
managerMatrix.applyITRS(emitter.x, emitter.y, emitter.rotation, emitter.scaleX, emitter.scaleY);
}
var ctx = renderer.currentContext;
var roundPixels = camera.roundPixels;
var camerAlpha = camera.alpha;
var emitterAlpha = emitter.alpha;
var particles = emitter.alive;
var particleCount = particles.length;
var viewBounds = emitter.viewBounds;
if (!emitter.visible || particleCount === 0 || viewBounds && !RectangleToRectangle(viewBounds, camera.worldView)) {
return;
}
if (emitter.sortCallback) {
emitter.depthSort();
}
camera.addToRenderList(emitter);
var scrollFactorX = emitter.scrollFactorX;
var scrollFactorY = emitter.scrollFactorY;
ctx.save();
ctx.globalCompositeOperation = renderer.blendModes[emitter.blendMode];
for (var i = 0; i < particleCount; i++) {
var particle = particles[i];
var alpha = particle.alpha * emitterAlpha * camerAlpha;
if (alpha <= 0 || particle.scaleX === 0 || particle.scaleY === 0) {
continue;
}
particleMatrix.applyITRS(particle.x, particle.y, particle.rotation, particle.scaleX, particle.scaleY);
camMatrix.copyFrom(camera.matrix);
camMatrix.multiplyWithOffset(managerMatrix, -camera.scrollX * scrollFactorX, -camera.scrollY * scrollFactorY);
particleMatrix.e = particle.x;
particleMatrix.f = particle.y;
camMatrix.multiply(particleMatrix, calcMatrix);
var frame = particle.frame;
var cd = frame.canvasData;
if (cd.width > 0 && cd.height > 0) {
var x = -frame.halfWidth;
var y = -frame.halfHeight;
ctx.globalAlpha = alpha;
ctx.save();
calcMatrix.setToContext(ctx);
if (roundPixels) {
x = Math.round(x);
y = Math.round(y);
}
ctx.imageSmoothingEnabled = !frame.source.scaleMode;
ctx.drawImage(frame.source.image, cd.x, cd.y, cd.width, cd.height, x, y, cd.width, cd.height);
ctx.restore();
}
}
ctx.restore();
};
module2.exports = ParticleEmitterCanvasRenderer;
}
),
/***/
92730: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var BuildGameObject = __webpack_require__2(25305);
var GameObjectCreator = __webpack_require__2(44603);
var GetAdvancedValue = __webpack_require__2(23568);
var GetFastValue = __webpack_require__2(95540);
var ParticleEmitter = __webpack_require__2(31600);
GameObjectCreator.register("particles", function(config, addToScene) {
if (config === void 0) {
config = {};
}
var key = GetAdvancedValue(config, "key", null);
var emitterConfig = GetFastValue(config, "config", null);
var emitter = new ParticleEmitter(this.scene, 0, 0, key);
if (addToScene !== void 0) {
config.add = addToScene;
}
BuildGameObject(this.scene, emitter, config);
if (emitterConfig) {
emitter.setConfig(emitterConfig);
}
return emitter;
});
}
),
/***/
676: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var GameObjectFactory = __webpack_require__2(39429);
var ParticleEmitter = __webpack_require__2(31600);
GameObjectFactory.register("particles", function(x, y, texture, config) {
if (x !== void 0 && typeof x === "string") {
console.warn("ParticleEmitterManager was removed in Phaser 3.60. See documentation for details");
}
return this.displayList.add(new ParticleEmitter(this.scene, x, y, texture, config));
});
}
),
/***/
90668: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(21188);
}
if (true) {
renderCanvas = __webpack_require__2(9871);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
21188: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var RectangleToRectangle = __webpack_require__2(59996);
var TransformMatrix = __webpack_require__2(61340);
var Utils = __webpack_require__2(70554);
var tempMatrix1 = new TransformMatrix();
var tempMatrix2 = new TransformMatrix();
var tempMatrix3 = new TransformMatrix();
var tempMatrix4 = new TransformMatrix();
var ParticleEmitterWebGLRenderer = function(renderer, emitter, camera, parentMatrix) {
var pipeline = renderer.pipelines.set(emitter.pipeline);
var camMatrix = tempMatrix1;
var calcMatrix = tempMatrix2;
var particleMatrix = tempMatrix3;
var managerMatrix = tempMatrix4;
if (parentMatrix) {
managerMatrix.loadIdentity();
managerMatrix.multiply(parentMatrix);
managerMatrix.translate(emitter.x, emitter.y);
managerMatrix.rotate(emitter.rotation);
managerMatrix.scale(emitter.scaleX, emitter.scaleY);
} else {
managerMatrix.applyITRS(emitter.x, emitter.y, emitter.rotation, emitter.scaleX, emitter.scaleY);
}
var getTint = Utils.getTintAppendFloatAlpha;
var camerAlpha = camera.alpha;
var emitterAlpha = emitter.alpha;
renderer.pipelines.preBatch(emitter);
var particles = emitter.alive;
var particleCount = particles.length;
var viewBounds = emitter.viewBounds;
if (particleCount === 0 || viewBounds && !RectangleToRectangle(viewBounds, camera.worldView)) {
return;
}
if (emitter.sortCallback) {
emitter.depthSort();
}
camera.addToRenderList(emitter);
camMatrix.copyFrom(camera.matrix);
camMatrix.multiplyWithOffset(managerMatrix, -camera.scrollX * emitter.scrollFactorX, -camera.scrollY * emitter.scrollFactorY);
renderer.setBlendMode(emitter.blendMode);
if (emitter.mask) {
emitter.mask.preRenderWebGL(renderer, emitter, camera);
renderer.pipelines.set(emitter.pipeline);
}
var tintEffect = emitter.tintFill;
var textureUnit;
var glTexture;
for (var i = 0; i < particleCount; i++) {
var particle = particles[i];
var alpha = particle.alpha * emitterAlpha * camerAlpha;
if (alpha <= 0 || particle.scaleX === 0 || particle.scaleY === 0) {
continue;
}
particleMatrix.applyITRS(particle.x, particle.y, particle.rotation, particle.scaleX, particle.scaleY);
particleMatrix.e = particle.x;
particleMatrix.f = particle.y;
camMatrix.multiply(particleMatrix, calcMatrix);
var frame = particle.frame;
if (frame.glTexture !== glTexture) {
glTexture = frame.glTexture;
textureUnit = pipeline.setGameObject(emitter, frame);
}
var x = -frame.halfWidth;
var y = -frame.halfHeight;
var quad = calcMatrix.setQuad(x, y, x + frame.width, y + frame.height);
var tint = getTint(particle.tint, alpha);
if (pipeline.shouldFlush(6)) {
pipeline.flush();
textureUnit = pipeline.setGameObject(emitter, frame);
}
pipeline.batchQuad(
emitter,
quad[0],
quad[1],
quad[2],
quad[3],
quad[4],
quad[5],
quad[6],
quad[7],
frame.u0,
frame.v0,
frame.u1,
frame.v1,
tint,
tint,
tint,
tint,
tintEffect,
glTexture,
textureUnit
);
}
if (emitter.mask) {
emitter.mask.postRenderWebGL(renderer, camera);
}
renderer.pipelines.postBatch(emitter);
};
module2.exports = ParticleEmitterWebGLRenderer;
}
),
/***/
20286: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var ParticleProcessor = new Class({
initialize: function ParticleProcessor2(x, y, active) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (active === void 0) {
active = true;
}
this.emitter;
this.x = x;
this.y = y;
this.active = active;
},
/**
* The Particle Processor update method should be overriden by your own
* method and handle the processing of the particles, typically modifying
* their velocityX/Y values based on the criteria of this processor.
*
* @method Phaser.GameObjects.Particles.ParticleProcessor#update
* @since 3.60.0
*
* @param {Phaser.GameObjects.Particles.Particle} particle - The Particle to update.
* @param {number} delta - The delta time in ms.
* @param {number} step - The delta value divided by 1000.
* @param {number} t - The current normalized lifetime of the particle, between 0 (birth) and 1 (death).
*/
update: function() {
},
/**
* Destroys this Particle Processor by removing all external references.
*
* This is called automatically when the owning Particle Emitter is destroyed.
*
* @method Phaser.GameObjects.Particles.ParticleProcessor#destroy
* @since 3.60.0
*/
destroy: function() {
this.emitter = null;
}
});
module2.exports = ParticleProcessor;
}
),
/***/
9774: (
/***/
(module2) => {
module2.exports = "complete";
}
),
/***/
812: (
/***/
(module2) => {
module2.exports = "deathzone";
}
),
/***/
30522: (
/***/
(module2) => {
module2.exports = "explode";
}
),
/***/
96695: (
/***/
(module2) => {
module2.exports = "start";
}
),
/***/
18677: (
/***/
(module2) => {
module2.exports = "stop";
}
),
/***/
20696: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
COMPLETE: __webpack_require__2(9774),
DEATH_ZONE: __webpack_require__2(812),
EXPLODE: __webpack_require__2(30522),
START: __webpack_require__2(96695),
STOP: __webpack_require__2(18677)
};
}
),
/***/
18404: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
EmitterColorOp: __webpack_require__2(76472),
EmitterOp: __webpack_require__2(44777),
Events: __webpack_require__2(20696),
GravityWell: __webpack_require__2(24502),
Particle: __webpack_require__2(56480),
ParticleBounds: __webpack_require__2(69601),
ParticleEmitter: __webpack_require__2(31600),
ParticleProcessor: __webpack_require__2(20286),
Zones: __webpack_require__2(21024)
};
}
),
/***/
26388: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var DeathZone = new Class({
initialize: function DeathZone2(source, killOnEnter) {
this.source = source;
this.killOnEnter = killOnEnter;
},
/**
* Checks if the given Particle will be killed or not by this zone.
*
* @method Phaser.GameObjects.Particles.Zones.DeathZone#willKill
* @since 3.0.0
*
* @param {Phaser.GameObjects.Particles.Particle} particle - The particle to test against this Death Zones.
*
* @return {boolean} Return `true` if the Particle is to be killed, otherwise return `false`.
*/
willKill: function(particle) {
var withinZone = this.source.contains(particle.x, particle.y);
return withinZone && this.killOnEnter || !withinZone && !this.killOnEnter;
}
});
module2.exports = DeathZone;
}
),
/***/
19909: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var EdgeZone = new Class({
initialize: function EdgeZone2(source, quantity, stepRate, yoyo, seamless, total) {
if (yoyo === void 0) {
yoyo = false;
}
if (seamless === void 0) {
seamless = true;
}
if (total === void 0) {
total = -1;
}
this.source = source;
this.points = [];
this.quantity = quantity;
this.stepRate = stepRate;
this.yoyo = yoyo;
this.counter = -1;
this.seamless = seamless;
this._length = 0;
this._direction = 0;
this.total = total;
this.updateSource();
},
/**
* Update the {@link Phaser.GameObjects.Particles.Zones.EdgeZone#points} from the EdgeZone's
* {@link Phaser.GameObjects.Particles.Zones.EdgeZone#source}.
*
* Also updates internal properties.
*
* @method Phaser.GameObjects.Particles.Zones.EdgeZone#updateSource
* @since 3.0.0
*
* @return {this} This Edge Zone.
*/
updateSource: function() {
this.points = this.source.getPoints(this.quantity, this.stepRate);
if (this.seamless) {
var a = this.points[0];
var b = this.points[this.points.length - 1];
if (a.x === b.x && a.y === b.y) {
this.points.pop();
}
}
var oldLength = this._length;
this._length = this.points.length;
if (this._length < oldLength && this.counter > this._length) {
this.counter = this._length - 1;
}
return this;
},
/**
* Change the source of the EdgeZone.
*
* @method Phaser.GameObjects.Particles.Zones.EdgeZone#changeSource
* @since 3.0.0
*
* @param {Phaser.Types.GameObjects.Particles.EdgeZoneSource} source - An object instance with a `getPoints(quantity, stepRate)` method returning an array of points.
*
* @return {this} This Edge Zone.
*/
changeSource: function(source) {
this.source = source;
return this.updateSource();
},
/**
* Get the next point in the Zone and set its coordinates on the given Particle.
*
* @method Phaser.GameObjects.Particles.Zones.EdgeZone#getPoint
* @since 3.0.0
*
* @param {Phaser.GameObjects.Particles.Particle} particle - The Particle.
*/
getPoint: function(particle) {
if (this._direction === 0) {
this.counter++;
if (this.counter >= this._length) {
if (this.yoyo) {
this._direction = 1;
this.counter = this._length - 1;
} else {
this.counter = 0;
}
}
} else {
this.counter--;
if (this.counter === -1) {
if (this.yoyo) {
this._direction = 0;
this.counter = 0;
} else {
this.counter = this._length - 1;
}
}
}
var point = this.points[this.counter];
if (point) {
particle.x = point.x;
particle.y = point.y;
}
}
});
module2.exports = EdgeZone;
}
),
/***/
68875: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Vector2 = __webpack_require__2(26099);
var RandomZone = new Class({
initialize: function RandomZone2(source) {
this.source = source;
this._tempVec = new Vector2();
this.total = -1;
},
/**
* Get the next point in the Zone and set its coordinates on the given Particle.
*
* @method Phaser.GameObjects.Particles.Zones.RandomZone#getPoint
* @since 3.0.0
*
* @param {Phaser.GameObjects.Particles.Particle} particle - The Particle.
*/
getPoint: function(particle) {
var vec = this._tempVec;
this.source.getRandomPoint(vec);
particle.x = vec.x;
particle.y = vec.y;
}
});
module2.exports = RandomZone;
}
),
/***/
21024: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
DeathZone: __webpack_require__2(26388),
EdgeZone: __webpack_require__2(19909),
RandomZone: __webpack_require__2(68875)
};
}
),
/***/
1159: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31401);
var Sprite = __webpack_require__2(68287);
var PathFollower = new Class({
Extends: Sprite,
Mixins: [
Components.PathFollower
],
initialize: function PathFollower2(scene, path, x, y, texture, frame) {
Sprite.call(this, scene, x, y, texture, frame);
this.path = path;
},
/**
* Internal update handler that advances this PathFollower along the path.
*
* Called automatically by the Scene step, should not typically be called directly.
*
* @method Phaser.GameObjects.PathFollower#preUpdate
* @protected
* @since 3.0.0
*
* @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout.
* @param {number} delta - The delta time, in ms, elapsed since the last frame.
*/
preUpdate: function(time, delta) {
this.anims.update(time, delta);
this.pathUpdate(time);
}
});
module2.exports = PathFollower;
}
),
/***/
90145: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var GameObjectFactory = __webpack_require__2(39429);
var PathFollower = __webpack_require__2(1159);
GameObjectFactory.register("follower", function(path, x, y, key, frame) {
var sprite = new PathFollower(this.scene, path, x, y, key, frame);
this.displayList.add(sprite);
this.updateList.add(sprite);
return sprite;
});
}
),
/***/
33663: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var AnimationState = __webpack_require__2(9674);
var Class = __webpack_require__2(83419);
var GenerateGridVerts = __webpack_require__2(48803);
var IntegerToRGB = __webpack_require__2(90664);
var Mesh = __webpack_require__2(4703);
var UUID = __webpack_require__2(45650);
var Plane = new Class({
Extends: Mesh,
initialize: function Plane2(scene, x, y, texture, frame, width, height, tile) {
if (!texture) {
texture = "__DEFAULT";
}
Mesh.call(this, scene, x, y, texture, frame);
this.type = "Plane";
this.anims = new AnimationState(this);
this.gridWidth;
this.gridHeight;
this.isTiled;
this._checkerboard = null;
this.hideCCW = false;
this.setGridSize(width, height, tile);
this.setSizeToFrame(false);
this.setViewHeight();
},
/**
* Do not change this value. It has no effect other than to break things.
*
* @name Phaser.GameObjects.Plane#originX
* @type {number}
* @readonly
* @override
* @since 3.70.0
*/
originX: {
get: function() {
return 0.5;
}
},
/**
* Do not change this value. It has no effect other than to break things.
*
* @name Phaser.GameObjects.Plane#originY
* @type {number}
* @readonly
* @override
* @since 3.70.0
*/
originY: {
get: function() {
return 0.5;
}
},
/**
* Modifies the layout of this Plane by adjusting the grid dimensions to the
* given width and height. The values are given in cells, not pixels.
*
* The `tile` parameter allows you to control if the texture is tiled, or
* applied across the entire Plane? A tiled texture will repeat with one
* iteration per cell. A non-tiled texture will be applied across the whole
* Plane.
*
* Note that if this Plane is using a single texture, not from a texture atlas
* or sprite sheet, then you can use the `Plane.uvScale` method to have much
* more fine-grained control over the texture tiling.
*
* @method Phaser.GameObjects.Plane#preDestroy
* @since 3.60.0
*
* @param {number} [width=8] - The width of this Plane, in cells, not pixels.
* @param {number} [height=8] - The height of this Plane, in cells, not pixels.
* @param {boolean} [tile=false] - Is the texture tiled? I.e. repeated across each cell.
*/
setGridSize: function(width, height, tile) {
if (width === void 0) {
width = 8;
}
if (height === void 0) {
height = 8;
}
if (tile === void 0) {
tile = false;
}
var flipY = false;
if (tile) {
flipY = true;
}
this.gridWidth = width;
this.gridHeight = height;
this.isTiled = tile;
this.clear();
GenerateGridVerts({
mesh: this,
widthSegments: width,
heightSegments: height,
isOrtho: false,
tile,
flipY
});
return this;
},
/**
* An internal method that resets the perspective projection for this Plane
* when it changes texture or frame, and also resets the cell UV coordinates,
* if required.
*
* @method Phaser.GameObjects.Plane#setSizeToFrame
* @since 3.60.0
* @override
*
* @param {boolean} [resetUV=true] - Reset all of the cell UV coordinates?
*
* @return {this} This Game Object instance.
*/
setSizeToFrame: function(resetUV) {
if (resetUV === void 0) {
resetUV = true;
}
var frame = this.frame;
this.setPerspective(this.width / frame.width, this.height / frame.height);
if (this._checkerboard && this._checkerboard !== this.texture) {
this.removeCheckerboard();
}
if (!resetUV) {
return this;
}
var gridX = this.gridWidth;
var gridY = this.gridHeight;
var verts = this.vertices;
var frameU0 = frame.u0;
var frameU1 = frame.u1;
var frameV0 = frame.v0;
var frameV1 = frame.v1;
var x;
var y;
var i = 0;
if (this.isTiled) {
frameV0 = frame.v1;
frameV1 = frame.v0;
for (y = 0; y < gridY; y++) {
for (x = 0; x < gridX; x++) {
verts[i++].setUVs(frameU0, frameV1);
verts[i++].setUVs(frameU0, frameV0);
verts[i++].setUVs(frameU1, frameV1);
verts[i++].setUVs(frameU0, frameV0);
verts[i++].setUVs(frameU1, frameV0);
verts[i++].setUVs(frameU1, frameV1);
}
}
} else {
var gridX1 = gridX + 1;
var gridY1 = gridY + 1;
var frameU = frameU1 - frameU0;
var frameV = frameV1 - frameV0;
var uvs = [];
for (y = 0; y < gridY1; y++) {
for (x = 0; x < gridX1; x++) {
var tu = frameU0 + frameU * (x / gridX);
var tv = frameV0 + frameV * (y / gridY);
uvs.push(tu, tv);
}
}
for (y = 0; y < gridY; y++) {
for (x = 0; x < gridX; x++) {
var a = (x + gridX1 * y) * 2;
var b = (x + gridX1 * (y + 1)) * 2;
var c = (x + 1 + gridX1 * (y + 1)) * 2;
var d = (x + 1 + gridX1 * y) * 2;
verts[i++].setUVs(uvs[a], uvs[a + 1]);
verts[i++].setUVs(uvs[b], uvs[b + 1]);
verts[i++].setUVs(uvs[d], uvs[d + 1]);
verts[i++].setUVs(uvs[b], uvs[b + 1]);
verts[i++].setUVs(uvs[c], uvs[c + 1]);
verts[i++].setUVs(uvs[d], uvs[d + 1]);
}
}
}
return this;
},
/**
* Sets the height of this Plane to match the given value, in pixels.
*
* This adjusts the `Plane.viewPosition.z` value to achieve this.
*
* If no `value` parameter is given, it will set the view height to match
* that of the current texture frame the Plane is using.
*
* @method Phaser.GameObjects.Plane#setViewHeight
* @since 3.60.0
*
* @param {number} [value] - The height, in pixels, to set this Plane view height to.
*/
setViewHeight: function(value) {
if (value === void 0) {
value = this.frame.height;
}
var vFOV = this.fov * (Math.PI / 180);
this.viewPosition.z = this.height / value / Math.tan(vFOV / 2);
this.dirtyCache[10] = 1;
},
/**
* Creates a checkerboard style texture, based on the given colors and alpha
* values and applies it to this Plane, replacing any current texture it may
* have.
*
* The colors are used in an alternating pattern, like a chess board.
*
* Calling this method generates a brand new 16x16 pixel WebGLTexture internally
* and applies it to this Plane. While quite fast to do, you should still be
* mindful of calling this method either extensively, or in tight parts of
* your game.
*
* @method Phaser.GameObjects.Plane#createCheckerboard
* @since 3.60.0
*
* @param {number} [color1=0xffffff] - The odd cell color, specified as a hex value.
* @param {number} [color2=0x0000ff] - The even cell color, specified as a hex value.
* @param {number} [alpha1=255] - The odd cell alpha value, specified as a number between 0 and 255.
* @param {number} [alpha2=255] - The even cell alpha value, specified as a number between 0 and 255.
* @param {number} [height=128] - The view height of the Plane after creation, in pixels.
*/
createCheckerboard: function(color1, color2, alpha1, alpha2, height) {
if (color1 === void 0) {
color1 = 16777215;
}
if (color2 === void 0) {
color2 = 255;
}
if (alpha1 === void 0) {
alpha1 = 255;
}
if (alpha2 === void 0) {
alpha2 = 255;
}
if (height === void 0) {
height = 128;
}
var c1 = IntegerToRGB(color1);
var c2 = IntegerToRGB(color2);
var colors = [];
for (var h = 0; h < 16; h++) {
for (var w = 0; w < 16; w++) {
if (h < 8 && w < 8 || h > 7 && w > 7) {
colors.push(c1.r, c1.g, c1.b, alpha1);
} else {
colors.push(c2.r, c2.g, c2.b, alpha2);
}
}
}
var texture = this.scene.sys.textures.addUint8Array(UUID(), new Uint8Array(colors), 16, 16);
this.removeCheckerboard();
this.setTexture(texture);
this.setSizeToFrame();
this.setViewHeight(height);
return this;
},
/**
* If this Plane has a Checkerboard Texture, this method will destroy it
* and reset the internal flag for it.
*
* @method Phaser.GameObjects.Plane#removeCheckerboard
* @since 3.60.0
*/
removeCheckerboard: function() {
if (this._checkerboard) {
this._checkerboard.destroy();
this._checkerboard = null;
}
},
/**
* Start playing the given animation on this Plane.
*
* Animations in Phaser can either belong to the global Animation Manager, or specifically to this Plane.
*
* The benefit of a global animation is that multiple Game Objects can all play the same animation, without
* having to duplicate the data. You can just create it once and then play it on any animating Game Object.
*
* The following code shows how to create a global repeating animation. The animation will be created
* from all of the frames within the sprite sheet that was loaded with the key 'muybridge':
*
* ```javascript
* var config = {
* key: 'run',
* frames: 'muybridge',
* frameRate: 15,
* repeat: -1
* };
*
* // This code should be run from within a Scene:
* this.anims.create(config);
* ```
*
* However, if you wish to create an animation that is unique to this Plane, and this Plane alone,
* you can call the `Animation.create` method instead. It accepts the exact same parameters as when
* creating a global animation, however the resulting data is kept locally in this Plane.
*
* With the animation created, either globally or locally, you can now play it on this Plane:
*
* ```javascript
* const plane = this.add.plane(...);
* plane.play('run');
* ```
*
* Alternatively, if you wish to run it at a different frame rate for example, you can pass a config
* object instead:
*
* ```javascript
* const plane = this.add.plane(...);
* plane.play({ key: 'run', frameRate: 24 });
* ```
*
* When playing an animation on a Plane it will first check to see if it can find a matching key
* locally within the Plane. If it can, it will play the local animation. If not, it will then
* search the global Animation Manager and look for it there.
*
* If you need a Plane to be able to play both local and global animations, make sure they don't
* have conflicting keys.
*
* See the documentation for the `PlayAnimationConfig` config object for more details about this.
*
* Also, see the documentation in the Animation Manager for further details on creating animations.
*
* @method Phaser.GameObjects.Plane#play
* @fires Phaser.Animations.Events#ANIMATION_START
* @since 3.60.0
*
* @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object.
* @param {boolean} [ignoreIfPlaying=false] - If an animation is already playing then ignore this call.
*
* @return {this} This Game Object.
*/
play: function(key, ignoreIfPlaying) {
return this.anims.play(key, ignoreIfPlaying);
},
/**
* Start playing the given animation on this Plane, in reverse.
*
* Animations in Phaser can either belong to the global Animation Manager, or specifically to a Game Object.
*
* The benefit of a global animation is that multiple Game Objects can all play the same animation, without
* having to duplicate the data. You can just create it once and then play it on any animating Game Object.
*
* The following code shows how to create a global repeating animation. The animation will be created
* from all of the frames within the sprite sheet that was loaded with the key 'muybridge':
*
* ```javascript
* var config = {
* key: 'run',
* frames: 'muybridge',
* frameRate: 15,
* repeat: -1
* };
*
* // This code should be run from within a Scene:
* this.anims.create(config);
* ```
*
* However, if you wish to create an animation that is unique to this Game Object, and this Game Object alone,
* you can call the `Animation.create` method instead. It accepts the exact same parameters as when
* creating a global animation, however the resulting data is kept locally in this Game Object.
*
* With the animation created, either globally or locally, you can now play it on this Game Object:
*
* ```javascript
* const plane = this.add.plane(...);
* plane.playReverse('run');
* ```
*
* Alternatively, if you wish to run it at a different frame rate, for example, you can pass a config
* object instead:
*
* ```javascript
* const plane = this.add.plane(...);
* plane.playReverse({ key: 'run', frameRate: 24 });
* ```
*
* When playing an animation on a Game Object it will first check to see if it can find a matching key
* locally within the Game Object. If it can, it will play the local animation. If not, it will then
* search the global Animation Manager and look for it there.
*
* If you need a Game Object to be able to play both local and global animations, make sure they don't
* have conflicting keys.
*
* See the documentation for the `PlayAnimationConfig` config object for more details about this.
*
* Also, see the documentation in the Animation Manager for further details on creating animations.
*
* @method Phaser.GameObjects.Plane#playReverse
* @fires Phaser.Animations.Events#ANIMATION_START
* @since 3.60.0
*
* @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object.
* @param {boolean} [ignoreIfPlaying=false] - If an animation is already playing then ignore this call.
*
* @return {this} This Game Object.
*/
playReverse: function(key, ignoreIfPlaying) {
return this.anims.playReverse(key, ignoreIfPlaying);
},
/**
* Waits for the specified delay, in milliseconds, then starts playback of the given animation.
*
* If the animation _also_ has a delay value set in its config, it will be **added** to the delay given here.
*
* If an animation is already running and a new animation is given to this method, it will wait for
* the given delay before starting the new animation.
*
* If no animation is currently running, the given one begins after the delay.
*
* When playing an animation on a Game Object it will first check to see if it can find a matching key
* locally within the Game Object. If it can, it will play the local animation. If not, it will then
* search the global Animation Manager and look for it there.
*
* @method Phaser.GameObjects.Plane#playAfterDelay
* @fires Phaser.Animations.Events#ANIMATION_START
* @since 3.60.0
*
* @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object.
* @param {number} delay - The delay, in milliseconds, to wait before starting the animation playing.
*
* @return {this} This Game Object.
*/
playAfterDelay: function(key, delay) {
return this.anims.playAfterDelay(key, delay);
},
/**
* Waits for the current animation to complete the `repeatCount` number of repeat cycles, then starts playback
* of the given animation.
*
* You can use this to ensure there are no harsh jumps between two sets of animations, i.e. going from an
* idle animation to a walking animation, by making them blend smoothly into each other.
*
* If no animation is currently running, the given one will start immediately.
*
* When playing an animation on a Game Object it will first check to see if it can find a matching key
* locally within the Game Object. If it can, it will play the local animation. If not, it will then
* search the global Animation Manager and look for it there.
*
* @method Phaser.GameObjects.Plane#playAfterRepeat
* @fires Phaser.Animations.Events#ANIMATION_START
* @since 3.60.0
*
* @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object.
* @param {number} [repeatCount=1] - How many times should the animation repeat before the next one starts?
*
* @return {this} This Game Object.
*/
playAfterRepeat: function(key, repeatCount) {
return this.anims.playAfterRepeat(key, repeatCount);
},
/**
* Immediately stops the current animation from playing and dispatches the `ANIMATION_STOP` events.
*
* If no animation is playing, no event will be dispatched.
*
* If there is another animation queued (via the `chain` method) then it will start playing immediately.
*
* @method Phaser.GameObjects.Plane#stop
* @fires Phaser.Animations.Events#ANIMATION_STOP
* @since 3.60.0
*
* @return {this} This Game Object.
*/
stop: function() {
return this.anims.stop();
},
/**
* Stops the current animation from playing after the specified time delay, given in milliseconds.
*
* It then dispatches the `ANIMATION_STOP` event.
*
* If no animation is running, no events will be dispatched.
*
* If there is another animation in the queue (set via the `chain` method) then it will start playing,
* when the current one stops.
*
* @method Phaser.GameObjects.Plane#stopAfterDelay
* @fires Phaser.Animations.Events#ANIMATION_STOP
* @since 3.60.0
*
* @param {number} delay - The number of milliseconds to wait before stopping this animation.
*
* @return {this} This Game Object.
*/
stopAfterDelay: function(delay) {
return this.anims.stopAfterDelay(delay);
},
/**
* Stops the current animation from playing after the given number of repeats.
*
* It then dispatches the `ANIMATION_STOP` event.
*
* If no animation is running, no events will be dispatched.
*
* If there is another animation in the queue (set via the `chain` method) then it will start playing,
* when the current one stops.
*
* @method Phaser.GameObjects.Plane#stopAfterRepeat
* @fires Phaser.Animations.Events#ANIMATION_STOP
* @since 3.60.0
*
* @param {number} [repeatCount=1] - How many times should the animation repeat before stopping?
*
* @return {this} This Game Object.
*/
stopAfterRepeat: function(repeatCount) {
return this.anims.stopAfterRepeat(repeatCount);
},
/**
* Stops the current animation from playing when it next sets the given frame.
* If this frame doesn't exist within the animation it will not stop it from playing.
*
* It then dispatches the `ANIMATION_STOP` event.
*
* If no animation is running, no events will be dispatched.
*
* If there is another animation in the queue (set via the `chain` method) then it will start playing,
* when the current one stops.
*
* @method Phaser.GameObjects.Plane#stopOnFrame
* @fires Phaser.Animations.Events#ANIMATION_STOP
* @since 3.60.0
*
* @param {Phaser.Animations.AnimationFrame} frame - The frame to check before stopping this animation.
*
* @return {this} This Game Object.
*/
stopOnFrame: function(frame) {
return this.anims.stopOnFrame(frame);
},
/**
* Runs the preUpdate for this Plane, which will check its Animation State,
* if one is playing, and refresh view / model matrices, if updated.
*
* @method Phaser.GameObjects.Plane#preUpdate
* @protected
* @since 3.60.0
*
* @param {number} time - The current timestamp.
* @param {number} delta - The delta time, in ms, elapsed since the last frame.
*/
preUpdate: function(time, delta) {
Mesh.prototype.preUpdate.call(this, time, delta);
this.anims.update(time, delta);
},
/**
* Handles the pre-destroy step for the Plane, which removes the vertices and debug callbacks.
*
* @method Phaser.GameObjects.Plane#preDestroy
* @private
* @since 3.60.0
*/
preDestroy: function() {
this.clear();
this.removeCheckerboard();
this.anims.destroy();
this.anims = void 0;
this.debugCallback = null;
this.debugGraphic = null;
}
});
module2.exports = Plane;
}
),
/***/
56015: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var BuildGameObject = __webpack_require__2(25305);
var BuildGameObjectAnimation = __webpack_require__2(13059);
var GameObjectCreator = __webpack_require__2(44603);
var GetAdvancedValue = __webpack_require__2(23568);
var GetValue = __webpack_require__2(35154);
var Plane = __webpack_require__2(33663);
GameObjectCreator.register("plane", function(config, addToScene) {
if (config === void 0) {
config = {};
}
var key = GetAdvancedValue(config, "key", null);
var frame = GetAdvancedValue(config, "frame", null);
var width = GetValue(config, "width", 8);
var height = GetValue(config, "height", 8);
var tile = GetValue(config, "tile", false);
var plane = new Plane(this.scene, 0, 0, key, frame, width, height, tile);
if (addToScene !== void 0) {
config.add = addToScene;
}
var checkerboard = GetValue(config, "checkerboard", null);
if (checkerboard) {
var color1 = GetValue(checkerboard, "color1", 16777215);
var color2 = GetValue(checkerboard, "color2", 255);
var alpha1 = GetValue(checkerboard, "alpha1", 255);
var alpha2 = GetValue(checkerboard, "alpha2", 255);
var checkheight = GetValue(checkerboard, "height", 128);
plane.createCheckerboard(color1, color2, alpha1, alpha2, checkheight);
}
BuildGameObject(this.scene, plane, config);
BuildGameObjectAnimation(plane, config);
return plane;
});
}
),
/***/
30985: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var Plane = __webpack_require__2(33663);
var GameObjectFactory = __webpack_require__2(39429);
GameObjectFactory.register("plane", function(x, y, texture, frame, width, height, tile) {
return this.displayList.add(new Plane(this.scene, x, y, texture, frame, width, height, tile));
});
}
),
/***/
80321: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31401);
var GameObject = __webpack_require__2(95643);
var IntegerToColor = __webpack_require__2(30100);
var PIPELINES_CONST = __webpack_require__2(36060);
var Render = __webpack_require__2(67277);
var PointLight = new Class({
Extends: GameObject,
Mixins: [
Components.AlphaSingle,
Components.BlendMode,
Components.Depth,
Components.Mask,
Components.Pipeline,
Components.PostPipeline,
Components.ScrollFactor,
Components.Transform,
Components.Visible,
Render
],
initialize: function PointLight2(scene, x, y, color, radius, intensity, attenuation) {
if (color === void 0) {
color = 16777215;
}
if (radius === void 0) {
radius = 128;
}
if (intensity === void 0) {
intensity = 1;
}
if (attenuation === void 0) {
attenuation = 0.1;
}
GameObject.call(this, scene, "PointLight");
this.initPipeline(PIPELINES_CONST.POINTLIGHT_PIPELINE);
this.initPostPipeline();
this.setPosition(x, y);
this.color = IntegerToColor(color);
this.intensity = intensity;
this.attenuation = attenuation;
this.width = radius * 2;
this.height = radius * 2;
this._radius = radius;
},
/**
* The radius of the Point Light.
*
* @name Phaser.GameObjects.PointLight#radius
* @type {number}
* @since 3.50.0
*/
radius: {
get: function() {
return this._radius;
},
set: function(value) {
this._radius = value;
this.width = value * 2;
this.height = value * 2;
}
},
originX: {
get: function() {
return 0.5;
}
},
originY: {
get: function() {
return 0.5;
}
},
displayOriginX: {
get: function() {
return this._radius;
}
},
displayOriginY: {
get: function() {
return this._radius;
}
}
});
module2.exports = PointLight;
}
),
/***/
39829: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var BuildGameObject = __webpack_require__2(25305);
var GameObjectCreator = __webpack_require__2(44603);
var GetAdvancedValue = __webpack_require__2(23568);
var PointLight = __webpack_require__2(80321);
GameObjectCreator.register("pointlight", function(config, addToScene) {
if (config === void 0) {
config = {};
}
var color = GetAdvancedValue(config, "color", 16777215);
var radius = GetAdvancedValue(config, "radius", 128);
var intensity = GetAdvancedValue(config, "intensity", 1);
var attenuation = GetAdvancedValue(config, "attenuation", 0.1);
var layer = new PointLight(this.scene, 0, 0, color, radius, intensity, attenuation);
if (addToScene !== void 0) {
config.add = addToScene;
}
BuildGameObject(this.scene, layer, config);
return layer;
});
}
),
/***/
71255: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var GameObjectFactory = __webpack_require__2(39429);
var PointLight = __webpack_require__2(80321);
GameObjectFactory.register("pointlight", function(x, y, color, radius, intensity, attenuation) {
return this.displayList.add(new PointLight(this.scene, x, y, color, radius, intensity, attenuation));
});
}
),
/***/
67277: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(57787);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
57787: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetCalcMatrix = __webpack_require__2(91296);
var PointLightWebGLRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
var pipeline = renderer.pipelines.set(src.pipeline);
var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc;
var width = src.width;
var height = src.height;
var x = -src._radius;
var y = -src._radius;
var xw = x + width;
var yh = y + height;
var lightX = calcMatrix.getX(0, 0);
var lightY = calcMatrix.getY(0, 0);
var tx0 = calcMatrix.getX(x, y);
var ty0 = calcMatrix.getY(x, y);
var tx1 = calcMatrix.getX(x, yh);
var ty1 = calcMatrix.getY(x, yh);
var tx2 = calcMatrix.getX(xw, yh);
var ty2 = calcMatrix.getY(xw, yh);
var tx3 = calcMatrix.getX(xw, y);
var ty3 = calcMatrix.getY(xw, y);
renderer.pipelines.preBatch(src);
pipeline.batchPointLight(src, camera, tx0, ty0, tx1, ty1, tx2, ty2, tx3, ty3, lightX, lightY);
renderer.pipelines.postBatch(src);
};
module2.exports = PointLightWebGLRenderer;
}
),
/***/
591: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var DynamicTexture = __webpack_require__2(81320);
var Image2 = __webpack_require__2(88571);
var RenderTexture = new Class({
Extends: Image2,
initialize: function RenderTexture2(scene, x, y, width, height) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (width === void 0) {
width = 32;
}
if (height === void 0) {
height = 32;
}
var dynamicTexture = new DynamicTexture(scene.sys.textures, "", width, height);
Image2.call(this, scene, x, y, dynamicTexture);
this.type = "RenderTexture";
this.camera = this.texture.camera;
this._saved = false;
},
/**
* Sets the internal size of this Render Texture, as used for frame or physics body creation.
*
* This will not change the size that the Game Object is rendered in-game.
* For that you need to either set the scale of the Game Object (`setScale`) or call the
* `setDisplaySize` method, which is the same thing as changing the scale but allows you
* to do so by giving pixel values.
*
* If you have enabled this Game Object for input, changing the size will _not_ change the
* size of the hit area. To do this you should adjust the `input.hitArea` object directly.
*
* @method Phaser.GameObjects.RenderTexture#setSize
* @since 3.0.0
*
* @param {number} width - The width of this Game Object.
* @param {number} height - The height of this Game Object.
*
* @return {this} This Game Object instance.
*/
setSize: function(width, height) {
this.width = width;
this.height = height;
this.texture.setSize(width, height);
this.updateDisplayOrigin();
var input = this.input;
if (input && !input.customHitArea) {
input.hitArea.width = width;
input.hitArea.height = height;
}
return this;
},
/**
* Resizes the Render Texture to the new dimensions given.
*
* In WebGL it will destroy and then re-create the frame buffer being used by the Render Texture.
* In Canvas it will resize the underlying canvas element.
*
* Both approaches will erase everything currently drawn to the Render Texture.
*
* If the dimensions given are the same as those already being used, calling this method will do nothing.
*
* @method Phaser.GameObjects.RenderTexture#resize
* @since 3.10.0
*
* @param {number} width - The new width of the Render Texture.
* @param {number} [height=width] - The new height of the Render Texture. If not specified, will be set the same as the `width`.
*
* @return {this} This Render Texture.
*/
resize: function(width, height) {
this.setSize(width, height);
return this;
},
/**
* Stores a copy of this Render Texture in the Texture Manager using the given key.
*
* After doing this, any texture based Game Object, such as a Sprite, can use the contents of this
* Render Texture by using the texture key:
*
* ```javascript
* var rt = this.add.renderTexture(0, 0, 128, 128);
*
* // Draw something to the Render Texture
*
* rt.saveTexture('doodle');
*
* this.add.image(400, 300, 'doodle');
* ```
*
* Updating the contents of this Render Texture will automatically update _any_ Game Object
* that is using it as a texture. Calling `saveTexture` again will not save another copy
* of the same texture, it will just rename the key of the existing copy.
*
* By default it will create a single base texture. You can add frames to the texture
* by using the `Texture.add` method. After doing this, you can then allow Game Objects
* to use a specific frame from a Render Texture.
*
* If you destroy this Render Texture, any Game Object using it via the Texture Manager will
* stop rendering. Ensure you remove the texture from the Texture Manager and any Game Objects
* using it first, before destroying this Render Texture.
*
* @method Phaser.GameObjects.RenderTexture#saveTexture
* @since 3.12.0
*
* @param {string} key - The unique key to store the texture as within the global Texture Manager.
*
* @return {Phaser.Textures.DynamicTexture} The Texture that was saved.
*/
saveTexture: function(key) {
var texture = this.texture;
texture.key = key;
if (texture.manager.addDynamicTexture(texture)) {
this._saved = true;
}
return texture;
},
/**
* Fills this Render Texture with the given color.
*
* By default it will fill the entire texture, however you can set it to fill a specific
* rectangular area by using the x, y, width and height arguments.
*
* The color should be given in hex format, i.e. 0xff0000 for red, 0x00ff00 for green, etc.
*
* @method Phaser.GameObjects.RenderTexture#fill
* @since 3.2.0
*
* @param {number} rgb - The color to fill this Render Texture with, such as 0xff0000 for red.
* @param {number} [alpha=1] - The alpha value used by the fill.
* @param {number} [x=0] - The left coordinate of the fill rectangle.
* @param {number} [y=0] - The top coordinate of the fill rectangle.
* @param {number} [width=this.width] - The width of the fill rectangle.
* @param {number} [height=this.height] - The height of the fill rectangle.
*
* @return {this} This Render Texture instance.
*/
fill: function(rgb, alpha, x, y, width, height) {
this.texture.fill(rgb, alpha, x, y, width, height);
return this;
},
/**
* Fully clears this Render Texture, erasing everything from it and resetting it back to
* a blank, transparent, texture.
*
* @method Phaser.GameObjects.RenderTexture#clear
* @since 3.2.0
*
* @return {this} This Render Texture instance.
*/
clear: function() {
this.texture.clear();
return this;
},
/**
* Takes the given texture key and frame and then stamps it at the given
* x and y coordinates. You can use the optional 'config' argument to provide
* lots more options about how the stamp is applied, including the alpha,
* tint, angle, scale and origin.
*
* By default, the frame will stamp on the x/y coordinates based on its center.
*
* If you wish to stamp from the top-left, set the config `originX` and
* `originY` properties both to zero.
*
* @method Phaser.GameObjects.RenderTexture#stamp
* @since 3.60.0
*
* @param {string} key - The key of the texture to be used, as stored in the Texture Manager.
* @param {(string|number)} [frame] - The name or index of the frame within the Texture. Set to `null` to skip this argument if not required.
* @param {number} [x=0] - The x position to draw the frame at.
* @param {number} [y=0] - The y position to draw the frame at.
* @param {Phaser.Types.Textures.StampConfig} [config] - The stamp configuration object, allowing you to set the alpha, tint, angle, scale and origin of the stamp.
*
* @return {this} This Render Texture instance.
*/
stamp: function(key, frame, x, y, config) {
this.texture.stamp(key, frame, x, y, config);
return this;
},
/**
* Draws the given object, or an array of objects, to this Render Texture using a blend mode of ERASE.
* This has the effect of erasing any filled pixels present in the objects from this texture.
*
* It can accept any of the following:
*
* * Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite.
* * Tilemap Layers.
* * A Group. The contents of which will be iterated and drawn in turn.
* * A Container. The contents of which will be iterated fully, and drawn in turn.
* * A Scene Display List. Pass in `Scene.children` to draw the whole list.
* * Another Dynamic Texture, or a Render Texture.
* * A Texture Frame instance.
* * A string. This is used to look-up the texture from the Texture Manager.
*
* Note: You cannot erase a Render Texture from itself.
*
* If passing in a Group or Container it will only draw children that return `true`
* when their `willRender()` method is called. I.e. a Container with 10 children,
* 5 of which have `visible=false` will only draw the 5 visible ones.
*
* If passing in an array of Game Objects it will draw them all, regardless if
* they pass a `willRender` check or not.
*
* You can pass in a string in which case it will look for a texture in the Texture
* Manager matching that string, and draw the base frame.
*
* You can pass in the `x` and `y` coordinates to draw the objects at. The use of
* the coordinates differ based on what objects are being drawn. If the object is
* a Group, Container or Display List, the coordinates are _added_ to the positions
* of the children. For all other types of object, the coordinates are exact.
*
* Calling this method causes the WebGL batch to flush, so it can write the texture
* data to the framebuffer being used internally. The batch is flushed at the end,
* after the entries have been iterated. So if you've a bunch of objects to draw,
* try and pass them in an array in one single call, rather than making lots of
* separate calls.
*
* @method Phaser.GameObjects.RenderTexture#erase
* @since 3.16.0
*
* @param {any} entries - Any renderable Game Object, or Group, Container, Display List, Render Texture, Texture Frame, or an array of any of these.
* @param {number} [x=0] - The x position to draw the Frame at, or the offset applied to the object.
* @param {number} [y=0] - The y position to draw the Frame at, or the offset applied to the object.
*
* @return {this} This Render Texture instance.
*/
erase: function(entries, x, y) {
this.texture.erase(entries, x, y);
return this;
},
/**
* Draws the given object, or an array of objects, to this Render Texture.
*
* It can accept any of the following:
*
* * Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite.
* * Tilemap Layers.
* * A Group. The contents of which will be iterated and drawn in turn.
* * A Container. The contents of which will be iterated fully, and drawn in turn.
* * A Scene Display List. Pass in `Scene.children` to draw the whole list.
* * Another Dynamic Texture, or a Render Texture.
* * A Texture Frame instance.
* * A string. This is used to look-up the texture from the Texture Manager.
*
* Note 1: You cannot draw a Render Texture to itself.
*
* Note 2: For Game Objects that have Post FX Pipelines, the pipeline _cannot_ be
* used when drawn to this texture.
*
* If passing in a Group or Container it will only draw children that return `true`
* when their `willRender()` method is called. I.e. a Container with 10 children,
* 5 of which have `visible=false` will only draw the 5 visible ones.
*
* If passing in an array of Game Objects it will draw them all, regardless if
* they pass a `willRender` check or not.
*
* You can pass in a string in which case it will look for a texture in the Texture
* Manager matching that string, and draw the base frame. If you need to specify
* exactly which frame to draw then use the method `drawFrame` instead.
*
* You can pass in the `x` and `y` coordinates to draw the objects at. The use of
* the coordinates differ based on what objects are being drawn. If the object is
* a Group, Container or Display List, the coordinates are _added_ to the positions
* of the children. For all other types of object, the coordinates are exact.
*
* The `alpha` and `tint` values are only used by Texture Frames.
* Game Objects use their own alpha and tint values when being drawn.
*
* Calling this method causes the WebGL batch to flush, so it can write the texture
* data to the framebuffer being used internally. The batch is flushed at the end,
* after the entries have been iterated. So if you've a bunch of objects to draw,
* try and pass them in an array in one single call, rather than making lots of
* separate calls.
*
* @method Phaser.GameObjects.RenderTexture#draw
* @since 3.2.0
*
* @param {any} entries - Any renderable Game Object, or Group, Container, Display List, other Render Texture, Texture Frame or an array of any of these.
* @param {number} [x=0] - The x position to draw the Frame at, or the offset applied to the object.
* @param {number} [y=0] - The y position to draw the Frame at, or the offset applied to the object.
* @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha.
* @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only.
*
* @return {this} This Render Texture instance.
*/
draw: function(entries, x, y, alpha, tint) {
this.texture.draw(entries, x, y, alpha, tint);
return this;
},
/**
* Draws the Texture Frame to the Render Texture at the given position.
*
* Textures are referenced by their string-based keys, as stored in the Texture Manager.
*
* ```javascript
* var rt = this.add.renderTexture(0, 0, 800, 600);
* rt.drawFrame(key, frame);
* ```
*
* You can optionally provide a position, alpha and tint value to apply to the frame
* before it is drawn.
*
* Calling this method will cause a batch flush, so if you've got a stack of things to draw
* in a tight loop, try using the `draw` method instead.
*
* If you need to draw a Sprite to this Render Texture, use the `draw` method instead.
*
* @method Phaser.GameObjects.RenderTexture#drawFrame
* @since 3.12.0
*
* @param {string} key - The key of the texture to be used, as stored in the Texture Manager.
* @param {(string|number)} [frame] - The name or index of the frame within the Texture. Set to `null` to skip this argument if not required.
* @param {number} [x=0] - The x position to draw the frame at.
* @param {number} [y=0] - The y position to draw the frame at.
* @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture.
* @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. WebGL only.
*
* @return {this} This Render Texture instance.
*/
drawFrame: function(key, frame, x, y, alpha, tint) {
this.texture.drawFrame(key, frame, x, y, alpha, tint);
return this;
},
/**
* Takes the given Texture Frame and draws it to this Render Texture as a fill pattern,
* i.e. in a grid-layout based on the frame dimensions.
*
* Textures are referenced by their string-based keys, as stored in the Texture Manager.
*
* You can optionally provide a position, width, height, alpha and tint value to apply to
* the frames before they are drawn. The position controls the top-left where the repeating
* fill will start from. The width and height control the size of the filled area.
*
* The position can be negative if required, but the dimensions cannot.
*
* Calling this method will cause a batch flush by default. Use the `skipBatch` argument
* to disable this if this call is part of a larger batch draw.
*
* @method Phaser.GameObjects.RenderTexture#repeat
* @since 3.60.0
*
* @param {string} key - The key of the texture to be used, as stored in the Texture Manager.
* @param {(string|number)} [frame] - The name or index of the frame within the Texture. Set to `null` to skip this argument if not required.
* @param {number} [x=0] - The x position to start drawing the frames from (can be negative to offset).
* @param {number} [y=0] - The y position to start drawing the frames from (can be negative to offset).
* @param {number} [width=this.width] - The width of the area to repeat the frame within. Defaults to the width of this Dynamic Texture.
* @param {number} [height=this.height] - The height of the area to repeat the frame within. Defaults to the height of this Dynamic Texture.
* @param {number} [alpha=1] - The alpha to use. Defaults to 1, no alpha.
* @param {number} [tint=0xffffff] - WebGL only. The tint color to use. Leave as undefined, or 0xffffff to have no tint.
* @param {boolean} [skipBatch=false] - Skip beginning and ending a batch with this call. Use if this is part of a bigger batched draw.
*
* @return {this} This Render Texture instance.
*/
repeat: function(key, frame, x, y, width, height, alpha, tint, skipBatch) {
this.texture.repeat(key, frame, x, y, width, height, alpha, tint, skipBatch);
return this;
},
/**
* Use this method if you need to batch draw a large number of Game Objects to
* this Render Texture in a single pass, or on a frequent basis. This is especially
* useful under WebGL, however, if your game is using Canvas only, it will not make
* any speed difference in that situation.
*
* This method starts the beginning of a batched draw, unless one is already open.
*
* Batched drawing is faster than calling `draw` in loop, but you must be careful
* to manage the flow of code and remember to call `endDraw()` when you're finished.
*
* If you don't need to draw large numbers of objects it's much safer and easier
* to use the `draw` method instead.
*
* The flow should be:
*
* ```javascript
* // Call once:
* RenderTexture.beginDraw();
*
* // repeat n times:
* RenderTexture.batchDraw();
* // or
* RenderTexture.batchDrawFrame();
*
* // Call once:
* RenderTexture.endDraw();
* ```
*
* Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you
* have started a batch. Also, be very careful not to destroy this Render Texture while the
* batch is still open. Doing so will cause a run-time error in the WebGL Renderer.
*
* You can use the `RenderTexture.texture.isDrawing` boolean property to tell if a batch is
* currently open, or not.
*
* @method Phaser.GameObjects.RenderTexture#beginDraw
* @since 3.50.0
*
* @return {this} This Render Texture instance.
*/
beginDraw: function() {
this.texture.beginDraw();
return this;
},
/**
* Use this method if you have already called `beginDraw` and need to batch
* draw a large number of objects to this Render Texture.
*
* This method batches the drawing of the given objects to this texture,
* without causing a WebGL bind or batch flush for each one.
*
* It is faster than calling `draw`, but you must be careful to manage the
* flow of code and remember to call `endDraw()`. If you don't need to draw large
* numbers of objects it's much safer and easier to use the `draw` method instead.
*
* The flow should be:
*
* ```javascript
* // Call once:
* RenderTexture.beginDraw();
*
* // repeat n times:
* RenderTexture.batchDraw();
* // or
* RenderTexture.batchDrawFrame();
*
* // Call once:
* RenderTexture.endDraw();
* ```
*
* Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you
* have started a batch. Also, be very careful not to destroy this Render Texture while the
* batch is still open. Doing so will cause a run-time error in the WebGL Renderer.
*
* You can use the `RenderTexture.texture.isDrawing` boolean property to tell if a batch is
* currently open, or not.
*
* This method can accept any of the following:
*
* * Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite.
* * Tilemap Layers.
* * A Group. The contents of which will be iterated and drawn in turn.
* * A Container. The contents of which will be iterated fully, and drawn in turn.
* * A Scene's Display List. Pass in `Scene.children` to draw the whole list.
* * Another Dynamic Texture or Render Texture.
* * A Texture Frame instance.
* * A string. This is used to look-up a texture from the Texture Manager.
*
* Note: You cannot draw a Render Texture to itself.
*
* If passing in a Group or Container it will only draw children that return `true`
* when their `willRender()` method is called. I.e. a Container with 10 children,
* 5 of which have `visible=false` will only draw the 5 visible ones.
*
* If passing in an array of Game Objects it will draw them all, regardless if
* they pass a `willRender` check or not.
*
* You can pass in a string in which case it will look for a texture in the Texture
* Manager matching that string, and draw the base frame. If you need to specify
* exactly which frame to draw then use the method `drawFrame` instead.
*
* You can pass in the `x` and `y` coordinates to draw the objects at. The use of
* the coordinates differ based on what objects are being drawn. If the object is
* a Group, Container or Display List, the coordinates are _added_ to the positions
* of the children. For all other types of object, the coordinates are exact.
*
* The `alpha` and `tint` values are only used by Texture Frames.
* Game Objects use their own alpha and tint values when being drawn.
*
* @method Phaser.GameObjects.RenderTexture#batchDraw
* @since 3.50.0
*
* @param {any} entries - Any renderable Game Object, or Group, Container, Display List, other Dynamic or Texture, Texture Frame or an array of any of these.
* @param {number} [x=0] - The x position to draw the Frame at, or the offset applied to the object.
* @param {number} [y=0] - The y position to draw the Frame at, or the offset applied to the object.
* @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha.
* @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only.
*
* @return {this} This Render Texture instance.
*/
batchDraw: function(entries, x, y, alpha, tint) {
this.texture.batchDraw(entries, x, y, alpha, tint);
return this;
},
/**
* Use this method if you have already called `beginDraw` and need to batch
* draw a large number of texture frames to this Render Texture.
*
* This method batches the drawing of the given frames to this Render Texture,
* without causing a WebGL bind or batch flush for each one.
*
* It is faster than calling `drawFrame`, but you must be careful to manage the
* flow of code and remember to call `endDraw()`. If you don't need to draw large
* numbers of frames it's much safer and easier to use the `drawFrame` method instead.
*
* The flow should be:
*
* ```javascript
* // Call once:
* RenderTexture.beginDraw();
*
* // repeat n times:
* RenderTexture.batchDraw();
* // or
* RenderTexture.batchDrawFrame();
*
* // Call once:
* RenderTexture.endDraw();
* ```
*
* Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you
* have started a batch. Also, be very careful not to destroy this Render Texture while the
* batch is still open. Doing so will cause a run-time error in the WebGL Renderer.
*
* You can use the `RenderTexture.texture.isDrawing` boolean property to tell if a batch is
* currently open, or not.
*
* Textures are referenced by their string-based keys, as stored in the Texture Manager.
*
* You can optionally provide a position, alpha and tint value to apply to the frame
* before it is drawn.
*
* @method Phaser.GameObjects.RenderTexture#batchDrawFrame
* @since 3.50.0
*
* @param {string} key - The key of the texture to be used, as stored in the Texture Manager.
* @param {(string|number)} [frame] - The name or index of the frame within the Texture.
* @param {number} [x=0] - The x position to draw the frame at.
* @param {number} [y=0] - The y position to draw the frame at.
* @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha.
* @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only.
*
* @return {this} This Render Texture instance.
*/
batchDrawFrame: function(key, frame, x, y, alpha, tint) {
this.texture.batchDrawFrame(key, frame, x, y, alpha, tint);
return this;
},
/**
* Use this method to finish batch drawing to this Render Texture.
*
* Doing so will stop the WebGL Renderer from capturing draws and then blit the
* framebuffer to the Render Target owned by this texture.
*
* Calling this method without first calling `beginDraw` will have no effect.
*
* Batch drawing is faster than calling `draw`, but you must be careful to manage the
* flow of code and remember to call `endDraw()` when you're finished.
*
* If you don't need to draw large numbers of objects it's much safer and easier
* to use the `draw` method instead.
*
* The flow should be:
*
* ```javascript
* // Call once:
* RenderTexture.beginDraw();
*
* // repeat n times:
* RenderTexture.batchDraw();
* // or
* RenderTexture.batchDrawFrame();
*
* // Call once:
* RenderTexture.endDraw();
* ```
*
* Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you
* have started a batch. Also, be very careful not to destroy this Render Texture while the
* batch is still open. Doing so will cause a run-time error in the WebGL Renderer.
*
* You can use the `RenderTexture.texture.isDrawing` boolean property to tell if a batch is
* currently open, or not.
*
* @method Phaser.GameObjects.RenderTexture#endDraw
* @since 3.50.0
*
* @param {boolean} [erase=false] - Draws all objects in this batch using a blend mode of ERASE. This has the effect of erasing any filled pixels in the objects being drawn.
*
* @return {this} This Render Texture instance.
*/
endDraw: function(erase) {
this.texture.endDraw(erase);
return this;
},
/**
* Takes a snapshot of the given area of this Render Texture.
*
* The snapshot is taken immediately, but the results are returned via the given callback.
*
* To capture the whole Render Texture see the `snapshot` method.
* To capture just a specific pixel, see the `snapshotPixel` method.
*
* Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer
* into an ArrayBufferView. It then parses this, copying the contents to a temporary Canvas and finally
* creating an Image object from it, which is the image returned to the callback provided.
*
* All in all, this is a computationally expensive and blocking process, which gets more expensive
* the larger the resolution this Render Texture has, so please be careful how you employ this in your game.
*
* @method Phaser.GameObjects.RenderTexture#snapshotArea
* @since 3.19.0
*
* @param {number} x - The x coordinate to grab from.
* @param {number} y - The y coordinate to grab from.
* @param {number} width - The width of the area to grab.
* @param {number} height - The height of the area to grab.
* @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created.
* @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`.
* @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`.
*
* @return {this} This Render Texture instance.
*/
snapshotArea: function(x, y, width, height, callback, type, encoderOptions) {
this.texture.snapshotArea(x, y, width, height, callback, type, encoderOptions);
return this;
},
/**
* Takes a snapshot of the whole of this Render Texture.
*
* The snapshot is taken immediately, but the results are returned via the given callback.
*
* To capture a portion of this Render Texture see the `snapshotArea` method.
* To capture just a specific pixel, see the `snapshotPixel` method.
*
* Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer
* into an ArrayBufferView. It then parses this, copying the contents to a temporary Canvas and finally
* creating an Image object from it, which is the image returned to the callback provided.
*
* All in all, this is a computationally expensive and blocking process, which gets more expensive
* the larger the resolution this Render Texture has, so please be careful how you employ this in your game.
*
* @method Phaser.GameObjects.RenderTexture#snapshot
* @since 3.19.0
*
* @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created.
* @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`.
* @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`.
*
* @return {this} This Render Texture instance.
*/
snapshot: function(callback, type, encoderOptions) {
return this.snapshotArea(0, 0, this.width, this.height, callback, type, encoderOptions);
},
/**
* Takes a snapshot of the given pixel from this Render Texture.
*
* The snapshot is taken immediately, but the results are returned via the given callback.
*
* To capture the whole Render Texture see the `snapshot` method.
* To capture a portion of this Render Texture see the `snapshotArea` method.
*
* Unlike the two other snapshot methods, this one will send your callback a `Color` object
* containing the color data for the requested pixel. It doesn't need to create an internal
* Canvas or Image object, so is a lot faster to execute, using less memory than the other snapshot methods.
*
* @method Phaser.GameObjects.RenderTexture#snapshotPixel
* @since 3.19.0
*
* @param {number} x - The x coordinate of the pixel to get.
* @param {number} y - The y coordinate of the pixel to get.
* @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot pixel data is extracted.
*
* @return {this} This Render Texture instance.
*/
snapshotPixel: function(x, y, callback) {
return this.snapshotArea(x, y, 1, 1, callback, "pixel");
},
/**
* Internal destroy handler, called as part of the destroy process.
*
* @method Phaser.GameObjects.RenderTexture#preDestroy
* @protected
* @since 3.9.0
*/
preDestroy: function() {
this.camera = null;
if (!this._saved) {
this.texture.destroy();
}
}
});
module2.exports = RenderTexture;
}
),
/***/
34495: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var BuildGameObject = __webpack_require__2(25305);
var GameObjectCreator = __webpack_require__2(44603);
var GetAdvancedValue = __webpack_require__2(23568);
var RenderTexture = __webpack_require__2(591);
GameObjectCreator.register("renderTexture", function(config, addToScene) {
if (config === void 0) {
config = {};
}
var x = GetAdvancedValue(config, "x", 0);
var y = GetAdvancedValue(config, "y", 0);
var width = GetAdvancedValue(config, "width", 32);
var height = GetAdvancedValue(config, "height", 32);
var renderTexture = new RenderTexture(this.scene, x, y, width, height);
if (addToScene !== void 0) {
config.add = addToScene;
}
BuildGameObject(this.scene, renderTexture, config);
return renderTexture;
});
}
),
/***/
60505: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var GameObjectFactory = __webpack_require__2(39429);
var RenderTexture = __webpack_require__2(591);
GameObjectFactory.register("renderTexture", function(x, y, width, height) {
return this.displayList.add(new RenderTexture(this.scene, x, y, width, height));
});
}
),
/***/
77757: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var AnimationState = __webpack_require__2(9674);
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31401);
var GameObject = __webpack_require__2(95643);
var PIPELINE_CONST = __webpack_require__2(36060);
var RopeRender = __webpack_require__2(38745);
var Vector2 = __webpack_require__2(26099);
var Rope = new Class({
Extends: GameObject,
Mixins: [
Components.AlphaSingle,
Components.BlendMode,
Components.Depth,
Components.Flip,
Components.Mask,
Components.Pipeline,
Components.PostPipeline,
Components.Size,
Components.Texture,
Components.Transform,
Components.Visible,
Components.ScrollFactor,
RopeRender
],
initialize: function Rope2(scene, x, y, texture, frame, points, horizontal, colors, alphas) {
if (texture === void 0) {
texture = "__DEFAULT";
}
if (points === void 0) {
points = 2;
}
if (horizontal === void 0) {
horizontal = true;
}
GameObject.call(this, scene, "Rope");
this.anims = new AnimationState(this);
this.points = points;
this.vertices;
this.uv;
this.colors;
this.alphas;
this.tintFill = texture === "__DEFAULT" ? true : false;
this.dirty = false;
this.horizontal = horizontal;
this._flipX = false;
this._flipY = false;
this._perp = new Vector2();
this.debugCallback = null;
this.debugGraphic = null;
this.setTexture(texture, frame);
this.setPosition(x, y);
this.setSizeToFrame();
this.initPipeline(PIPELINE_CONST.ROPE_PIPELINE);
this.initPostPipeline();
if (Array.isArray(points)) {
this.resizeArrays(points.length);
}
this.setPoints(points, colors, alphas);
this.updateVertices();
},
// Overrides Game Object method
addedToScene: function() {
this.scene.sys.updateList.add(this);
},
// Overrides Game Object method
removedFromScene: function() {
this.scene.sys.updateList.remove(this);
},
/**
* The Rope update loop.
*
* @method Phaser.GameObjects.Rope#preUpdate
* @protected
* @since 3.23.0
*
* @param {number} time - The current timestamp.
* @param {number} delta - The delta time, in ms, elapsed since the last frame.
*/
preUpdate: function(time, delta) {
var prevFrame = this.anims.currentFrame;
this.anims.update(time, delta);
if (this.anims.currentFrame !== prevFrame) {
this.updateUVs();
this.updateVertices();
}
},
/**
* Start playing the given animation.
*
* @method Phaser.GameObjects.Rope#play
* @since 3.23.0
*
* @param {string} key - The string-based key of the animation to play.
* @param {boolean} [ignoreIfPlaying=false] - If an animation is already playing then ignore this call.
* @param {number} [startFrame=0] - Optionally start the animation playing from this frame index.
*
* @return {this} This Game Object.
*/
play: function(key, ignoreIfPlaying, startFrame) {
this.anims.play(key, ignoreIfPlaying, startFrame);
return this;
},
/**
* Flags this Rope as being dirty. A dirty rope will recalculate all of its vertices data
* the _next_ time it renders. You should set this rope as dirty if you update the points
* array directly.
*
* @method Phaser.GameObjects.Rope#setDirty
* @since 3.23.0
*
* @return {this} This Game Object instance.
*/
setDirty: function() {
this.dirty = true;
return this;
},
/**
* Sets the alignment of the points in this Rope to be horizontal, in a strip format.
*
* Calling this method will reset this Rope. The current points, vertices, colors and alpha
* values will be reset to thoes values given as parameters.
*
* @method Phaser.GameObjects.Rope#setHorizontal
* @since 3.23.0
*
* @param {(number|Phaser.Types.Math.Vector2Like[])} [points] - An array containing the vertices data for this Rope, or a number that indicates how many segments to split the texture frame into. If none is provided the current points length is used.
* @param {(number|number[])} [colors] - Either a single color value, or an array of values.
* @param {(number|number[])} [alphas] - Either a single alpha value, or an array of values.
*
* @return {this} This Game Object instance.
*/
setHorizontal: function(points, colors, alphas) {
if (points === void 0) {
points = this.points.length;
}
if (this.horizontal) {
return this;
}
this.horizontal = true;
return this.setPoints(points, colors, alphas);
},
/**
* Sets the alignment of the points in this Rope to be vertical, in a column format.
*
* Calling this method will reset this Rope. The current points, vertices, colors and alpha
* values will be reset to thoes values given as parameters.
*
* @method Phaser.GameObjects.Rope#setVertical
* @since 3.23.0
*
* @param {(number|Phaser.Types.Math.Vector2Like[])} [points] - An array containing the vertices data for this Rope, or a number that indicates how many segments to split the texture frame into. If none is provided the current points length is used.
* @param {(number|number[])} [colors] - Either a single color value, or an array of values.
* @param {(number|number[])} [alphas] - Either a single alpha value, or an array of values.
*
* @return {this} This Game Object instance.
*/
setVertical: function(points, colors, alphas) {
if (points === void 0) {
points = this.points.length;
}
if (!this.horizontal) {
return this;
}
this.horizontal = false;
return this.setPoints(points, colors, alphas);
},
/**
* Sets the tint fill mode.
*
* Mode 0 (`false`) is an additive tint, the default, which blends the vertices colors with the texture.
* This mode respects the texture alpha.
*
* Mode 1 (`true`) is a fill tint. Unlike an additive tint, a fill-tint literally replaces the pixel colors
* from the texture with those in the tint. You can use this for effects such as making a player flash 'white'
* if hit by something. This mode respects the texture alpha.
*
* See the `setColors` method for details of how to color each of the vertices.
*
* @method Phaser.GameObjects.Rope#setTintFill
* @webglOnly
* @since 3.23.0
*
* @param {boolean} [value=false] - Set to `false` for an Additive tint or `true` fill tint with alpha.
*
* @return {this} This Game Object instance.
*/
setTintFill: function(value) {
if (value === void 0) {
value = false;
}
this.tintFill = value;
return this;
},
/**
* Set the alpha values used by the Rope during rendering.
*
* You can provide the values in a number of ways:
*
* 1) One single numeric value: `setAlphas(0.5)` - This will set a single alpha for the whole Rope.
* 2) Two numeric value: `setAlphas(1, 0.5)` - This will set a 'top' and 'bottom' alpha value across the whole Rope.
* 3) An array of values: `setAlphas([ 1, 0.5, 0.2 ])`
*
* If you provide an array of values and the array has exactly the same number of values as `points` in the Rope, it
* will use each alpha value per rope segment.
*
* If the provided array has a different number of values than `points` then it will use the values in order, from
* the first Rope segment and on, until it runs out of values. This allows you to control the alpha values at all
* vertices in the Rope.
*
* Note this method is called `setAlphas` (plural) and not `setAlpha`.
*
* @method Phaser.GameObjects.Rope#setAlphas
* @since 3.23.0
*
* @param {(number|number[])} [alphas] - Either a single alpha value, or an array of values. If nothing is provided alpha is reset to 1.
* @param {number} [bottomAlpha] - An optional bottom alpha value. See the method description for details.
*
* @return {this} This Game Object instance.
*/
setAlphas: function(alphas, bottomAlpha) {
var total = this.points.length;
if (total < 1) {
return this;
}
var currentAlphas = this.alphas;
if (alphas === void 0) {
alphas = [1];
} else if (!Array.isArray(alphas) && bottomAlpha === void 0) {
alphas = [alphas];
}
var i;
var index = 0;
if (bottomAlpha !== void 0) {
for (i = 0; i < total; i++) {
index = i * 2;
currentAlphas[index] = alphas;
currentAlphas[index + 1] = bottomAlpha;
}
} else if (alphas.length === total) {
for (i = 0; i < total; i++) {
index = i * 2;
currentAlphas[index] = alphas[i];
currentAlphas[index + 1] = alphas[i];
}
} else {
var prevAlpha = alphas[0];
for (i = 0; i < total; i++) {
index = i * 2;
if (alphas.length > index) {
prevAlpha = alphas[index];
}
currentAlphas[index] = prevAlpha;
if (alphas.length > index + 1) {
prevAlpha = alphas[index + 1];
}
currentAlphas[index + 1] = prevAlpha;
}
}
return this;
},
/**
* Set the color values used by the Rope during rendering.
*
* Colors are used to control the level of tint applied across the Rope texture.
*
* You can provide the values in a number of ways:
*
* * One single numeric value: `setColors(0xff0000)` - This will set a single color tint for the whole Rope.
* * An array of values: `setColors([ 0xff0000, 0x00ff00, 0x0000ff ])`
*
* If you provide an array of values and the array has exactly the same number of values as `points` in the Rope, it
* will use each color per rope segment.
*
* If the provided array has a different number of values than `points` then it will use the values in order, from
* the first Rope segment and on, until it runs out of values. This allows you to control the color values at all
* vertices in the Rope.
*
* @method Phaser.GameObjects.Rope#setColors
* @since 3.23.0
*
* @param {(number|number[])} [colors] - Either a single color value, or an array of values. If nothing is provided color is reset to 0xffffff.
*
* @return {this} This Game Object instance.
*/
setColors: function(colors) {
var total = this.points.length;
if (total < 1) {
return this;
}
var currentColors = this.colors;
if (colors === void 0) {
colors = [16777215];
} else if (!Array.isArray(colors)) {
colors = [colors];
}
var i;
var index = 0;
if (colors.length === total) {
for (i = 0; i < total; i++) {
index = i * 2;
currentColors[index] = colors[i];
currentColors[index + 1] = colors[i];
}
} else {
var prevColor = colors[0];
for (i = 0; i < total; i++) {
index = i * 2;
if (colors.length > index) {
prevColor = colors[index];
}
currentColors[index] = prevColor;
if (colors.length > index + 1) {
prevColor = colors[index + 1];
}
currentColors[index + 1] = prevColor;
}
}
return this;
},
/**
* Sets the points used by this Rope.
*
* The points should be provided as an array of Vector2, or vector2-like objects (i.e. those with public x/y properties).
*
* Each point corresponds to one segment of the Rope. The more points in the array, the more segments the rope has.
*
* Point coordinates are given in local-space, not world-space, and are directly related to the size of the texture
* this Rope object is using.
*
* For example, a Rope using a 512 px wide texture, split into 4 segments (128px each) would use the following points:
*
* ```javascript
* rope.setPoints([
* { x: 0, y: 0 },
* { x: 128, y: 0 },
* { x: 256, y: 0 },
* { x: 384, y: 0 }
* ]);
* ```
*
* Or, you can provide an integer to do the same thing:
*
* ```javascript
* rope.setPoints(4);
* ```
*
* Which will divide the Rope into 4 equally sized segments based on the frame width.
*
* Note that calling this method with a different number of points than the Rope has currently will
* _reset_ the color and alpha values, unless you provide them as arguments to this method.
*
* @method Phaser.GameObjects.Rope#setPoints
* @since 3.23.0
*
* @param {(number|Phaser.Types.Math.Vector2Like[])} [points=2] - An array containing the vertices data for this Rope, or a number that indicates how many segments to split the texture frame into. If none is provided a simple quad is created.
* @param {(number|number[])} [colors] - Either a single color value, or an array of values.
* @param {(number|number[])} [alphas] - Either a single alpha value, or an array of values.
*
* @return {this} This Game Object instance.
*/
setPoints: function(points, colors, alphas) {
if (points === void 0) {
points = 2;
}
if (typeof points === "number") {
var segments = points;
if (segments < 2) {
segments = 2;
}
points = [];
var s;
var frameSegment;
var offset;
if (this.horizontal) {
offset = -this.frame.halfWidth;
frameSegment = this.frame.width / (segments - 1);
for (s = 0; s < segments; s++) {
points.push({ x: offset + s * frameSegment, y: 0 });
}
} else {
offset = -this.frame.halfHeight;
frameSegment = this.frame.height / (segments - 1);
for (s = 0; s < segments; s++) {
points.push({ x: 0, y: offset + s * frameSegment });
}
}
}
var total = points.length;
var currentTotal = this.points.length;
if (total < 1) {
console.warn("Rope: Not enough points given");
return this;
} else if (total === 1) {
points.unshift({ x: 0, y: 0 });
total++;
}
if (currentTotal !== total) {
this.resizeArrays(total);
}
this.dirty = true;
this.points = points;
this.updateUVs();
if (colors !== void 0 && colors !== null) {
this.setColors(colors);
}
if (alphas !== void 0 && alphas !== null) {
this.setAlphas(alphas);
}
return this;
},
/**
* Updates all of the UVs based on the Rope.points and `flipX` and `flipY` settings.
*
* @method Phaser.GameObjects.Rope#updateUVs
* @since 3.23.0
*
* @return {this} This Game Object instance.
*/
updateUVs: function() {
var currentUVs = this.uv;
var total = this.points.length;
var u0 = this.frame.u0;
var v0 = this.frame.v0;
var u1 = this.frame.u1;
var v1 = this.frame.v1;
var partH = (u1 - u0) / (total - 1);
var partV = (v1 - v0) / (total - 1);
for (var i = 0; i < total; i++) {
var index = i * 4;
var uv0;
var uv1;
var uv2;
var uv3;
if (this.horizontal) {
if (this._flipX) {
uv0 = u1 - i * partH;
uv2 = u1 - i * partH;
} else {
uv0 = u0 + i * partH;
uv2 = u0 + i * partH;
}
if (this._flipY) {
uv1 = v1;
uv3 = v0;
} else {
uv1 = v0;
uv3 = v1;
}
} else {
if (this._flipX) {
uv0 = u0;
uv2 = u1;
} else {
uv0 = u1;
uv2 = u0;
}
if (this._flipY) {
uv1 = v1 - i * partV;
uv3 = v1 - i * partV;
} else {
uv1 = v0 + i * partV;
uv3 = v0 + i * partV;
}
}
currentUVs[index + 0] = uv0;
currentUVs[index + 1] = uv1;
currentUVs[index + 2] = uv2;
currentUVs[index + 3] = uv3;
}
return this;
},
/**
* Resizes all of the internal arrays: `vertices`, `uv`, `colors` and `alphas` to the new
* given Rope segment total.
*
* @method Phaser.GameObjects.Rope#resizeArrays
* @since 3.23.0
*
* @param {number} newSize - The amount of segments to split the Rope in to.
*
* @return {this} This Game Object instance.
*/
resizeArrays: function(newSize) {
var colors = this.colors;
var alphas = this.alphas;
this.vertices = new Float32Array(newSize * 4);
this.uv = new Float32Array(newSize * 4);
colors = new Uint32Array(newSize * 2);
alphas = new Float32Array(newSize * 2);
for (var i = 0; i < newSize * 2; i++) {
colors[i] = 16777215;
alphas[i] = 1;
}
this.colors = colors;
this.alphas = alphas;
this.dirty = true;
return this;
},
/**
* Updates the vertices based on the Rope points.
*
* This method is called automatically during rendering if `Rope.dirty` is `true`, which is set
* by the `setPoints` and `setDirty` methods. You should flag the Rope as being dirty if you modify
* the Rope points directly.
*
* @method Phaser.GameObjects.Rope#updateVertices
* @since 3.23.0
*
* @return {this} This Game Object instance.
*/
updateVertices: function() {
var perp = this._perp;
var points = this.points;
var vertices = this.vertices;
var total = points.length;
this.dirty = false;
if (total < 1) {
return;
}
var nextPoint;
var lastPoint = points[0];
var frameSize = this.horizontal ? this.frame.halfHeight : this.frame.halfWidth;
for (var i = 0; i < total; i++) {
var point = points[i];
var index = i * 4;
if (i < total - 1) {
nextPoint = points[i + 1];
} else {
nextPoint = point;
}
perp.x = nextPoint.y - lastPoint.y;
perp.y = -(nextPoint.x - lastPoint.x);
var perpLength = perp.length();
perp.x /= perpLength;
perp.y /= perpLength;
perp.x *= frameSize;
perp.y *= frameSize;
vertices[index] = point.x + perp.x;
vertices[index + 1] = point.y + perp.y;
vertices[index + 2] = point.x - perp.x;
vertices[index + 3] = point.y - perp.y;
lastPoint = point;
}
return this;
},
/**
* This method enables rendering of the Rope vertices to the given Graphics instance.
*
* If you enable this feature, you **must** call `Graphics.clear()` in your Scene `update`,
* otherwise the Graphics instance you provide to debug will fill-up with draw calls,
* eventually crashing the browser. This is not done automatically to allow you to debug
* draw multiple Rope objects to a single Graphics instance.
*
* The Rope class has a built-in debug rendering callback `Rope.renderDebugVerts`, however
* you can also provide your own callback to be used instead. Do this by setting the `callback` parameter.
*
* The callback is invoked _once per render_ and sent the following parameters:
*
* `callback(src, meshLength, verts)`
*
* `src` is the Rope instance being debugged.
* `meshLength` is the number of mesh vertices in total.
* `verts` is an array of the translated vertex coordinates.
*
* If using your own callback you do not have to provide a Graphics instance to this method.
*
* To disable debug rendering, to either your own callback or the built-in one, call this method
* with no arguments.
*
* @method Phaser.GameObjects.Rope#setDebug
* @since 3.23.0
*
* @param {Phaser.GameObjects.Graphics} [graphic] - The Graphic instance to render to if using the built-in callback.
* @param {function} [callback] - The callback to invoke during debug render. Leave as undefined to use the built-in callback.
*
* @return {this} This Game Object instance.
*/
setDebug: function(graphic, callback) {
this.debugGraphic = graphic;
if (!graphic && !callback) {
this.debugCallback = null;
} else if (!callback) {
this.debugCallback = this.renderDebugVerts;
} else {
this.debugCallback = callback;
}
return this;
},
/**
* The built-in Rope vertices debug rendering method.
*
* See `Rope.setDebug` for more details.
*
* @method Phaser.GameObjects.Rope#renderDebugVerts
* @since 3.23.0
*
* @param {Phaser.GameObjects.Rope} src - The Rope object being rendered.
* @param {number} meshLength - The number of vertices in the mesh.
* @param {number[]} verts - An array of translated vertex coordinates.
*/
renderDebugVerts: function(src, meshLength, verts) {
var graphic = src.debugGraphic;
var px0 = verts[0];
var py0 = verts[1];
var px1 = verts[2];
var py1 = verts[3];
graphic.lineBetween(px0, py0, px1, py1);
for (var i = 4; i < meshLength; i += 4) {
var x0 = verts[i + 0];
var y0 = verts[i + 1];
var x1 = verts[i + 2];
var y1 = verts[i + 3];
graphic.lineBetween(px0, py0, x0, y0);
graphic.lineBetween(px1, py1, x1, y1);
graphic.lineBetween(px1, py1, x0, y0);
graphic.lineBetween(x0, y0, x1, y1);
px0 = x0;
py0 = y0;
px1 = x1;
py1 = y1;
}
},
/**
* Handles the pre-destroy step for the Rope, which removes the Animation component and typed arrays.
*
* @method Phaser.GameObjects.Rope#preDestroy
* @private
* @since 3.23.0
*/
preDestroy: function() {
this.anims.destroy();
this.anims = void 0;
this.points = null;
this.vertices = null;
this.uv = null;
this.colors = null;
this.alphas = null;
this.debugCallback = null;
this.debugGraphic = null;
},
/**
* The horizontally flipped state of the Game Object.
*
* A Game Object that is flipped horizontally will render inversed on the horizontal axis.
* Flipping always takes place from the middle of the texture and does not impact the scale value.
* If this Game Object has a physics body, it will not change the body. This is a rendering toggle only.
*
* @name Phaser.GameObjects.Rope#flipX
* @type {boolean}
* @default false
* @since 3.23.0
*/
flipX: {
get: function() {
return this._flipX;
},
set: function(value) {
this._flipX = value;
return this.updateUVs();
}
},
/**
* The vertically flipped state of the Game Object.
*
* A Game Object that is flipped vertically will render inversed on the vertical axis (i.e. upside down)
* Flipping always takes place from the middle of the texture and does not impact the scale value.
* If this Game Object has a physics body, it will not change the body. This is a rendering toggle only.
*
* @name Phaser.GameObjects.Rope#flipY
* @type {boolean}
* @default false
* @since 3.23.0
*/
flipY: {
get: function() {
return this._flipY;
},
set: function(value) {
this._flipY = value;
return this.updateUVs();
}
}
});
module2.exports = Rope;
}
),
/***/
95262: (
/***/
(module2) => {
var RopeCanvasRenderer = function() {
};
module2.exports = RopeCanvasRenderer;
}
),
/***/
26209: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var BuildGameObject = __webpack_require__2(25305);
var GameObjectCreator = __webpack_require__2(44603);
var GetAdvancedValue = __webpack_require__2(23568);
var GetValue = __webpack_require__2(35154);
var Rope = __webpack_require__2(77757);
GameObjectCreator.register("rope", function(config, addToScene) {
if (config === void 0) {
config = {};
}
var key = GetAdvancedValue(config, "key", null);
var frame = GetAdvancedValue(config, "frame", null);
var horizontal = GetAdvancedValue(config, "horizontal", true);
var points = GetValue(config, "points", void 0);
var colors = GetValue(config, "colors", void 0);
var alphas = GetValue(config, "alphas", void 0);
var rope = new Rope(this.scene, 0, 0, key, frame, points, horizontal, colors, alphas);
if (addToScene !== void 0) {
config.add = addToScene;
}
BuildGameObject(this.scene, rope, config);
return rope;
});
}
),
/***/
96819: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var Rope = __webpack_require__2(77757);
var GameObjectFactory = __webpack_require__2(39429);
if (true) {
GameObjectFactory.register("rope", function(x, y, texture, frame, points, horizontal, colors, alphas) {
return this.displayList.add(new Rope(this.scene, x, y, texture, frame, points, horizontal, colors, alphas));
});
}
}
),
/***/
38745: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(20439);
}
if (true) {
renderCanvas = __webpack_require__2(95262);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
20439: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetCalcMatrix = __webpack_require__2(91296);
var Utils = __webpack_require__2(70554);
var RopeWebGLRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
var pipeline = renderer.pipelines.set(src.pipeline, src);
var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc;
var vertices = src.vertices;
var uvs = src.uv;
var colors = src.colors;
var alphas = src.alphas;
var alpha = src.alpha;
var getTint = Utils.getTintAppendFloatAlpha;
var roundPixels = camera.roundPixels;
var meshVerticesLength = vertices.length;
var vertexCount = Math.floor(meshVerticesLength * 0.5);
pipeline.flush();
renderer.pipelines.preBatch(src);
var textureUnit = pipeline.setGameObject(src);
var vertexViewF32 = pipeline.vertexViewF32;
var vertexViewU32 = pipeline.vertexViewU32;
var vertexOffset = pipeline.vertexCount * pipeline.currentShader.vertexComponentCount - 1;
var colorIndex = 0;
var tintEffect = src.tintFill;
if (src.dirty) {
src.updateVertices();
}
var debugCallback = src.debugCallback;
var debugVerts = [];
for (var i = 0; i < meshVerticesLength; i += 2) {
var x = vertices[i + 0];
var y = vertices[i + 1];
var tx = x * calcMatrix.a + y * calcMatrix.c + calcMatrix.e;
var ty = x * calcMatrix.b + y * calcMatrix.d + calcMatrix.f;
if (roundPixels) {
tx = Math.round(tx);
ty = Math.round(ty);
}
vertexViewF32[++vertexOffset] = tx;
vertexViewF32[++vertexOffset] = ty;
vertexViewF32[++vertexOffset] = uvs[i + 0];
vertexViewF32[++vertexOffset] = uvs[i + 1];
vertexViewF32[++vertexOffset] = textureUnit;
vertexViewF32[++vertexOffset] = tintEffect;
vertexViewU32[++vertexOffset] = getTint(colors[colorIndex], camera.alpha * (alphas[colorIndex] * alpha));
colorIndex++;
if (debugCallback) {
debugVerts[i + 0] = tx;
debugVerts[i + 1] = ty;
}
}
if (debugCallback) {
debugCallback.call(src, src, meshVerticesLength, debugVerts);
}
pipeline.vertexCount += vertexCount;
pipeline.currentBatch.count = pipeline.vertexCount - pipeline.currentBatch.start;
renderer.pipelines.postBatch(src);
};
module2.exports = RopeWebGLRenderer;
}
),
/***/
20071: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31401);
var GameObject = __webpack_require__2(95643);
var GetFastValue = __webpack_require__2(95540);
var Extend = __webpack_require__2(79291);
var SetValue = __webpack_require__2(61622);
var ShaderRender = __webpack_require__2(25479);
var TransformMatrix = __webpack_require__2(61340);
var ArrayEach = __webpack_require__2(95428);
var RenderEvents = __webpack_require__2(92503);
var Shader = new Class({
Extends: GameObject,
Mixins: [
Components.ComputedSize,
Components.Depth,
Components.GetBounds,
Components.Mask,
Components.Origin,
Components.ScrollFactor,
Components.Transform,
Components.Visible,
ShaderRender
],
initialize: function Shader2(scene, key, x, y, width, height, textures, textureData) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (width === void 0) {
width = 128;
}
if (height === void 0) {
height = 128;
}
GameObject.call(this, scene, "Shader");
this.blendMode = -1;
this.shader;
var renderer = scene.sys.renderer;
this.renderer = renderer;
this.gl = renderer.gl;
this.vertexData = new ArrayBuffer(6 * (Float32Array.BYTES_PER_ELEMENT * 2));
this.vertexBuffer = renderer.createVertexBuffer(this.vertexData.byteLength, this.gl.STREAM_DRAW);
this._deferSetShader = null;
this._deferProjOrtho = null;
this.program = null;
this.bytes = new Uint8Array(this.vertexData);
this.vertexViewF32 = new Float32Array(this.vertexData);
this._tempMatrix1 = new TransformMatrix();
this._tempMatrix2 = new TransformMatrix();
this._tempMatrix3 = new TransformMatrix();
this.viewMatrix = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
this.projectionMatrix = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
this.uniforms = {};
this.pointer = null;
this._rendererWidth = renderer.width;
this._rendererHeight = renderer.height;
this._textureCount = 0;
this.framebuffer = null;
this.glTexture = null;
this.renderToTexture = false;
this.texture = null;
this.setPosition(x, y);
this.setSize(width, height);
this.setOrigin(0.5, 0.5);
this.setShader(key, textures, textureData);
this.renderer.on(RenderEvents.RESTORE_WEBGL, this.onContextRestored, this);
},
/**
* Compares the renderMask with the renderFlags to see if this Game Object will render or not.
* Also checks the Game Object against the given Cameras exclusion list.
*
* @method Phaser.GameObjects.Shader#willRender
* @since 3.0.0
*
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to check against this Game Object.
*
* @return {boolean} True if the Game Object should be rendered, otherwise false.
*/
willRender: function(camera) {
if (this.renderToTexture) {
return true;
} else {
return !(GameObject.RENDER_MASK !== this.renderFlags || this.cameraFilter !== 0 && this.cameraFilter & camera.id);
}
},
/**
* Changes this Shader so instead of rendering to the display list it renders to a
* WebGL Framebuffer and WebGL Texture instead. This allows you to use the output
* of this shader as an input for another shader, by mapping a sampler2D uniform
* to it.
*
* After calling this method the `Shader.framebuffer` and `Shader.glTexture` properties
* are populated.
*
* Additionally, you can provide a key to this method. Doing so will create a Phaser Texture
* from this Shader and save it into the Texture Manager, allowing you to then use it for
* any texture-based Game Object, such as a Sprite or Image:
*
* ```javascript
* var shader = this.add.shader('myShader', x, y, width, height);
*
* shader.setRenderToTexture('doodle');
*
* this.add.image(400, 300, 'doodle');
* ```
*
* Note that it stores an active reference to this Shader. That means as this shader updates,
* so does the texture and any object using it to render with. Also, if you destroy this
* shader, be sure to clear any objects that may have been using it as a texture too.
*
* You can access the Phaser Texture that is created via the `Shader.texture` property.
*
* By default it will create a single base texture. You can add frames to the texture
* by using the `Texture.add` method. After doing this, you can then allow Game Objects
* to use a specific frame from a Render Texture.
*
* @method Phaser.GameObjects.Shader#setRenderToTexture
* @since 3.19.0
*
* @param {string} [key] - The unique key to store the texture as within the global Texture Manager.
* @param {boolean} [flipY=false] - Does this texture need vertically flipping before rendering? This should usually be set to `true` if being fed from a buffer.
*
* @return {this} This Shader instance.
*/
setRenderToTexture: function(key, flipY) {
if (flipY === void 0) {
flipY = false;
}
if (!this.renderToTexture) {
var width = this.width;
var height = this.height;
var renderer = this.renderer;
this.glTexture = renderer.createTextureFromSource(null, width, height, 0);
this.framebuffer = renderer.createFramebuffer(width, height, this.glTexture, false);
this._rendererWidth = width;
this._rendererHeight = height;
this.renderToTexture = true;
this.projOrtho(0, this.width, this.height, 0);
if (key) {
this.texture = this.scene.sys.textures.addGLTexture(key, this.glTexture);
}
}
if (this.shader) {
renderer.pipelines.clear();
this.load();
this.flush();
renderer.pipelines.rebind();
}
return this;
},
/**
* Sets the fragment and, optionally, the vertex shader source code that this Shader will use.
* This will immediately delete the active shader program, if set, and then create a new one
* with the given source. Finally, the shader uniforms are initialized.
*
* @method Phaser.GameObjects.Shader#setShader
* @since 3.17.0
*
* @param {(string|Phaser.Display.BaseShader)} key - The key of the shader to use from the shader cache, or a BaseShader instance.
* @param {string[]} [textures] - Optional array of texture keys to bind to the iChannel0...3 uniforms. The textures must already exist in the Texture Manager.
* @param {any} [textureData] - Additional texture data.
*
* @return {this} This Shader instance.
*/
setShader: function(key, textures, textureData) {
if (this.renderer.contextLost) {
this._deferSetShader = { key, textures, textureData };
return this;
}
if (textures === void 0) {
textures = [];
}
if (typeof key === "string") {
var cache = this.scene.sys.cache.shader;
if (!cache.has(key)) {
console.warn("Shader missing: " + key);
return this;
}
this.shader = cache.get(key);
} else {
this.shader = key;
}
var gl = this.gl;
var renderer = this.renderer;
if (this.program) {
renderer.deleteProgram(this.program);
}
var program = renderer.createProgram(this.shader.vertexSrc, this.shader.fragmentSrc);
gl.uniformMatrix4fv(gl.getUniformLocation(program.webGLProgram, "uViewMatrix"), false, this.viewMatrix);
gl.uniformMatrix4fv(gl.getUniformLocation(program.webGLProgram, "uProjectionMatrix"), false, this.projectionMatrix);
gl.uniform2f(gl.getUniformLocation(program.webGLProgram, "uResolution"), this.width, this.height);
this.program = program;
var d = /* @__PURE__ */ new Date();
var defaultUniforms = {
resolution: { type: "2f", value: { x: this.width, y: this.height } },
time: { type: "1f", value: 0 },
mouse: { type: "2f", value: { x: this.width / 2, y: this.height / 2 } },
date: { type: "4fv", value: [d.getFullYear(), d.getMonth(), d.getDate(), d.getHours() * 60 * 60 + d.getMinutes() * 60 + d.getSeconds()] },
sampleRate: { type: "1f", value: 44100 },
iChannel0: { type: "sampler2D", value: null, textureData: { repeat: true } },
iChannel1: { type: "sampler2D", value: null, textureData: { repeat: true } },
iChannel2: { type: "sampler2D", value: null, textureData: { repeat: true } },
iChannel3: { type: "sampler2D", value: null, textureData: { repeat: true } }
};
if (this.shader.uniforms) {
this.uniforms = Extend(true, {}, this.shader.uniforms, defaultUniforms);
} else {
this.uniforms = defaultUniforms;
}
for (var i = 0; i < 4; i++) {
if (textures[i]) {
this.setSampler2D("iChannel" + i, textures[i], i, textureData);
}
}
this.initUniforms();
this.projOrtho(0, this._rendererWidth, this._rendererHeight, 0);
return this;
},
/**
* Binds a Phaser Pointer object to this Shader.
*
* The screen position of the pointer will be set in to the shaders `mouse` uniform
* automatically every frame. Call this method with no arguments to unbind the pointer.
*
* @method Phaser.GameObjects.Shader#setPointer
* @since 3.17.0
*
* @param {Phaser.Input.Pointer} [pointer] - The Pointer to bind to this shader.
*
* @return {this} This Shader instance.
*/
setPointer: function(pointer) {
this.pointer = pointer;
return this;
},
/**
* Sets this shader to use an orthographic projection matrix.
* This matrix is stored locally in the `projectionMatrix` property,
* as well as being bound to the `uProjectionMatrix` uniform.
*
* @method Phaser.GameObjects.Shader#projOrtho
* @since 3.17.0
*
* @param {number} left - The left value.
* @param {number} right - The right value.
* @param {number} bottom - The bottom value.
* @param {number} top - The top value.
*/
projOrtho: function(left, right, bottom, top) {
if (this.renderer.contextLost) {
this._deferProjOrtho = { left, right, bottom, top };
return;
}
var near = -1e3;
var far = 1e3;
var leftRight = 1 / (left - right);
var bottomTop = 1 / (bottom - top);
var nearFar = 1 / (near - far);
var pm = this.projectionMatrix;
pm[0] = -2 * leftRight;
pm[5] = -2 * bottomTop;
pm[10] = 2 * nearFar;
pm[12] = (left + right) * leftRight;
pm[13] = (top + bottom) * bottomTop;
pm[14] = (far + near) * nearFar;
var program = this.program;
var gl = this.gl;
var renderer = this.renderer;
renderer.setProgram(program);
gl.uniformMatrix4fv(gl.getUniformLocation(program.webGLProgram, "uProjectionMatrix"), false, this.projectionMatrix);
this._rendererWidth = right;
this._rendererHeight = bottom;
},
// Uniforms are specified in the GLSL_ES Specification: http://www.khronos.org/registry/webgl/specs/latest/1.0/
// http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf
/**
* Initializes all of the uniforms this shader uses.
*
* @method Phaser.GameObjects.Shader#initUniforms
* @private
* @since 3.17.0
*/
initUniforms: function() {
var map = this.renderer.glFuncMap;
var program = this.program;
this._textureCount = 0;
for (var key in this.uniforms) {
var uniform = this.uniforms[key];
var type = uniform.type;
var data = map[type];
uniform.uniformLocation = this.renderer.createUniformLocation(program, key);
if (type !== "sampler2D") {
uniform.glMatrix = data.matrix;
uniform.glValueLength = data.length;
uniform.glFunc = data.func;
}
}
},
/**
* Sets a sampler2D uniform on this shader where the source texture is a WebGLTextureBuffer.
*
* This allows you to feed the output from one Shader into another:
*
* ```javascript
* let shader1 = this.add.shader(baseShader1, 0, 0, 512, 512).setRenderToTexture();
* let shader2 = this.add.shader(baseShader2, 0, 0, 512, 512).setRenderToTexture('output');
*
* shader1.setSampler2DBuffer('iChannel0', shader2.glTexture, 512, 512);
* shader2.setSampler2DBuffer('iChannel0', shader1.glTexture, 512, 512);
* ```
*
* In the above code, the result of baseShader1 is fed into Shader2 as the `iChannel0` sampler2D uniform.
* The result of baseShader2 is then fed back into shader1 again, creating a feedback loop.
*
* If you wish to use an image from the Texture Manager as a sampler2D input for this shader,
* see the `Shader.setSampler2D` method.
*
* @method Phaser.GameObjects.Shader#setSampler2DBuffer
* @since 3.19.0
*
* @param {string} uniformKey - The key of the sampler2D uniform to be updated, i.e. `iChannel0`.
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} texture - A texture reference.
* @param {number} width - The width of the texture.
* @param {number} height - The height of the texture.
* @param {number} [textureIndex=0] - The texture index.
* @param {any} [textureData] - Additional texture data.
*
* @return {this} This Shader instance.
*/
setSampler2DBuffer: function(uniformKey, texture, width, height, textureIndex, textureData) {
if (textureIndex === void 0) {
textureIndex = 0;
}
if (textureData === void 0) {
textureData = {};
}
var uniform = this.uniforms[uniformKey];
uniform.value = texture;
textureData.width = width;
textureData.height = height;
uniform.textureData = textureData;
this._textureCount = textureIndex;
this.initSampler2D(uniform);
return this;
},
/**
* Sets a sampler2D uniform on this shader.
*
* The textureKey given is the key from the Texture Manager cache. You cannot use a single frame
* from a texture, only the full image. Also, lots of shaders expect textures to be power-of-two sized.
*
* If you wish to use another Shader as a sampler2D input for this shader, see the `Shader.setSampler2DBuffer` method.
*
* @method Phaser.GameObjects.Shader#setSampler2D
* @since 3.17.0
*
* @param {string} uniformKey - The key of the sampler2D uniform to be updated, i.e. `iChannel0`.
* @param {string} textureKey - The key of the texture, as stored in the Texture Manager. Must already be loaded.
* @param {number} [textureIndex=0] - The texture index.
* @param {any} [textureData] - Additional texture data.
*
* @return {this} This Shader instance.
*/
setSampler2D: function(uniformKey, textureKey, textureIndex, textureData) {
if (textureIndex === void 0) {
textureIndex = 0;
}
var textureManager = this.scene.sys.textures;
if (textureManager.exists(textureKey)) {
var frame = textureManager.getFrame(textureKey);
if (frame.glTexture && frame.glTexture.isRenderTexture) {
return this.setSampler2DBuffer(uniformKey, frame.glTexture, frame.width, frame.height, textureIndex, textureData);
}
var uniform = this.uniforms[uniformKey];
var source = frame.source;
uniform.textureKey = textureKey;
uniform.source = source.image;
uniform.value = frame.glTexture;
if (source.isGLTexture) {
if (!textureData) {
textureData = {};
}
textureData.width = source.width;
textureData.height = source.height;
}
if (textureData) {
uniform.textureData = textureData;
}
this._textureCount = textureIndex;
this.initSampler2D(uniform);
}
return this;
},
/**
* Sets a property of a uniform already present on this shader.
*
* To modify the value of a uniform such as a 1f or 1i use the `value` property directly:
*
* ```javascript
* shader.setUniform('size.value', 16);
* ```
*
* You can use dot notation to access deeper values, for example:
*
* ```javascript
* shader.setUniform('resolution.value.x', 512);
* ```
*
* The change to the uniform will take effect the next time the shader is rendered.
*
* @method Phaser.GameObjects.Shader#setUniform
* @since 3.17.0
*
* @param {string} key - The key of the uniform to modify. Use dots for deep properties, i.e. `resolution.value.x`.
* @param {any} value - The value to set into the uniform.
*
* @return {this} This Shader instance.
*/
setUniform: function(key, value) {
SetValue(this.uniforms, key, value);
return this;
},
/**
* Returns the uniform object for the given key, or `null` if the uniform couldn't be found.
*
* @method Phaser.GameObjects.Shader#getUniform
* @since 3.17.0
*
* @param {string} key - The key of the uniform to return the value for.
*
* @return {any} A reference to the uniform object. This is not a copy, so modifying it will update the original object also.
*/
getUniform: function(key) {
return GetFastValue(this.uniforms, key, null);
},
/**
* A short-cut method that will directly set the texture being used by the `iChannel0` sampler2D uniform.
*
* The textureKey given is the key from the Texture Manager cache. You cannot use a single frame
* from a texture, only the full image. Also, lots of shaders expect textures to be power-of-two sized.
*
* @method Phaser.GameObjects.Shader#setChannel0
* @since 3.17.0
*
* @param {string} textureKey - The key of the texture, as stored in the Texture Manager. Must already be loaded.
* @param {any} [textureData] - Additional texture data.
*
* @return {this} This Shader instance.
*/
setChannel0: function(textureKey, textureData) {
return this.setSampler2D("iChannel0", textureKey, 0, textureData);
},
/**
* A short-cut method that will directly set the texture being used by the `iChannel1` sampler2D uniform.
*
* The textureKey given is the key from the Texture Manager cache. You cannot use a single frame
* from a texture, only the full image. Also, lots of shaders expect textures to be power-of-two sized.
*
* @method Phaser.GameObjects.Shader#setChannel1
* @since 3.17.0
*
* @param {string} textureKey - The key of the texture, as stored in the Texture Manager. Must already be loaded.
* @param {any} [textureData] - Additional texture data.
*
* @return {this} This Shader instance.
*/
setChannel1: function(textureKey, textureData) {
return this.setSampler2D("iChannel1", textureKey, 1, textureData);
},
/**
* A short-cut method that will directly set the texture being used by the `iChannel2` sampler2D uniform.
*
* The textureKey given is the key from the Texture Manager cache. You cannot use a single frame
* from a texture, only the full image. Also, lots of shaders expect textures to be power-of-two sized.
*
* @method Phaser.GameObjects.Shader#setChannel2
* @since 3.17.0
*
* @param {string} textureKey - The key of the texture, as stored in the Texture Manager. Must already be loaded.
* @param {any} [textureData] - Additional texture data.
*
* @return {this} This Shader instance.
*/
setChannel2: function(textureKey, textureData) {
return this.setSampler2D("iChannel2", textureKey, 2, textureData);
},
/**
* A short-cut method that will directly set the texture being used by the `iChannel3` sampler2D uniform.
*
* The textureKey given is the key from the Texture Manager cache. You cannot use a single frame
* from a texture, only the full image. Also, lots of shaders expect textures to be power-of-two sized.
*
* @method Phaser.GameObjects.Shader#setChannel3
* @since 3.17.0
*
* @param {string} textureKey - The key of the texture, as stored in the Texture Manager. Must already be loaded.
* @param {any} [textureData] - Additional texture data.
*
* @return {this} This Shader instance.
*/
setChannel3: function(textureKey, textureData) {
return this.setSampler2D("iChannel3", textureKey, 3, textureData);
},
/**
* Internal method that takes a sampler2D uniform and prepares it for use by setting the
* gl texture parameters.
*
* @method Phaser.GameObjects.Shader#initSampler2D
* @private
* @since 3.17.0
*
* @param {any} uniform - The sampler2D uniform to process.
*/
initSampler2D: function(uniform) {
if (!uniform.value) {
return;
}
var data = uniform.textureData;
if (data && !uniform.value.isRenderTexture) {
var gl = this.gl;
var wrapper = uniform.value;
var magFilter = gl[GetFastValue(data, "magFilter", "linear").toUpperCase()];
var minFilter = gl[GetFastValue(data, "minFilter", "linear").toUpperCase()];
var wrapS = gl[GetFastValue(data, "wrapS", "repeat").toUpperCase()];
var wrapT = gl[GetFastValue(data, "wrapT", "repeat").toUpperCase()];
var format = gl[GetFastValue(data, "format", "rgba").toUpperCase()];
var flipY = GetFastValue(data, "flipY", false);
var width = GetFastValue(data, "width", wrapper.width);
var height = GetFastValue(data, "height", wrapper.height);
var source = GetFastValue(data, "source", wrapper.pixels);
if (data.repeat) {
wrapS = gl.REPEAT;
wrapT = gl.REPEAT;
}
if (data.width) {
source = null;
}
wrapper.update(source, width, height, flipY, wrapS, wrapT, minFilter, magFilter, format);
}
this.renderer.setProgram(this.program);
this._textureCount++;
},
/**
* Synchronizes all of the uniforms this shader uses.
* Each uniforms gl function is called in turn.
*
* @method Phaser.GameObjects.Shader#syncUniforms
* @private
* @since 3.17.0
*/
syncUniforms: function() {
var gl = this.gl;
var uniforms = this.uniforms;
var uniform;
var length;
var glFunc;
var location;
var value;
var textureCount = 0;
for (var key in uniforms) {
uniform = uniforms[key];
glFunc = uniform.glFunc;
length = uniform.glValueLength;
location = uniform.uniformLocation;
value = uniform.value;
if (value === null) {
continue;
}
if (length === 1) {
if (uniform.glMatrix) {
glFunc.call(gl, location.webGLUniformLocation, uniform.transpose, value);
} else {
glFunc.call(gl, location.webGLUniformLocation, value);
}
} else if (length === 2) {
glFunc.call(gl, location.webGLUniformLocation, value.x, value.y);
} else if (length === 3) {
glFunc.call(gl, location.webGLUniformLocation, value.x, value.y, value.z);
} else if (length === 4) {
glFunc.call(gl, location.webGLUniformLocation, value.x, value.y, value.z, value.w);
} else if (uniform.type === "sampler2D") {
gl.activeTexture(gl.TEXTURE0 + textureCount);
gl.bindTexture(gl.TEXTURE_2D, value.webGLTexture);
gl.uniform1i(location.webGLUniformLocation, textureCount);
textureCount++;
}
}
},
/**
* Called automatically during render.
*
* This method performs matrix ITRS and then stores the resulting value in the `uViewMatrix` uniform.
* It then sets up the vertex buffer and shader, updates and syncs the uniforms ready
* for flush to be called.
*
* @method Phaser.GameObjects.Shader#load
* @since 3.17.0
*
* @param {Phaser.GameObjects.Components.TransformMatrix} [matrix2D] - The transform matrix to use during rendering.
*/
load: function(matrix2D) {
var gl = this.gl;
var width = this.width;
var height = this.height;
var renderer = this.renderer;
var program = this.program;
var vm = this.viewMatrix;
if (!this.renderToTexture) {
var x = -this._displayOriginX;
var y = -this._displayOriginY;
vm[0] = matrix2D[0];
vm[1] = matrix2D[1];
vm[4] = matrix2D[2];
vm[5] = matrix2D[3];
vm[8] = matrix2D[4];
vm[9] = matrix2D[5];
vm[12] = vm[0] * x + vm[4] * y;
vm[13] = vm[1] * x + vm[5] * y;
}
gl.useProgram(program.webGLProgram);
gl.uniformMatrix4fv(gl.getUniformLocation(program.webGLProgram, "uViewMatrix"), false, vm);
gl.uniformMatrix4fv(gl.getUniformLocation(program.webGLProgram, "uProjectionMatrix"), false, this.projectionMatrix);
gl.uniform2f(gl.getUniformLocation(program.webGLProgram, "uResolution"), this.width, this.height);
var uniforms = this.uniforms;
var res = uniforms.resolution;
res.value.x = width;
res.value.y = height;
uniforms.time.value = renderer.game.loop.getDuration();
var pointer = this.pointer;
if (pointer) {
var mouse = uniforms.mouse;
var px = pointer.x / width;
var py = 1 - pointer.y / height;
mouse.value.x = px.toFixed(2);
mouse.value.y = py.toFixed(2);
}
this.syncUniforms();
},
/**
* Called automatically during render.
*
* Sets the active shader, loads the vertex buffer and then draws.
*
* @method Phaser.GameObjects.Shader#flush
* @since 3.17.0
*/
flush: function() {
var width = this.width;
var height = this.height;
var program = this.program;
var gl = this.gl;
var vertexBuffer = this.vertexBuffer;
var renderer = this.renderer;
var vertexSize = Float32Array.BYTES_PER_ELEMENT * 2;
if (this.renderToTexture) {
renderer.setFramebuffer(this.framebuffer);
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
}
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer.webGLBuffer);
var location = gl.getAttribLocation(program.webGLProgram, "inPosition");
if (location !== -1) {
gl.enableVertexAttribArray(location);
gl.vertexAttribPointer(location, 2, gl.FLOAT, false, vertexSize, 0);
}
var vf = this.vertexViewF32;
vf[3] = height;
vf[4] = width;
vf[5] = height;
vf[8] = width;
vf[9] = height;
vf[10] = width;
var vertexCount = 6;
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.bytes.subarray(0, vertexCount * vertexSize));
gl.drawArrays(gl.TRIANGLES, 0, vertexCount);
if (this.renderToTexture) {
renderer.setFramebuffer(null, false);
}
},
/**
* A NOOP method so you can pass a Shader to a Container.
* Calling this method will do nothing. It is intentionally empty.
*
* @method Phaser.GameObjects.Shader#setAlpha
* @private
* @since 3.17.0
*/
setAlpha: function() {
},
/**
* A NOOP method so you can pass a Shader to a Container.
* Calling this method will do nothing. It is intentionally empty.
*
* @method Phaser.GameObjects.Shader#setBlendMode
* @private
* @since 3.17.0
*/
setBlendMode: function() {
},
/**
* Run any logic that was deferred during context loss.
*
* @method Phaser.GameObjects.Shader#onContextRestored
* @since 3.80.0
*/
onContextRestored: function() {
if (this._deferSetShader !== null) {
var key = this._deferSetShader.key;
var textures = this._deferSetShader.textures;
var textureData = this._deferSetShader.textureData;
this._deferSetShader = null;
this.setShader(key, textures, textureData);
}
if (this._deferProjOrtho !== null) {
var left = this._deferProjOrtho.left;
var right = this._deferProjOrtho.right;
var bottom = this._deferProjOrtho.bottom;
var top = this._deferProjOrtho.top;
this._deferProjOrtho = null;
this.projOrtho(left, right, bottom, top);
}
},
/**
* Internal destroy handler, called as part of the destroy process.
*
* @method Phaser.GameObjects.Shader#preDestroy
* @protected
* @since 3.17.0
*/
preDestroy: function() {
var renderer = this.renderer;
renderer.off(RenderEvents.RESTORE_WEBGL, this.onContextRestored, this);
renderer.deleteProgram(this.program);
renderer.deleteBuffer(this.vertexBuffer);
if (this.renderToTexture) {
renderer.deleteFramebuffer(this.framebuffer);
this.texture.destroy();
this.framebuffer = null;
this.glTexture = null;
this.texture = null;
}
ArrayEach(this.uniforms, function(uniform) {
renderer.deleteUniformLocation(uniform.uniformLocation);
uniform.uniformLocation = null;
});
}
});
module2.exports = Shader;
}
),
/***/
80464: (
/***/
(module2) => {
var ShaderCanvasRenderer = function() {
};
module2.exports = ShaderCanvasRenderer;
}
),
/***/
54935: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var BuildGameObject = __webpack_require__2(25305);
var GameObjectCreator = __webpack_require__2(44603);
var GetAdvancedValue = __webpack_require__2(23568);
var Shader = __webpack_require__2(20071);
GameObjectCreator.register("shader", function(config, addToScene) {
if (config === void 0) {
config = {};
}
var key = GetAdvancedValue(config, "key", null);
var x = GetAdvancedValue(config, "x", 0);
var y = GetAdvancedValue(config, "y", 0);
var width = GetAdvancedValue(config, "width", 128);
var height = GetAdvancedValue(config, "height", 128);
var shader = new Shader(this.scene, key, x, y, width, height);
if (addToScene !== void 0) {
config.add = addToScene;
}
BuildGameObject(this.scene, shader, config);
return shader;
});
}
),
/***/
74177: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var Shader = __webpack_require__2(20071);
var GameObjectFactory = __webpack_require__2(39429);
if (true) {
GameObjectFactory.register("shader", function(key, x, y, width, height, textures, textureData) {
return this.displayList.add(new Shader(this.scene, key, x, y, width, height, textures, textureData));
});
}
}
),
/***/
25479: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(19257);
}
if (true) {
renderCanvas = __webpack_require__2(80464);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
19257: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetCalcMatrix = __webpack_require__2(91296);
var ShaderWebGLRenderer = function(renderer, src, camera, parentMatrix) {
if (!src.shader) {
return;
}
camera.addToRenderList(src);
renderer.pipelines.clear();
if (src.renderToTexture) {
src.load();
src.flush();
} else {
var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc;
if (renderer.width !== src._rendererWidth || renderer.height !== src._rendererHeight) {
src.projOrtho(0, renderer.width, renderer.height, 0);
}
src.load(calcMatrix.matrix);
src.flush();
}
renderer.pipelines.rebind();
};
module2.exports = ShaderWebGLRenderer;
}
),
/***/
10441: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Utils = __webpack_require__2(70554);
var FillPathWebGL = function(pipeline, calcMatrix, src, alpha, dx, dy) {
var fillTintColor = Utils.getTintAppendFloatAlpha(src.fillColor, src.fillAlpha * alpha);
var path = src.pathData;
var pathIndexes = src.pathIndexes;
for (var i = 0; i < pathIndexes.length; i += 3) {
var p0 = pathIndexes[i] * 2;
var p1 = pathIndexes[i + 1] * 2;
var p2 = pathIndexes[i + 2] * 2;
var x0 = path[p0 + 0] - dx;
var y0 = path[p0 + 1] - dy;
var x1 = path[p1 + 0] - dx;
var y1 = path[p1 + 1] - dy;
var x2 = path[p2 + 0] - dx;
var y2 = path[p2 + 1] - dy;
var tx0 = calcMatrix.getX(x0, y0);
var ty0 = calcMatrix.getY(x0, y0);
var tx1 = calcMatrix.getX(x1, y1);
var ty1 = calcMatrix.getY(x1, y1);
var tx2 = calcMatrix.getX(x2, y2);
var ty2 = calcMatrix.getY(x2, y2);
pipeline.batchTri(src, tx0, ty0, tx1, ty1, tx2, ty2, 0, 0, 1, 1, fillTintColor, fillTintColor, fillTintColor, 2);
}
};
module2.exports = FillPathWebGL;
}
),
/***/
65960: (
/***/
(module2) => {
var FillStyleCanvas = function(ctx, src, altColor, altAlpha) {
var fillColor = altColor ? altColor : src.fillColor;
var fillAlpha = altAlpha ? altAlpha : src.fillAlpha;
var red = (fillColor & 16711680) >>> 16;
var green = (fillColor & 65280) >>> 8;
var blue = fillColor & 255;
ctx.fillStyle = "rgba(" + red + "," + green + "," + blue + "," + fillAlpha + ")";
};
module2.exports = FillStyleCanvas;
}
),
/***/
75177: (
/***/
(module2) => {
var LineStyleCanvas = function(ctx, src, altColor, altAlpha) {
var strokeColor = altColor ? altColor : src.strokeColor;
var strokeAlpha = altAlpha ? altAlpha : src.strokeAlpha;
var red = (strokeColor & 16711680) >>> 16;
var green = (strokeColor & 65280) >>> 8;
var blue = strokeColor & 255;
ctx.strokeStyle = "rgba(" + red + "," + green + "," + blue + "," + strokeAlpha + ")";
ctx.lineWidth = src.lineWidth;
};
module2.exports = LineStyleCanvas;
}
),
/***/
17803: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31401);
var GameObject = __webpack_require__2(95643);
var Line = __webpack_require__2(23031);
var Shape = new Class({
Extends: GameObject,
Mixins: [
Components.AlphaSingle,
Components.BlendMode,
Components.Depth,
Components.GetBounds,
Components.Mask,
Components.Origin,
Components.Pipeline,
Components.PostPipeline,
Components.ScrollFactor,
Components.Transform,
Components.Visible
],
initialize: function Shape2(scene, type, data) {
if (type === void 0) {
type = "Shape";
}
GameObject.call(this, scene, type);
this.geom = data;
this.pathData = [];
this.pathIndexes = [];
this.fillColor = 16777215;
this.fillAlpha = 1;
this.strokeColor = 16777215;
this.strokeAlpha = 1;
this.lineWidth = 1;
this.isFilled = false;
this.isStroked = false;
this.closePath = true;
this._tempLine = new Line();
this.width = 0;
this.height = 0;
this.initPipeline();
this.initPostPipeline();
},
/**
* Sets the fill color and alpha for this Shape.
*
* If you wish for the Shape to not be filled then call this method with no arguments, or just set `isFilled` to `false`.
*
* Note that some Shapes do not support fill colors, such as the Line shape.
*
* This call can be chained.
*
* @method Phaser.GameObjects.Shape#setFillStyle
* @since 3.13.0
*
* @param {number} [color] - The color used to fill this shape. If not provided the Shape will not be filled.
* @param {number} [alpha=1] - The alpha value used when filling this shape, if a fill color is given.
*
* @return {this} This Game Object instance.
*/
setFillStyle: function(color, alpha) {
if (alpha === void 0) {
alpha = 1;
}
if (color === void 0) {
this.isFilled = false;
} else {
this.fillColor = color;
this.fillAlpha = alpha;
this.isFilled = true;
}
return this;
},
/**
* Sets the stroke color and alpha for this Shape.
*
* If you wish for the Shape to not be stroked then call this method with no arguments, or just set `isStroked` to `false`.
*
* Note that some Shapes do not support being stroked, such as the Iso Box shape.
*
* This call can be chained.
*
* @method Phaser.GameObjects.Shape#setStrokeStyle
* @since 3.13.0
*
* @param {number} [lineWidth] - The width of line to stroke with. If not provided or undefined the Shape will not be stroked.
* @param {number} [color] - The color used to stroke this shape. If not provided the Shape will not be stroked.
* @param {number} [alpha=1] - The alpha value used when stroking this shape, if a stroke color is given.
*
* @return {this} This Game Object instance.
*/
setStrokeStyle: function(lineWidth, color, alpha) {
if (alpha === void 0) {
alpha = 1;
}
if (lineWidth === void 0) {
this.isStroked = false;
} else {
this.lineWidth = lineWidth;
this.strokeColor = color;
this.strokeAlpha = alpha;
this.isStroked = true;
}
return this;
},
/**
* Sets if this Shape path is closed during rendering when stroked.
* Note that some Shapes are always closed when stroked (such as Ellipse shapes)
*
* This call can be chained.
*
* @method Phaser.GameObjects.Shape#setClosePath
* @since 3.13.0
*
* @param {boolean} value - Set to `true` if the Shape should be closed when stroked, otherwise `false`.
*
* @return {this} This Game Object instance.
*/
setClosePath: function(value) {
this.closePath = value;
return this;
},
/**
* Sets the internal size of this Game Object, as used for frame or physics body creation.
*
* This will not change the size that the Game Object is rendered in-game.
* For that you need to either set the scale of the Game Object (`setScale`) or call the
* `setDisplaySize` method, which is the same thing as changing the scale but allows you
* to do so by giving pixel values.
*
* If you have enabled this Game Object for input, changing the size will _not_ change the
* size of the hit area. To do this you should adjust the `input.hitArea` object directly.
*
* @method Phaser.GameObjects.Shape#setSize
* @private
* @since 3.13.0
*
* @param {number} width - The width of this Game Object.
* @param {number} height - The height of this Game Object.
*
* @return {this} This Game Object instance.
*/
setSize: function(width, height) {
this.width = width;
this.height = height;
return this;
},
/**
* Sets the display size of this Shape.
*
* Calling this will adjust the scale.
*
* @method Phaser.GameObjects.Shape#setDisplaySize
* @since 3.53.0
*
* @param {number} width - The display width of this Shape.
* @param {number} height - The display height of this Shape.
*
* @return {this} This Shape instance.
*/
setDisplaySize: function(width, height) {
this.displayWidth = width;
this.displayHeight = height;
return this;
},
/**
* Internal destroy handler, called as part of the destroy process.
*
* @method Phaser.GameObjects.Shape#preDestroy
* @protected
* @since 3.13.0
*/
preDestroy: function() {
this.geom = null;
this._tempLine = null;
this.pathData = [];
this.pathIndexes = [];
},
/**
* The displayed width of this Game Object.
*
* This value takes into account the scale factor.
*
* Setting this value will adjust the Game Object's scale property.
*
* @name Phaser.GameObjects.Shape#displayWidth
* @type {number}
* @since 3.13.0
*/
displayWidth: {
get: function() {
return this.scaleX * this.width;
},
set: function(value) {
this.scaleX = value / this.width;
}
},
/**
* The displayed height of this Game Object.
*
* This value takes into account the scale factor.
*
* Setting this value will adjust the Game Object's scale property.
*
* @name Phaser.GameObjects.Shape#displayHeight
* @type {number}
* @since 3.13.0
*/
displayHeight: {
get: function() {
return this.scaleY * this.height;
},
set: function(value) {
this.scaleY = value / this.height;
}
}
});
module2.exports = Shape;
}
),
/***/
34682: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Utils = __webpack_require__2(70554);
var StrokePathWebGL = function(pipeline, src, alpha, dx, dy) {
var strokeTint = pipeline.strokeTint;
var strokeTintColor = Utils.getTintAppendFloatAlpha(src.strokeColor, src.strokeAlpha * alpha);
strokeTint.TL = strokeTintColor;
strokeTint.TR = strokeTintColor;
strokeTint.BL = strokeTintColor;
strokeTint.BR = strokeTintColor;
var path = src.pathData;
var pathLength = path.length - 1;
var lineWidth = src.lineWidth;
var halfLineWidth = lineWidth / 2;
var px1 = path[0] - dx;
var py1 = path[1] - dy;
if (!src.closePath) {
pathLength -= 2;
}
for (var i = 2; i < pathLength; i += 2) {
var px2 = path[i] - dx;
var py2 = path[i + 1] - dy;
pipeline.batchLine(
px1,
py1,
px2,
py2,
halfLineWidth,
halfLineWidth,
lineWidth,
i - 2,
src.closePath ? i === pathLength - 1 : false
);
px1 = px2;
py1 = py2;
}
};
module2.exports = StrokePathWebGL;
}
),
/***/
23629: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var ArcRender = __webpack_require__2(13609);
var Class = __webpack_require__2(83419);
var DegToRad = __webpack_require__2(39506);
var Earcut = __webpack_require__2(94811);
var GeomCircle = __webpack_require__2(96503);
var MATH_CONST = __webpack_require__2(36383);
var Shape = __webpack_require__2(17803);
var Arc = new Class({
Extends: Shape,
Mixins: [
ArcRender
],
initialize: function Arc2(scene, x, y, radius, startAngle, endAngle, anticlockwise, fillColor, fillAlpha) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (radius === void 0) {
radius = 128;
}
if (startAngle === void 0) {
startAngle = 0;
}
if (endAngle === void 0) {
endAngle = 360;
}
if (anticlockwise === void 0) {
anticlockwise = false;
}
Shape.call(this, scene, "Arc", new GeomCircle(0, 0, radius));
this._startAngle = startAngle;
this._endAngle = endAngle;
this._anticlockwise = anticlockwise;
this._iterations = 0.01;
this.setPosition(x, y);
var diameter = this.geom.radius * 2;
this.setSize(diameter, diameter);
if (fillColor !== void 0) {
this.setFillStyle(fillColor, fillAlpha);
}
this.updateDisplayOrigin();
this.updateData();
},
/**
* The number of iterations used when drawing the arc.
* Increase this value for smoother arcs, at the cost of more polygons being rendered.
* Modify this value by small amounts, such as 0.01.
*
* @name Phaser.GameObjects.Arc#iterations
* @type {number}
* @default 0.01
* @since 3.13.0
*/
iterations: {
get: function() {
return this._iterations;
},
set: function(value) {
this._iterations = value;
this.updateData();
}
},
/**
* The radius of the arc.
*
* @name Phaser.GameObjects.Arc#radius
* @type {number}
* @since 3.13.0
*/
radius: {
get: function() {
return this.geom.radius;
},
set: function(value) {
this.geom.radius = value;
var diameter = value * 2;
this.setSize(diameter, diameter);
this.updateDisplayOrigin();
this.updateData();
}
},
/**
* The start angle of the arc, in degrees.
*
* @name Phaser.GameObjects.Arc#startAngle
* @type {number}
* @since 3.13.0
*/
startAngle: {
get: function() {
return this._startAngle;
},
set: function(value) {
this._startAngle = value;
this.updateData();
}
},
/**
* The end angle of the arc, in degrees.
*
* @name Phaser.GameObjects.Arc#endAngle
* @type {number}
* @since 3.13.0
*/
endAngle: {
get: function() {
return this._endAngle;
},
set: function(value) {
this._endAngle = value;
this.updateData();
}
},
/**
* The winding order of the start and end angles.
*
* @name Phaser.GameObjects.Arc#anticlockwise
* @type {boolean}
* @since 3.13.0
*/
anticlockwise: {
get: function() {
return this._anticlockwise;
},
set: function(value) {
this._anticlockwise = value;
this.updateData();
}
},
/**
* Sets the radius of the arc.
* This call can be chained.
*
* @method Phaser.GameObjects.Arc#setRadius
* @since 3.13.0
*
* @param {number} value - The value to set the radius to.
*
* @return {this} This Game Object instance.
*/
setRadius: function(value) {
this.radius = value;
return this;
},
/**
* Sets the number of iterations used when drawing the arc.
* Increase this value for smoother arcs, at the cost of more polygons being rendered.
* Modify this value by small amounts, such as 0.01.
* This call can be chained.
*
* @method Phaser.GameObjects.Arc#setIterations
* @since 3.13.0
*
* @param {number} value - The value to set the iterations to.
*
* @return {this} This Game Object instance.
*/
setIterations: function(value) {
if (value === void 0) {
value = 0.01;
}
this.iterations = value;
return this;
},
/**
* Sets the starting angle of the arc, in degrees.
* This call can be chained.
*
* @method Phaser.GameObjects.Arc#setStartAngle
* @since 3.13.0
*
* @param {number} value - The value to set the starting angle to.
*
* @return {this} This Game Object instance.
*/
setStartAngle: function(angle, anticlockwise) {
this._startAngle = angle;
if (anticlockwise !== void 0) {
this._anticlockwise = anticlockwise;
}
return this.updateData();
},
/**
* Sets the ending angle of the arc, in degrees.
* This call can be chained.
*
* @method Phaser.GameObjects.Arc#setEndAngle
* @since 3.13.0
*
* @param {number} value - The value to set the ending angle to.
*
* @return {this} This Game Object instance.
*/
setEndAngle: function(angle, anticlockwise) {
this._endAngle = angle;
if (anticlockwise !== void 0) {
this._anticlockwise = anticlockwise;
}
return this.updateData();
},
/**
* Internal method that updates the data and path values.
*
* @method Phaser.GameObjects.Arc#updateData
* @private
* @since 3.13.0
*
* @return {this} This Game Object instance.
*/
updateData: function() {
var step = this._iterations;
var iteration = step;
var radius = this.geom.radius;
var startAngle = DegToRad(this._startAngle);
var endAngle = DegToRad(this._endAngle);
var anticlockwise = this._anticlockwise;
var x = radius;
var y = radius;
endAngle -= startAngle;
if (anticlockwise) {
if (endAngle < -MATH_CONST.PI2) {
endAngle = -MATH_CONST.PI2;
} else if (endAngle > 0) {
endAngle = -MATH_CONST.PI2 + endAngle % MATH_CONST.PI2;
}
} else if (endAngle > MATH_CONST.PI2) {
endAngle = MATH_CONST.PI2;
} else if (endAngle < 0) {
endAngle = MATH_CONST.PI2 + endAngle % MATH_CONST.PI2;
}
var path = [x + Math.cos(startAngle) * radius, y + Math.sin(startAngle) * radius];
var ta;
while (iteration < 1) {
ta = endAngle * iteration + startAngle;
path.push(x + Math.cos(ta) * radius, y + Math.sin(ta) * radius);
iteration += step;
}
ta = endAngle + startAngle;
path.push(x + Math.cos(ta) * radius, y + Math.sin(ta) * radius);
path.push(x + Math.cos(startAngle) * radius, y + Math.sin(startAngle) * radius);
this.pathIndexes = Earcut(path);
this.pathData = path;
return this;
}
});
module2.exports = Arc;
}
),
/***/
42542: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var DegToRad = __webpack_require__2(39506);
var FillStyleCanvas = __webpack_require__2(65960);
var LineStyleCanvas = __webpack_require__2(75177);
var SetTransform = __webpack_require__2(20926);
var ArcCanvasRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
var ctx = renderer.currentContext;
if (SetTransform(renderer, ctx, src, camera, parentMatrix)) {
var radius = src.radius;
ctx.beginPath();
ctx.arc(
radius - src.originX * (radius * 2),
radius - src.originY * (radius * 2),
radius,
DegToRad(src._startAngle),
DegToRad(src._endAngle),
src.anticlockwise
);
if (src.closePath) {
ctx.closePath();
}
if (src.isFilled) {
FillStyleCanvas(ctx, src);
ctx.fill();
}
if (src.isStroked) {
LineStyleCanvas(ctx, src);
ctx.stroke();
}
ctx.restore();
}
};
module2.exports = ArcCanvasRenderer;
}
),
/***/
42563: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var Arc = __webpack_require__2(23629);
var GameObjectFactory = __webpack_require__2(39429);
GameObjectFactory.register("arc", function(x, y, radius, startAngle, endAngle, anticlockwise, fillColor, fillAlpha) {
return this.displayList.add(new Arc(this.scene, x, y, radius, startAngle, endAngle, anticlockwise, fillColor, fillAlpha));
});
GameObjectFactory.register("circle", function(x, y, radius, fillColor, fillAlpha) {
return this.displayList.add(new Arc(this.scene, x, y, radius, 0, 360, false, fillColor, fillAlpha));
});
}
),
/***/
13609: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(41447);
}
if (true) {
renderCanvas = __webpack_require__2(42542);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
41447: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetCalcMatrix = __webpack_require__2(91296);
var FillPathWebGL = __webpack_require__2(10441);
var StrokePathWebGL = __webpack_require__2(34682);
var ArcWebGLRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
var pipeline = renderer.pipelines.set(src.pipeline);
var result = GetCalcMatrix(src, camera, parentMatrix);
var calcMatrix = pipeline.calcMatrix.copyFrom(result.calc);
var dx = src._displayOriginX;
var dy = src._displayOriginY;
var alpha = camera.alpha * src.alpha;
renderer.pipelines.preBatch(src);
if (src.isFilled) {
FillPathWebGL(pipeline, calcMatrix, src, alpha, dx, dy);
}
if (src.isStroked) {
StrokePathWebGL(pipeline, src, alpha, dx, dy);
}
renderer.pipelines.postBatch(src);
};
module2.exports = ArcWebGLRenderer;
}
),
/***/
89: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CurveRender = __webpack_require__2(33141);
var Earcut = __webpack_require__2(94811);
var Rectangle = __webpack_require__2(87841);
var Shape = __webpack_require__2(17803);
var Curve = new Class({
Extends: Shape,
Mixins: [
CurveRender
],
initialize: function Curve2(scene, x, y, curve, fillColor, fillAlpha) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
Shape.call(this, scene, "Curve", curve);
this._smoothness = 32;
this._curveBounds = new Rectangle();
this.closePath = false;
this.setPosition(x, y);
if (fillColor !== void 0) {
this.setFillStyle(fillColor, fillAlpha);
}
this.updateData();
},
/**
* The smoothness of the curve. The number of points used when rendering it.
* Increase this value for smoother curves, at the cost of more polygons being rendered.
*
* @name Phaser.GameObjects.Curve#smoothness
* @type {number}
* @default 32
* @since 3.13.0
*/
smoothness: {
get: function() {
return this._smoothness;
},
set: function(value) {
this._smoothness = value;
this.updateData();
}
},
/**
* Sets the smoothness of the curve. The number of points used when rendering it.
* Increase this value for smoother curves, at the cost of more polygons being rendered.
* This call can be chained.
*
* @method Phaser.GameObjects.Curve#setSmoothness
* @since 3.13.0
*
* @param {number} value - The value to set the smoothness to.
*
* @return {this} This Game Object instance.
*/
setSmoothness: function(value) {
this._smoothness = value;
return this.updateData();
},
/**
* Internal method that updates the data and path values.
*
* @method Phaser.GameObjects.Curve#updateData
* @private
* @since 3.13.0
*
* @return {this} This Game Object instance.
*/
updateData: function() {
var bounds = this._curveBounds;
var smoothness = this._smoothness;
this.geom.getBounds(bounds, smoothness);
this.setSize(bounds.width, bounds.height);
this.updateDisplayOrigin();
var path = [];
var points = this.geom.getPoints(smoothness);
for (var i = 0; i < points.length; i++) {
path.push(points[i].x, points[i].y);
}
path.push(points[0].x, points[0].y);
this.pathIndexes = Earcut(path);
this.pathData = path;
return this;
}
});
module2.exports = Curve;
}
),
/***/
3170: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var FillStyleCanvas = __webpack_require__2(65960);
var LineStyleCanvas = __webpack_require__2(75177);
var SetTransform = __webpack_require__2(20926);
var CurveCanvasRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
var ctx = renderer.currentContext;
if (SetTransform(renderer, ctx, src, camera, parentMatrix)) {
var dx = src._displayOriginX + src._curveBounds.x;
var dy = src._displayOriginY + src._curveBounds.y;
var path = src.pathData;
var pathLength = path.length - 1;
var px1 = path[0] - dx;
var py1 = path[1] - dy;
ctx.beginPath();
ctx.moveTo(px1, py1);
if (!src.closePath) {
pathLength -= 2;
}
for (var i = 2; i < pathLength; i += 2) {
var px2 = path[i] - dx;
var py2 = path[i + 1] - dy;
ctx.lineTo(px2, py2);
}
if (src.closePath) {
ctx.closePath();
}
if (src.isFilled) {
FillStyleCanvas(ctx, src);
ctx.fill();
}
if (src.isStroked) {
LineStyleCanvas(ctx, src);
ctx.stroke();
}
ctx.restore();
}
};
module2.exports = CurveCanvasRenderer;
}
),
/***/
40511: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var GameObjectFactory = __webpack_require__2(39429);
var Curve = __webpack_require__2(89);
GameObjectFactory.register("curve", function(x, y, curve, fillColor, fillAlpha) {
return this.displayList.add(new Curve(this.scene, x, y, curve, fillColor, fillAlpha));
});
}
),
/***/
33141: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(53987);
}
if (true) {
renderCanvas = __webpack_require__2(3170);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
53987: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var FillPathWebGL = __webpack_require__2(10441);
var GetCalcMatrix = __webpack_require__2(91296);
var StrokePathWebGL = __webpack_require__2(34682);
var CurveWebGLRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
var pipeline = renderer.pipelines.set(src.pipeline);
var result = GetCalcMatrix(src, camera, parentMatrix);
var calcMatrix = pipeline.calcMatrix.copyFrom(result.calc);
var dx = src._displayOriginX + src._curveBounds.x;
var dy = src._displayOriginY + src._curveBounds.y;
var alpha = camera.alpha * src.alpha;
renderer.pipelines.preBatch(src);
if (src.isFilled) {
FillPathWebGL(pipeline, calcMatrix, src, alpha, dx, dy);
}
if (src.isStroked) {
StrokePathWebGL(pipeline, src, alpha, dx, dy);
}
renderer.pipelines.postBatch(src);
};
module2.exports = CurveWebGLRenderer;
}
),
/***/
19921: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Earcut = __webpack_require__2(94811);
var EllipseRender = __webpack_require__2(54205);
var GeomEllipse = __webpack_require__2(8497);
var Shape = __webpack_require__2(17803);
var Ellipse = new Class({
Extends: Shape,
Mixins: [
EllipseRender
],
initialize: function Ellipse2(scene, x, y, width, height, fillColor, fillAlpha) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (width === void 0) {
width = 128;
}
if (height === void 0) {
height = 128;
}
Shape.call(this, scene, "Ellipse", new GeomEllipse(width / 2, height / 2, width, height));
this._smoothness = 64;
this.setPosition(x, y);
this.width = width;
this.height = height;
if (fillColor !== void 0) {
this.setFillStyle(fillColor, fillAlpha);
}
this.updateDisplayOrigin();
this.updateData();
},
/**
* The smoothness of the ellipse. The number of points used when rendering it.
* Increase this value for a smoother ellipse, at the cost of more polygons being rendered.
*
* @name Phaser.GameObjects.Ellipse#smoothness
* @type {number}
* @default 64
* @since 3.13.0
*/
smoothness: {
get: function() {
return this._smoothness;
},
set: function(value) {
this._smoothness = value;
this.updateData();
}
},
/**
* Sets the size of the ellipse by changing the underlying geometry data, rather than scaling the object.
* This call can be chained.
*
* @method Phaser.GameObjects.Ellipse#setSize
* @since 3.13.0
*
* @param {number} width - The width of the ellipse.
* @param {number} height - The height of the ellipse.
*
* @return {this} This Game Object instance.
*/
setSize: function(width, height) {
this.width = width;
this.height = height;
this.geom.setPosition(width / 2, height / 2);
this.geom.setSize(width, height);
this.updateDisplayOrigin();
return this.updateData();
},
/**
* Sets the smoothness of the ellipse. The number of points used when rendering it.
* Increase this value for a smoother ellipse, at the cost of more polygons being rendered.
* This call can be chained.
*
* @method Phaser.GameObjects.Ellipse#setSmoothness
* @since 3.13.0
*
* @param {number} value - The value to set the smoothness to.
*
* @return {this} This Game Object instance.
*/
setSmoothness: function(value) {
this._smoothness = value;
return this.updateData();
},
/**
* Internal method that updates the data and path values.
*
* @method Phaser.GameObjects.Ellipse#updateData
* @private
* @since 3.13.0
*
* @return {this} This Game Object instance.
*/
updateData: function() {
var path = [];
var points = this.geom.getPoints(this._smoothness);
for (var i = 0; i < points.length; i++) {
path.push(points[i].x, points[i].y);
}
path.push(points[0].x, points[0].y);
this.pathIndexes = Earcut(path);
this.pathData = path;
return this;
}
});
module2.exports = Ellipse;
}
),
/***/
7930: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var FillStyleCanvas = __webpack_require__2(65960);
var LineStyleCanvas = __webpack_require__2(75177);
var SetTransform = __webpack_require__2(20926);
var EllipseCanvasRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
var ctx = renderer.currentContext;
if (SetTransform(renderer, ctx, src, camera, parentMatrix)) {
var dx = src._displayOriginX;
var dy = src._displayOriginY;
var path = src.pathData;
var pathLength = path.length - 1;
var px1 = path[0] - dx;
var py1 = path[1] - dy;
ctx.beginPath();
ctx.moveTo(px1, py1);
if (!src.closePath) {
pathLength -= 2;
}
for (var i = 2; i < pathLength; i += 2) {
var px2 = path[i] - dx;
var py2 = path[i + 1] - dy;
ctx.lineTo(px2, py2);
}
ctx.closePath();
if (src.isFilled) {
FillStyleCanvas(ctx, src);
ctx.fill();
}
if (src.isStroked) {
LineStyleCanvas(ctx, src);
ctx.stroke();
}
ctx.restore();
}
};
module2.exports = EllipseCanvasRenderer;
}
),
/***/
1543: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var Ellipse = __webpack_require__2(19921);
var GameObjectFactory = __webpack_require__2(39429);
GameObjectFactory.register("ellipse", function(x, y, width, height, fillColor, fillAlpha) {
return this.displayList.add(new Ellipse(this.scene, x, y, width, height, fillColor, fillAlpha));
});
}
),
/***/
54205: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(19467);
}
if (true) {
renderCanvas = __webpack_require__2(7930);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
19467: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var FillPathWebGL = __webpack_require__2(10441);
var GetCalcMatrix = __webpack_require__2(91296);
var StrokePathWebGL = __webpack_require__2(34682);
var EllipseWebGLRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
var pipeline = renderer.pipelines.set(src.pipeline);
var result = GetCalcMatrix(src, camera, parentMatrix);
var calcMatrix = pipeline.calcMatrix.copyFrom(result.calc);
var dx = src._displayOriginX;
var dy = src._displayOriginY;
var alpha = camera.alpha * src.alpha;
renderer.pipelines.preBatch(src);
if (src.isFilled) {
FillPathWebGL(pipeline, calcMatrix, src, alpha, dx, dy);
}
if (src.isStroked) {
StrokePathWebGL(pipeline, src, alpha, dx, dy);
}
renderer.pipelines.postBatch(src);
};
module2.exports = EllipseWebGLRenderer;
}
),
/***/
30479: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Shape = __webpack_require__2(17803);
var GridRender = __webpack_require__2(26015);
var Grid = new Class({
Extends: Shape,
Mixins: [
GridRender
],
initialize: function Grid2(scene, x, y, width, height, cellWidth, cellHeight, fillColor, fillAlpha, outlineFillColor, outlineFillAlpha) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (width === void 0) {
width = 128;
}
if (height === void 0) {
height = 128;
}
if (cellWidth === void 0) {
cellWidth = 32;
}
if (cellHeight === void 0) {
cellHeight = 32;
}
Shape.call(this, scene, "Grid", null);
this.cellWidth = cellWidth;
this.cellHeight = cellHeight;
this.showCells = true;
this.outlineFillColor = 0;
this.outlineFillAlpha = 0;
this.showOutline = true;
this.showAltCells = false;
this.altFillColor;
this.altFillAlpha;
this.setPosition(x, y);
this.setSize(width, height);
this.setFillStyle(fillColor, fillAlpha);
if (outlineFillColor !== void 0) {
this.setOutlineStyle(outlineFillColor, outlineFillAlpha);
}
this.updateDisplayOrigin();
},
/**
* Sets the fill color and alpha level the grid cells will use when rendering.
*
* If this method is called with no values then the grid cells will not be rendered,
* however the grid lines and alternating cells may still be.
*
* Also see the `setOutlineStyle` and `setAltFillStyle` methods.
*
* This call can be chained.
*
* @method Phaser.GameObjects.Grid#setFillStyle
* @since 3.13.0
*
* @param {number} [fillColor] - The color the grid cells will be filled with, i.e. 0xff0000 for red.
* @param {number} [fillAlpha=1] - The alpha the grid cells will be filled with. You can also set the alpha of the overall Shape using its `alpha` property.
*
* @return {this} This Game Object instance.
*/
setFillStyle: function(fillColor, fillAlpha) {
if (fillAlpha === void 0) {
fillAlpha = 1;
}
if (fillColor === void 0) {
this.showCells = false;
} else {
this.fillColor = fillColor;
this.fillAlpha = fillAlpha;
this.showCells = true;
}
return this;
},
/**
* Sets the fill color and alpha level that the alternating grid cells will use.
*
* If this method is called with no values then alternating grid cells will not be rendered in a different color.
*
* Also see the `setOutlineStyle` and `setFillStyle` methods.
*
* This call can be chained.
*
* @method Phaser.GameObjects.Grid#setAltFillStyle
* @since 3.13.0
*
* @param {number} [fillColor] - The color the alternating grid cells will be filled with, i.e. 0xff0000 for red.
* @param {number} [fillAlpha=1] - The alpha the alternating grid cells will be filled with. You can also set the alpha of the overall Shape using its `alpha` property.
*
* @return {this} This Game Object instance.
*/
setAltFillStyle: function(fillColor, fillAlpha) {
if (fillAlpha === void 0) {
fillAlpha = 1;
}
if (fillColor === void 0) {
this.showAltCells = false;
} else {
this.altFillColor = fillColor;
this.altFillAlpha = fillAlpha;
this.showAltCells = true;
}
return this;
},
/**
* Sets the fill color and alpha level that the lines between each grid cell will use.
*
* If this method is called with no values then the grid lines will not be rendered at all, however
* the cells themselves may still be if they have colors set.
*
* Also see the `setFillStyle` and `setAltFillStyle` methods.
*
* This call can be chained.
*
* @method Phaser.GameObjects.Grid#setOutlineStyle
* @since 3.13.0
*
* @param {number} [fillColor] - The color the lines between the grid cells will be filled with, i.e. 0xff0000 for red.
* @param {number} [fillAlpha=1] - The alpha the lines between the grid cells will be filled with. You can also set the alpha of the overall Shape using its `alpha` property.
*
* @return {this} This Game Object instance.
*/
setOutlineStyle: function(fillColor, fillAlpha) {
if (fillAlpha === void 0) {
fillAlpha = 1;
}
if (fillColor === void 0) {
this.showOutline = false;
} else {
this.outlineFillColor = fillColor;
this.outlineFillAlpha = fillAlpha;
this.showOutline = true;
}
return this;
}
});
module2.exports = Grid;
}
),
/***/
49912: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var FillStyleCanvas = __webpack_require__2(65960);
var LineStyleCanvas = __webpack_require__2(75177);
var SetTransform = __webpack_require__2(20926);
var GridCanvasRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
var ctx = renderer.currentContext;
if (SetTransform(renderer, ctx, src, camera, parentMatrix)) {
var dx = -src._displayOriginX;
var dy = -src._displayOriginY;
var alpha = camera.alpha * src.alpha;
var width = src.width;
var height = src.height;
var cellWidth = src.cellWidth;
var cellHeight = src.cellHeight;
var gridWidth = Math.ceil(width / cellWidth);
var gridHeight = Math.ceil(height / cellHeight);
var cellWidthA = cellWidth;
var cellHeightA = cellHeight;
var cellWidthB = cellWidth - (gridWidth * cellWidth - width);
var cellHeightB = cellHeight - (gridHeight * cellHeight - height);
var showCells = src.showCells;
var showAltCells = src.showAltCells;
var showOutline = src.showOutline;
var x = 0;
var y = 0;
var r = 0;
var cw = 0;
var ch = 0;
if (showOutline) {
cellWidthA--;
cellHeightA--;
if (cellWidthB === cellWidth) {
cellWidthB--;
}
if (cellHeightB === cellHeight) {
cellHeightB--;
}
}
if (showCells && src.fillAlpha > 0) {
FillStyleCanvas(ctx, src);
for (y = 0; y < gridHeight; y++) {
if (showAltCells) {
r = y % 2;
}
for (x = 0; x < gridWidth; x++) {
if (showAltCells && r) {
r = 0;
continue;
}
r++;
cw = x < gridWidth - 1 ? cellWidthA : cellWidthB;
ch = y < gridHeight - 1 ? cellHeightA : cellHeightB;
ctx.fillRect(
dx + x * cellWidth,
dy + y * cellHeight,
cw,
ch
);
}
}
}
if (showAltCells && src.altFillAlpha > 0) {
FillStyleCanvas(ctx, src, src.altFillColor, src.altFillAlpha * alpha);
for (y = 0; y < gridHeight; y++) {
if (showAltCells) {
r = y % 2;
}
for (x = 0; x < gridWidth; x++) {
if (showAltCells && !r) {
r = 1;
continue;
}
r = 0;
cw = x < gridWidth - 1 ? cellWidthA : cellWidthB;
ch = y < gridHeight - 1 ? cellHeightA : cellHeightB;
ctx.fillRect(
dx + x * cellWidth,
dy + y * cellHeight,
cw,
ch
);
}
}
}
if (showOutline && src.outlineFillAlpha > 0) {
LineStyleCanvas(ctx, src, src.outlineFillColor, src.outlineFillAlpha * alpha);
for (x = 1; x < gridWidth; x++) {
var x1 = x * cellWidth;
ctx.beginPath();
ctx.moveTo(x1 + dx, dy);
ctx.lineTo(x1 + dx, height + dy);
ctx.stroke();
}
for (y = 1; y < gridHeight; y++) {
var y1 = y * cellHeight;
ctx.beginPath();
ctx.moveTo(dx, y1 + dy);
ctx.lineTo(dx + width, y1 + dy);
ctx.stroke();
}
}
ctx.restore();
}
};
module2.exports = GridCanvasRenderer;
}
),
/***/
34137: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var GameObjectFactory = __webpack_require__2(39429);
var Grid = __webpack_require__2(30479);
GameObjectFactory.register("grid", function(x, y, width, height, cellWidth, cellHeight, fillColor, fillAlpha, outlineFillColor, outlineFillAlpha) {
return this.displayList.add(new Grid(this.scene, x, y, width, height, cellWidth, cellHeight, fillColor, fillAlpha, outlineFillColor, outlineFillAlpha));
});
}
),
/***/
26015: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(46161);
}
if (true) {
renderCanvas = __webpack_require__2(49912);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
46161: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetCalcMatrix = __webpack_require__2(91296);
var Utils = __webpack_require__2(70554);
var GridWebGLRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
var pipeline = renderer.pipelines.set(src.pipeline);
var result = GetCalcMatrix(src, camera, parentMatrix);
var calcMatrix = pipeline.calcMatrix.copyFrom(result.calc);
calcMatrix.translate(-src._displayOriginX, -src._displayOriginY);
var alpha = camera.alpha * src.alpha;
var width = src.width;
var height = src.height;
var cellWidth = src.cellWidth;
var cellHeight = src.cellHeight;
var gridWidth = Math.ceil(width / cellWidth);
var gridHeight = Math.ceil(height / cellHeight);
var cellWidthA = cellWidth;
var cellHeightA = cellHeight;
var cellWidthB = cellWidth - (gridWidth * cellWidth - width);
var cellHeightB = cellHeight - (gridHeight * cellHeight - height);
var fillTint;
var fillTintColor;
var showCells = src.showCells;
var showAltCells = src.showAltCells;
var showOutline = src.showOutline;
var x = 0;
var y = 0;
var r = 0;
var cw = 0;
var ch = 0;
if (showOutline) {
cellWidthA--;
cellHeightA--;
if (cellWidthB === cellWidth) {
cellWidthB--;
}
if (cellHeightB === cellHeight) {
cellHeightB--;
}
}
renderer.pipelines.preBatch(src);
if (showCells && src.fillAlpha > 0) {
fillTint = pipeline.fillTint;
fillTintColor = Utils.getTintAppendFloatAlpha(src.fillColor, src.fillAlpha * alpha);
fillTint.TL = fillTintColor;
fillTint.TR = fillTintColor;
fillTint.BL = fillTintColor;
fillTint.BR = fillTintColor;
for (y = 0; y < gridHeight; y++) {
if (showAltCells) {
r = y % 2;
}
for (x = 0; x < gridWidth; x++) {
if (showAltCells && r) {
r = 0;
continue;
}
r++;
cw = x < gridWidth - 1 ? cellWidthA : cellWidthB;
ch = y < gridHeight - 1 ? cellHeightA : cellHeightB;
pipeline.batchFillRect(
x * cellWidth,
y * cellHeight,
cw,
ch
);
}
}
}
if (showAltCells && src.altFillAlpha > 0) {
fillTint = pipeline.fillTint;
fillTintColor = Utils.getTintAppendFloatAlpha(src.altFillColor, src.altFillAlpha * alpha);
fillTint.TL = fillTintColor;
fillTint.TR = fillTintColor;
fillTint.BL = fillTintColor;
fillTint.BR = fillTintColor;
for (y = 0; y < gridHeight; y++) {
if (showAltCells) {
r = y % 2;
}
for (x = 0; x < gridWidth; x++) {
if (showAltCells && !r) {
r = 1;
continue;
}
r = 0;
cw = x < gridWidth - 1 ? cellWidthA : cellWidthB;
ch = y < gridHeight - 1 ? cellHeightA : cellHeightB;
pipeline.batchFillRect(
x * cellWidth,
y * cellHeight,
cw,
ch
);
}
}
}
if (showOutline && src.outlineFillAlpha > 0) {
var strokeTint = pipeline.strokeTint;
var color = Utils.getTintAppendFloatAlpha(src.outlineFillColor, src.outlineFillAlpha * alpha);
strokeTint.TL = color;
strokeTint.TR = color;
strokeTint.BL = color;
strokeTint.BR = color;
for (x = 1; x < gridWidth; x++) {
var x1 = x * cellWidth;
pipeline.batchLine(x1, 0, x1, height, 1, 1, 1, 0, false);
}
for (y = 1; y < gridHeight; y++) {
var y1 = y * cellHeight;
pipeline.batchLine(0, y1, width, y1, 1, 1, 1, 0, false);
}
}
renderer.pipelines.postBatch(src);
};
module2.exports = GridWebGLRenderer;
}
),
/***/
61475: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var IsoBoxRender = __webpack_require__2(99651);
var Class = __webpack_require__2(83419);
var Shape = __webpack_require__2(17803);
var IsoBox = new Class({
Extends: Shape,
Mixins: [
IsoBoxRender
],
initialize: function IsoBox2(scene, x, y, size, height, fillTop, fillLeft, fillRight) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (size === void 0) {
size = 48;
}
if (height === void 0) {
height = 32;
}
if (fillTop === void 0) {
fillTop = 15658734;
}
if (fillLeft === void 0) {
fillLeft = 10066329;
}
if (fillRight === void 0) {
fillRight = 13421772;
}
Shape.call(this, scene, "IsoBox", null);
this.projection = 4;
this.fillTop = fillTop;
this.fillLeft = fillLeft;
this.fillRight = fillRight;
this.showTop = true;
this.showLeft = true;
this.showRight = true;
this.isFilled = true;
this.setPosition(x, y);
this.setSize(size, height);
this.updateDisplayOrigin();
},
/**
* Sets the projection level of the iso box. Change this to change the 'angle' at which you are looking at the box.
* This call can be chained.
*
* @method Phaser.GameObjects.IsoBox#setProjection
* @since 3.13.0
*
* @param {number} value - The value to set the projection to.
*
* @return {this} This Game Object instance.
*/
setProjection: function(value) {
this.projection = value;
return this;
},
/**
* Sets which faces of the iso box will be rendered.
* This call can be chained.
*
* @method Phaser.GameObjects.IsoBox#setFaces
* @since 3.13.0
*
* @param {boolean} [showTop=true] - Show the top-face of the iso box.
* @param {boolean} [showLeft=true] - Show the left-face of the iso box.
* @param {boolean} [showRight=true] - Show the right-face of the iso box.
*
* @return {this} This Game Object instance.
*/
setFaces: function(showTop, showLeft, showRight) {
if (showTop === void 0) {
showTop = true;
}
if (showLeft === void 0) {
showLeft = true;
}
if (showRight === void 0) {
showRight = true;
}
this.showTop = showTop;
this.showLeft = showLeft;
this.showRight = showRight;
return this;
},
/**
* Sets the fill colors for each face of the iso box.
* This call can be chained.
*
* @method Phaser.GameObjects.IsoBox#setFillStyle
* @since 3.13.0
*
* @param {number} [fillTop] - The color used to fill the top of the iso box.
* @param {number} [fillLeft] - The color used to fill in the left-facing side of the iso box.
* @param {number} [fillRight] - The color used to fill in the right-facing side of the iso box.
*
* @return {this} This Game Object instance.
*/
setFillStyle: function(fillTop, fillLeft, fillRight) {
this.fillTop = fillTop;
this.fillLeft = fillLeft;
this.fillRight = fillRight;
this.isFilled = true;
return this;
}
});
module2.exports = IsoBox;
}
),
/***/
11508: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var FillStyleCanvas = __webpack_require__2(65960);
var SetTransform = __webpack_require__2(20926);
var IsoBoxCanvasRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
var ctx = renderer.currentContext;
if (SetTransform(renderer, ctx, src, camera, parentMatrix) && src.isFilled) {
var size = src.width;
var height = src.height;
var sizeA = size / 2;
var sizeB = size / src.projection;
if (src.showTop) {
FillStyleCanvas(ctx, src, src.fillTop);
ctx.beginPath();
ctx.moveTo(-sizeA, -height);
ctx.lineTo(0, -sizeB - height);
ctx.lineTo(sizeA, -height);
ctx.lineTo(sizeA, -1);
ctx.lineTo(0, sizeB - 1);
ctx.lineTo(-sizeA, -1);
ctx.lineTo(-sizeA, -height);
ctx.fill();
}
if (src.showLeft) {
FillStyleCanvas(ctx, src, src.fillLeft);
ctx.beginPath();
ctx.moveTo(-sizeA, 0);
ctx.lineTo(0, sizeB);
ctx.lineTo(0, sizeB - height);
ctx.lineTo(-sizeA, -height);
ctx.lineTo(-sizeA, 0);
ctx.fill();
}
if (src.showRight) {
FillStyleCanvas(ctx, src, src.fillRight);
ctx.beginPath();
ctx.moveTo(sizeA, 0);
ctx.lineTo(0, sizeB);
ctx.lineTo(0, sizeB - height);
ctx.lineTo(sizeA, -height);
ctx.lineTo(sizeA, 0);
ctx.fill();
}
ctx.restore();
}
};
module2.exports = IsoBoxCanvasRenderer;
}
),
/***/
3933: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var GameObjectFactory = __webpack_require__2(39429);
var IsoBox = __webpack_require__2(61475);
GameObjectFactory.register("isobox", function(x, y, size, height, fillTop, fillLeft, fillRight) {
return this.displayList.add(new IsoBox(this.scene, x, y, size, height, fillTop, fillLeft, fillRight));
});
}
),
/***/
99651: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(68149);
}
if (true) {
renderCanvas = __webpack_require__2(11508);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
68149: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetCalcMatrix = __webpack_require__2(91296);
var Utils = __webpack_require__2(70554);
var IsoBoxWebGLRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
var pipeline = renderer.pipelines.set(src.pipeline);
var result = GetCalcMatrix(src, camera, parentMatrix);
var calcMatrix = pipeline.calcMatrix.copyFrom(result.calc);
var size = src.width;
var height = src.height;
var sizeA = size / 2;
var sizeB = size / src.projection;
var alpha = camera.alpha * src.alpha;
if (!src.isFilled) {
return;
}
var tint;
var x0;
var y0;
var x1;
var y1;
var x2;
var y2;
var x3;
var y3;
renderer.pipelines.preBatch(src);
if (src.showTop) {
tint = Utils.getTintAppendFloatAlpha(src.fillTop, alpha);
x0 = calcMatrix.getX(-sizeA, -height);
y0 = calcMatrix.getY(-sizeA, -height);
x1 = calcMatrix.getX(0, -sizeB - height);
y1 = calcMatrix.getY(0, -sizeB - height);
x2 = calcMatrix.getX(sizeA, -height);
y2 = calcMatrix.getY(sizeA, -height);
x3 = calcMatrix.getX(0, sizeB - height);
y3 = calcMatrix.getY(0, sizeB - height);
pipeline.batchQuad(src, x0, y0, x1, y1, x2, y2, x3, y3, 0, 0, 1, 1, tint, tint, tint, tint, 2);
}
if (src.showLeft) {
tint = Utils.getTintAppendFloatAlpha(src.fillLeft, alpha);
x0 = calcMatrix.getX(-sizeA, 0);
y0 = calcMatrix.getY(-sizeA, 0);
x1 = calcMatrix.getX(0, sizeB);
y1 = calcMatrix.getY(0, sizeB);
x2 = calcMatrix.getX(0, sizeB - height);
y2 = calcMatrix.getY(0, sizeB - height);
x3 = calcMatrix.getX(-sizeA, -height);
y3 = calcMatrix.getY(-sizeA, -height);
pipeline.batchQuad(src, x0, y0, x1, y1, x2, y2, x3, y3, 0, 0, 1, 1, tint, tint, tint, tint, 2);
}
if (src.showRight) {
tint = Utils.getTintAppendFloatAlpha(src.fillRight, alpha);
x0 = calcMatrix.getX(sizeA, 0);
y0 = calcMatrix.getY(sizeA, 0);
x1 = calcMatrix.getX(0, sizeB);
y1 = calcMatrix.getY(0, sizeB);
x2 = calcMatrix.getX(0, sizeB - height);
y2 = calcMatrix.getY(0, sizeB - height);
x3 = calcMatrix.getX(sizeA, -height);
y3 = calcMatrix.getY(sizeA, -height);
pipeline.batchQuad(src, x0, y0, x1, y1, x2, y2, x3, y3, 0, 0, 1, 1, tint, tint, tint, tint, 2);
}
renderer.pipelines.postBatch(src);
};
module2.exports = IsoBoxWebGLRenderer;
}
),
/***/
16933: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var IsoTriangleRender = __webpack_require__2(60561);
var Shape = __webpack_require__2(17803);
var IsoTriangle = new Class({
Extends: Shape,
Mixins: [
IsoTriangleRender
],
initialize: function IsoTriangle2(scene, x, y, size, height, reversed, fillTop, fillLeft, fillRight) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (size === void 0) {
size = 48;
}
if (height === void 0) {
height = 32;
}
if (reversed === void 0) {
reversed = false;
}
if (fillTop === void 0) {
fillTop = 15658734;
}
if (fillLeft === void 0) {
fillLeft = 10066329;
}
if (fillRight === void 0) {
fillRight = 13421772;
}
Shape.call(this, scene, "IsoTriangle", null);
this.projection = 4;
this.fillTop = fillTop;
this.fillLeft = fillLeft;
this.fillRight = fillRight;
this.showTop = true;
this.showLeft = true;
this.showRight = true;
this.isReversed = reversed;
this.isFilled = true;
this.setPosition(x, y);
this.setSize(size, height);
this.updateDisplayOrigin();
},
/**
* Sets the projection level of the iso triangle. Change this to change the 'angle' at which you are looking at the pyramid.
* This call can be chained.
*
* @method Phaser.GameObjects.IsoTriangle#setProjection
* @since 3.13.0
*
* @param {number} value - The value to set the projection to.
*
* @return {this} This Game Object instance.
*/
setProjection: function(value) {
this.projection = value;
return this;
},
/**
* Sets if the iso triangle will be rendered upside down or not.
* This call can be chained.
*
* @method Phaser.GameObjects.IsoTriangle#setReversed
* @since 3.13.0
*
* @param {boolean} reversed - Sets if the iso triangle will be rendered upside down or not.
*
* @return {this} This Game Object instance.
*/
setReversed: function(reversed) {
this.isReversed = reversed;
return this;
},
/**
* Sets which faces of the iso triangle will be rendered.
* This call can be chained.
*
* @method Phaser.GameObjects.IsoTriangle#setFaces
* @since 3.13.0
*
* @param {boolean} [showTop=true] - Show the top-face of the iso triangle (only if `reversed` is true)
* @param {boolean} [showLeft=true] - Show the left-face of the iso triangle.
* @param {boolean} [showRight=true] - Show the right-face of the iso triangle.
*
* @return {this} This Game Object instance.
*/
setFaces: function(showTop, showLeft, showRight) {
if (showTop === void 0) {
showTop = true;
}
if (showLeft === void 0) {
showLeft = true;
}
if (showRight === void 0) {
showRight = true;
}
this.showTop = showTop;
this.showLeft = showLeft;
this.showRight = showRight;
return this;
},
/**
* Sets the fill colors for each face of the iso triangle.
* This call can be chained.
*
* @method Phaser.GameObjects.IsoTriangle#setFillStyle
* @since 3.13.0
*
* @param {number} [fillTop] - The color used to fill the top of the iso triangle.
* @param {number} [fillLeft] - The color used to fill in the left-facing side of the iso triangle.
* @param {number} [fillRight] - The color used to fill in the right-facing side of the iso triangle.
*
* @return {this} This Game Object instance.
*/
setFillStyle: function(fillTop, fillLeft, fillRight) {
this.fillTop = fillTop;
this.fillLeft = fillLeft;
this.fillRight = fillRight;
this.isFilled = true;
return this;
}
});
module2.exports = IsoTriangle;
}
),
/***/
79590: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var FillStyleCanvas = __webpack_require__2(65960);
var SetTransform = __webpack_require__2(20926);
var IsoTriangleCanvasRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
var ctx = renderer.currentContext;
if (SetTransform(renderer, ctx, src, camera, parentMatrix) && src.isFilled) {
var size = src.width;
var height = src.height;
var sizeA = size / 2;
var sizeB = size / src.projection;
var reversed = src.isReversed;
if (src.showTop && reversed) {
FillStyleCanvas(ctx, src, src.fillTop);
ctx.beginPath();
ctx.moveTo(-sizeA, -height);
ctx.lineTo(0, -sizeB - height);
ctx.lineTo(sizeA, -height);
ctx.lineTo(0, sizeB - height);
ctx.fill();
}
if (src.showLeft) {
FillStyleCanvas(ctx, src, src.fillLeft);
ctx.beginPath();
if (reversed) {
ctx.moveTo(-sizeA, -height);
ctx.lineTo(0, sizeB);
ctx.lineTo(0, sizeB - height);
} else {
ctx.moveTo(-sizeA, 0);
ctx.lineTo(0, sizeB);
ctx.lineTo(0, sizeB - height);
}
ctx.fill();
}
if (src.showRight) {
FillStyleCanvas(ctx, src, src.fillRight);
ctx.beginPath();
if (reversed) {
ctx.moveTo(sizeA, -height);
ctx.lineTo(0, sizeB);
ctx.lineTo(0, sizeB - height);
} else {
ctx.moveTo(sizeA, 0);
ctx.lineTo(0, sizeB);
ctx.lineTo(0, sizeB - height);
}
ctx.fill();
}
ctx.restore();
}
};
module2.exports = IsoTriangleCanvasRenderer;
}
),
/***/
49803: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var GameObjectFactory = __webpack_require__2(39429);
var IsoTriangle = __webpack_require__2(16933);
GameObjectFactory.register("isotriangle", function(x, y, size, height, reversed, fillTop, fillLeft, fillRight) {
return this.displayList.add(new IsoTriangle(this.scene, x, y, size, height, reversed, fillTop, fillLeft, fillRight));
});
}
),
/***/
60561: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(51503);
}
if (true) {
renderCanvas = __webpack_require__2(79590);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
51503: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetCalcMatrix = __webpack_require__2(91296);
var Utils = __webpack_require__2(70554);
var IsoTriangleWebGLRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
var pipeline = renderer.pipelines.set(src.pipeline);
var result = GetCalcMatrix(src, camera, parentMatrix);
var calcMatrix = pipeline.calcMatrix.copyFrom(result.calc);
var size = src.width;
var height = src.height;
var sizeA = size / 2;
var sizeB = size / src.projection;
var reversed = src.isReversed;
var alpha = camera.alpha * src.alpha;
if (!src.isFilled) {
return;
}
renderer.pipelines.preBatch(src);
var tint;
var x0;
var y0;
var x1;
var y1;
var x2;
var y2;
if (src.showTop && reversed) {
tint = Utils.getTintAppendFloatAlpha(src.fillTop, alpha);
x0 = calcMatrix.getX(-sizeA, -height);
y0 = calcMatrix.getY(-sizeA, -height);
x1 = calcMatrix.getX(0, -sizeB - height);
y1 = calcMatrix.getY(0, -sizeB - height);
x2 = calcMatrix.getX(sizeA, -height);
y2 = calcMatrix.getY(sizeA, -height);
var x3 = calcMatrix.getX(0, sizeB - height);
var y3 = calcMatrix.getY(0, sizeB - height);
pipeline.batchQuad(src, x0, y0, x1, y1, x2, y2, x3, y3, 0, 0, 1, 1, tint, tint, tint, tint, 2);
}
if (src.showLeft) {
tint = Utils.getTintAppendFloatAlpha(src.fillLeft, alpha);
if (reversed) {
x0 = calcMatrix.getX(-sizeA, -height);
y0 = calcMatrix.getY(-sizeA, -height);
x1 = calcMatrix.getX(0, sizeB);
y1 = calcMatrix.getY(0, sizeB);
x2 = calcMatrix.getX(0, sizeB - height);
y2 = calcMatrix.getY(0, sizeB - height);
} else {
x0 = calcMatrix.getX(-sizeA, 0);
y0 = calcMatrix.getY(-sizeA, 0);
x1 = calcMatrix.getX(0, sizeB);
y1 = calcMatrix.getY(0, sizeB);
x2 = calcMatrix.getX(0, sizeB - height);
y2 = calcMatrix.getY(0, sizeB - height);
}
pipeline.batchTri(src, x0, y0, x1, y1, x2, y2, 0, 0, 1, 1, tint, tint, tint, 2);
}
if (src.showRight) {
tint = Utils.getTintAppendFloatAlpha(src.fillRight, alpha);
if (reversed) {
x0 = calcMatrix.getX(sizeA, -height);
y0 = calcMatrix.getY(sizeA, -height);
x1 = calcMatrix.getX(0, sizeB);
y1 = calcMatrix.getY(0, sizeB);
x2 = calcMatrix.getX(0, sizeB - height);
y2 = calcMatrix.getY(0, sizeB - height);
} else {
x0 = calcMatrix.getX(sizeA, 0);
y0 = calcMatrix.getY(sizeA, 0);
x1 = calcMatrix.getX(0, sizeB);
y1 = calcMatrix.getY(0, sizeB);
x2 = calcMatrix.getX(0, sizeB - height);
y2 = calcMatrix.getY(0, sizeB - height);
}
pipeline.batchTri(src, x0, y0, x1, y1, x2, y2, 0, 0, 1, 1, tint, tint, tint, 2);
}
renderer.pipelines.postBatch(src);
};
module2.exports = IsoTriangleWebGLRenderer;
}
),
/***/
57847: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Shape = __webpack_require__2(17803);
var GeomLine = __webpack_require__2(23031);
var LineRender = __webpack_require__2(36823);
var Line = new Class({
Extends: Shape,
Mixins: [
LineRender
],
initialize: function Line2(scene, x, y, x1, y1, x2, y2, strokeColor, strokeAlpha) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (x1 === void 0) {
x1 = 0;
}
if (y1 === void 0) {
y1 = 0;
}
if (x2 === void 0) {
x2 = 128;
}
if (y2 === void 0) {
y2 = 0;
}
Shape.call(this, scene, "Line", new GeomLine(x1, y1, x2, y2));
var width = Math.max(1, this.geom.right - this.geom.left);
var height = Math.max(1, this.geom.bottom - this.geom.top);
this.lineWidth = 1;
this._startWidth = 1;
this._endWidth = 1;
this.setPosition(x, y);
this.setSize(width, height);
if (strokeColor !== void 0) {
this.setStrokeStyle(1, strokeColor, strokeAlpha);
}
this.updateDisplayOrigin();
},
/**
* Sets the width of the line.
*
* When using the WebGL renderer you can have different start and end widths.
* When using the Canvas renderer only the `startWidth` value is used. The `endWidth` is ignored.
*
* This call can be chained.
*
* @method Phaser.GameObjects.Line#setLineWidth
* @since 3.13.0
*
* @param {number} startWidth - The start width of the line.
* @param {number} [endWidth] - The end width of the line. Only used in WebGL.
*
* @return {this} This Game Object instance.
*/
setLineWidth: function(startWidth, endWidth) {
if (endWidth === void 0) {
endWidth = startWidth;
}
this._startWidth = startWidth;
this._endWidth = endWidth;
this.lineWidth = startWidth;
return this;
},
/**
* Sets the start and end coordinates of this Line.
*
* @method Phaser.GameObjects.Line#setTo
* @since 3.13.0
*
* @param {number} [x1=0] - The horizontal position of the start of the line.
* @param {number} [y1=0] - The vertical position of the start of the line.
* @param {number} [x2=0] - The horizontal position of the end of the line.
* @param {number} [y2=0] - The vertical position of the end of the line.
*
* @return {this} This Line object.
*/
setTo: function(x1, y1, x2, y2) {
this.geom.setTo(x1, y1, x2, y2);
return this;
}
});
module2.exports = Line;
}
),
/***/
17440: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var LineStyleCanvas = __webpack_require__2(75177);
var SetTransform = __webpack_require__2(20926);
var LineCanvasRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
var ctx = renderer.currentContext;
if (SetTransform(renderer, ctx, src, camera, parentMatrix)) {
var dx = src._displayOriginX;
var dy = src._displayOriginY;
if (src.isStroked) {
LineStyleCanvas(ctx, src);
ctx.beginPath();
ctx.moveTo(src.geom.x1 - dx, src.geom.y1 - dy);
ctx.lineTo(src.geom.x2 - dx, src.geom.y2 - dy);
ctx.stroke();
}
ctx.restore();
}
};
module2.exports = LineCanvasRenderer;
}
),
/***/
2481: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var GameObjectFactory = __webpack_require__2(39429);
var Line = __webpack_require__2(57847);
GameObjectFactory.register("line", function(x, y, x1, y1, x2, y2, strokeColor, strokeAlpha) {
return this.displayList.add(new Line(this.scene, x, y, x1, y1, x2, y2, strokeColor, strokeAlpha));
});
}
),
/***/
36823: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(77385);
}
if (true) {
renderCanvas = __webpack_require__2(17440);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
77385: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetCalcMatrix = __webpack_require__2(91296);
var Utils = __webpack_require__2(70554);
var LineWebGLRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
var pipeline = renderer.pipelines.set(src.pipeline);
var result = GetCalcMatrix(src, camera, parentMatrix);
pipeline.calcMatrix.copyFrom(result.calc);
var dx = src._displayOriginX;
var dy = src._displayOriginY;
var alpha = camera.alpha * src.alpha;
renderer.pipelines.preBatch(src);
if (src.isStroked) {
var strokeTint = pipeline.strokeTint;
var color = Utils.getTintAppendFloatAlpha(src.strokeColor, src.strokeAlpha * alpha);
strokeTint.TL = color;
strokeTint.TR = color;
strokeTint.BL = color;
strokeTint.BR = color;
pipeline.batchLine(
src.geom.x1 - dx,
src.geom.y1 - dy,
src.geom.x2 - dx,
src.geom.y2 - dy,
src._startWidth / 2,
src._endWidth / 2,
1,
0,
false,
result.sprite,
result.camera
);
}
renderer.pipelines.postBatch(src);
};
module2.exports = LineWebGLRenderer;
}
),
/***/
24949: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PolygonRender = __webpack_require__2(90273);
var Class = __webpack_require__2(83419);
var Earcut = __webpack_require__2(94811);
var GetAABB = __webpack_require__2(13829);
var GeomPolygon = __webpack_require__2(25717);
var Shape = __webpack_require__2(17803);
var Smooth = __webpack_require__2(5469);
var Polygon = new Class({
Extends: Shape,
Mixins: [
PolygonRender
],
initialize: function Polygon2(scene, x, y, points, fillColor, fillAlpha) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
Shape.call(this, scene, "Polygon", new GeomPolygon(points));
var bounds = GetAABB(this.geom);
this.setPosition(x, y);
this.setSize(bounds.width, bounds.height);
if (fillColor !== void 0) {
this.setFillStyle(fillColor, fillAlpha);
}
this.updateDisplayOrigin();
this.updateData();
},
/**
* Smooths the polygon over the number of iterations specified.
* The base polygon data will be updated and replaced with the smoothed values.
* This call can be chained.
*
* @method Phaser.GameObjects.Polygon#smooth
* @since 3.13.0
*
* @param {number} [iterations=1] - The number of times to apply the polygon smoothing.
*
* @return {this} This Game Object instance.
*/
smooth: function(iterations) {
if (iterations === void 0) {
iterations = 1;
}
for (var i = 0; i < iterations; i++) {
Smooth(this.geom);
}
return this.updateData();
},
/**
* Sets this Polygon to the given points.
*
* The points can be set from a variety of formats:
*
* - A string containing paired values separated by a single space: `'40 0 40 20 100 20 100 80 40 80 40 100 0 50'`
* - An array of Point objects: `[new Phaser.Point(x1, y1), ...]`
* - An array of objects with public x/y properties: `[obj1, obj2, ...]`
* - An array of paired numbers that represent point coordinates: `[x1,y1, x2,y2, ...]`
* - An array of arrays with two elements representing x/y coordinates: `[[x1, y1], [x2, y2], ...]`
*
* Calling this method will reset the size (width, height) and display origin of this Shape.
*
* It also runs both GetAABB and EarCut on the given points, so please be careful not to do this
* at a high frequency, or with too many points.
*
* @method Phaser.GameObjects.Polygon#setTo
* @since 3.60.0
*
* @param {(string|number[]|Phaser.Types.Math.Vector2Like[])} [points] - Points defining the perimeter of this polygon. Please check function description above for the different supported formats.
*
* @return {this} This Game Object instance.
*/
setTo: function(points) {
this.geom.setTo(points);
var bounds = GetAABB(this.geom);
this.setSize(bounds.width, bounds.height);
this.updateDisplayOrigin();
return this.updateData();
},
/**
* Internal method that updates the data and path values.
*
* @method Phaser.GameObjects.Polygon#updateData
* @private
* @since 3.13.0
*
* @return {this} This Game Object instance.
*/
updateData: function() {
var path = [];
var points = this.geom.points;
for (var i = 0; i < points.length; i++) {
path.push(points[i].x, points[i].y);
}
path.push(points[0].x, points[0].y);
this.pathIndexes = Earcut(path);
this.pathData = path;
return this;
}
});
module2.exports = Polygon;
}
),
/***/
38710: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var FillStyleCanvas = __webpack_require__2(65960);
var LineStyleCanvas = __webpack_require__2(75177);
var SetTransform = __webpack_require__2(20926);
var PolygonCanvasRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
var ctx = renderer.currentContext;
if (SetTransform(renderer, ctx, src, camera, parentMatrix)) {
var dx = src._displayOriginX;
var dy = src._displayOriginY;
var path = src.pathData;
var pathLength = path.length - 1;
var px1 = path[0] - dx;
var py1 = path[1] - dy;
ctx.beginPath();
ctx.moveTo(px1, py1);
if (!src.closePath) {
pathLength -= 2;
}
for (var i = 2; i < pathLength; i += 2) {
var px2 = path[i] - dx;
var py2 = path[i + 1] - dy;
ctx.lineTo(px2, py2);
}
if (src.closePath) {
ctx.closePath();
}
if (src.isFilled) {
FillStyleCanvas(ctx, src);
ctx.fill();
}
if (src.isStroked) {
LineStyleCanvas(ctx, src);
ctx.stroke();
}
ctx.restore();
}
};
module2.exports = PolygonCanvasRenderer;
}
),
/***/
64827: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var GameObjectFactory = __webpack_require__2(39429);
var Polygon = __webpack_require__2(24949);
GameObjectFactory.register("polygon", function(x, y, points, fillColor, fillAlpha) {
return this.displayList.add(new Polygon(this.scene, x, y, points, fillColor, fillAlpha));
});
}
),
/***/
90273: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(73695);
}
if (true) {
renderCanvas = __webpack_require__2(38710);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
73695: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var FillPathWebGL = __webpack_require__2(10441);
var GetCalcMatrix = __webpack_require__2(91296);
var StrokePathWebGL = __webpack_require__2(34682);
var PolygonWebGLRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
var pipeline = renderer.pipelines.set(src.pipeline);
var result = GetCalcMatrix(src, camera, parentMatrix);
var calcMatrix = pipeline.calcMatrix.copyFrom(result.calc);
var dx = src._displayOriginX;
var dy = src._displayOriginY;
var alpha = camera.alpha * src.alpha;
renderer.pipelines.preBatch(src);
if (src.isFilled) {
FillPathWebGL(pipeline, calcMatrix, src, alpha, dx, dy);
}
if (src.isStroked) {
StrokePathWebGL(pipeline, src, alpha, dx, dy);
}
renderer.pipelines.postBatch(src);
};
module2.exports = PolygonWebGLRenderer;
}
),
/***/
74561: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var GeomRectangle = __webpack_require__2(87841);
var Shape = __webpack_require__2(17803);
var RectangleRender = __webpack_require__2(95597);
var Rectangle = new Class({
Extends: Shape,
Mixins: [
RectangleRender
],
initialize: function Rectangle2(scene, x, y, width, height, fillColor, fillAlpha) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (width === void 0) {
width = 128;
}
if (height === void 0) {
height = 128;
}
Shape.call(this, scene, "Rectangle", new GeomRectangle(0, 0, width, height));
this.setPosition(x, y);
this.setSize(width, height);
if (fillColor !== void 0) {
this.setFillStyle(fillColor, fillAlpha);
}
this.updateDisplayOrigin();
this.updateData();
},
/**
* Sets the internal size of this Rectangle, as used for frame or physics body creation.
*
* If you have assigned a custom input hit area for this Rectangle, changing the Rectangle size will _not_ change the
* size of the hit area. To do this you should adjust the `input.hitArea` object directly.
*
* @method Phaser.GameObjects.Rectangle#setSize
* @since 3.13.0
*
* @param {number} width - The width of this Game Object.
* @param {number} height - The height of this Game Object.
*
* @return {this} This Game Object instance.
*/
setSize: function(width, height) {
this.width = width;
this.height = height;
this.geom.setSize(width, height);
this.updateData();
this.updateDisplayOrigin();
var input = this.input;
if (input && !input.customHitArea) {
input.hitArea.width = width;
input.hitArea.height = height;
}
return this;
},
/**
* Internal method that updates the data and path values.
*
* @method Phaser.GameObjects.Rectangle#updateData
* @private
* @since 3.13.0
*
* @return {this} This Game Object instance.
*/
updateData: function() {
var path = [];
var rect = this.geom;
var line = this._tempLine;
rect.getLineA(line);
path.push(line.x1, line.y1, line.x2, line.y2);
rect.getLineB(line);
path.push(line.x2, line.y2);
rect.getLineC(line);
path.push(line.x2, line.y2);
rect.getLineD(line);
path.push(line.x2, line.y2);
this.pathData = path;
return this;
}
});
module2.exports = Rectangle;
}
),
/***/
48682: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var FillStyleCanvas = __webpack_require__2(65960);
var LineStyleCanvas = __webpack_require__2(75177);
var SetTransform = __webpack_require__2(20926);
var RectangleCanvasRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
var ctx = renderer.currentContext;
if (SetTransform(renderer, ctx, src, camera, parentMatrix)) {
var dx = src._displayOriginX;
var dy = src._displayOriginY;
if (src.isFilled) {
FillStyleCanvas(ctx, src);
ctx.fillRect(
-dx,
-dy,
src.width,
src.height
);
}
if (src.isStroked) {
LineStyleCanvas(ctx, src);
ctx.beginPath();
ctx.rect(
-dx,
-dy,
src.width,
src.height
);
ctx.stroke();
}
ctx.restore();
}
};
module2.exports = RectangleCanvasRenderer;
}
),
/***/
87959: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var GameObjectFactory = __webpack_require__2(39429);
var Rectangle = __webpack_require__2(74561);
GameObjectFactory.register("rectangle", function(x, y, width, height, fillColor, fillAlpha) {
return this.displayList.add(new Rectangle(this.scene, x, y, width, height, fillColor, fillAlpha));
});
}
),
/***/
95597: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(52059);
}
if (true) {
renderCanvas = __webpack_require__2(48682);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
52059: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetCalcMatrix = __webpack_require__2(91296);
var StrokePathWebGL = __webpack_require__2(34682);
var Utils = __webpack_require__2(70554);
var RectangleWebGLRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
var pipeline = renderer.pipelines.set(src.pipeline);
var result = GetCalcMatrix(src, camera, parentMatrix);
pipeline.calcMatrix.copyFrom(result.calc);
var dx = src._displayOriginX;
var dy = src._displayOriginY;
var alpha = camera.alpha * src.alpha;
renderer.pipelines.preBatch(src);
if (src.isFilled) {
var fillTint = pipeline.fillTint;
var fillTintColor = Utils.getTintAppendFloatAlpha(src.fillColor, src.fillAlpha * alpha);
fillTint.TL = fillTintColor;
fillTint.TR = fillTintColor;
fillTint.BL = fillTintColor;
fillTint.BR = fillTintColor;
pipeline.batchFillRect(
-dx,
-dy,
src.width,
src.height
);
}
if (src.isStroked) {
StrokePathWebGL(pipeline, src, alpha, dx, dy);
}
renderer.pipelines.postBatch(src);
};
module2.exports = RectangleWebGLRenderer;
}
),
/***/
55911: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var StarRender = __webpack_require__2(81991);
var Class = __webpack_require__2(83419);
var Earcut = __webpack_require__2(94811);
var Shape = __webpack_require__2(17803);
var Star = new Class({
Extends: Shape,
Mixins: [
StarRender
],
initialize: function Star2(scene, x, y, points, innerRadius, outerRadius, fillColor, fillAlpha) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (points === void 0) {
points = 5;
}
if (innerRadius === void 0) {
innerRadius = 32;
}
if (outerRadius === void 0) {
outerRadius = 64;
}
Shape.call(this, scene, "Star", null);
this._points = points;
this._innerRadius = innerRadius;
this._outerRadius = outerRadius;
this.setPosition(x, y);
this.setSize(outerRadius * 2, outerRadius * 2);
if (fillColor !== void 0) {
this.setFillStyle(fillColor, fillAlpha);
}
this.updateDisplayOrigin();
this.updateData();
},
/**
* Sets the number of points that make up the Star shape.
* This call can be chained.
*
* @method Phaser.GameObjects.Star#setPoints
* @since 3.13.0
*
* @param {number} value - The amount of points the Star will have.
*
* @return {this} This Game Object instance.
*/
setPoints: function(value) {
this._points = value;
return this.updateData();
},
/**
* Sets the inner radius of the Star shape.
* This call can be chained.
*
* @method Phaser.GameObjects.Star#setInnerRadius
* @since 3.13.0
*
* @param {number} value - The amount to set the inner radius to.
*
* @return {this} This Game Object instance.
*/
setInnerRadius: function(value) {
this._innerRadius = value;
return this.updateData();
},
/**
* Sets the outer radius of the Star shape.
* This call can be chained.
*
* @method Phaser.GameObjects.Star#setOuterRadius
* @since 3.13.0
*
* @param {number} value - The amount to set the outer radius to.
*
* @return {this} This Game Object instance.
*/
setOuterRadius: function(value) {
this._outerRadius = value;
return this.updateData();
},
/**
* The number of points that make up the Star shape.
*
* @name Phaser.GameObjects.Star#points
* @type {number}
* @default 5
* @since 3.13.0
*/
points: {
get: function() {
return this._points;
},
set: function(value) {
this._points = value;
this.updateData();
}
},
/**
* The inner radius of the Star shape.
*
* @name Phaser.GameObjects.Star#innerRadius
* @type {number}
* @default 32
* @since 3.13.0
*/
innerRadius: {
get: function() {
return this._innerRadius;
},
set: function(value) {
this._innerRadius = value;
this.updateData();
}
},
/**
* The outer radius of the Star shape.
*
* @name Phaser.GameObjects.Star#outerRadius
* @type {number}
* @default 64
* @since 3.13.0
*/
outerRadius: {
get: function() {
return this._outerRadius;
},
set: function(value) {
this._outerRadius = value;
this.updateData();
}
},
/**
* Internal method that updates the data and path values.
*
* @method Phaser.GameObjects.Star#updateData
* @private
* @since 3.13.0
*
* @return {this} This Game Object instance.
*/
updateData: function() {
var path = [];
var points = this._points;
var innerRadius = this._innerRadius;
var outerRadius = this._outerRadius;
var rot = Math.PI / 2 * 3;
var step = Math.PI / points;
var x = outerRadius;
var y = outerRadius;
path.push(x, y + -outerRadius);
for (var i = 0; i < points; i++) {
path.push(x + Math.cos(rot) * outerRadius, y + Math.sin(rot) * outerRadius);
rot += step;
path.push(x + Math.cos(rot) * innerRadius, y + Math.sin(rot) * innerRadius);
rot += step;
}
path.push(x, y + -outerRadius);
this.pathIndexes = Earcut(path);
this.pathData = path;
return this;
}
});
module2.exports = Star;
}
),
/***/
64272: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var FillStyleCanvas = __webpack_require__2(65960);
var LineStyleCanvas = __webpack_require__2(75177);
var SetTransform = __webpack_require__2(20926);
var StarCanvasRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
var ctx = renderer.currentContext;
if (SetTransform(renderer, ctx, src, camera, parentMatrix)) {
var dx = src._displayOriginX;
var dy = src._displayOriginY;
var path = src.pathData;
var pathLength = path.length - 1;
var px1 = path[0] - dx;
var py1 = path[1] - dy;
ctx.beginPath();
ctx.moveTo(px1, py1);
if (!src.closePath) {
pathLength -= 2;
}
for (var i = 2; i < pathLength; i += 2) {
var px2 = path[i] - dx;
var py2 = path[i + 1] - dy;
ctx.lineTo(px2, py2);
}
ctx.closePath();
if (src.isFilled) {
FillStyleCanvas(ctx, src);
ctx.fill();
}
if (src.isStroked) {
LineStyleCanvas(ctx, src);
ctx.stroke();
}
ctx.restore();
}
};
module2.exports = StarCanvasRenderer;
}
),
/***/
93697: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var Star = __webpack_require__2(55911);
var GameObjectFactory = __webpack_require__2(39429);
GameObjectFactory.register("star", function(x, y, points, innerRadius, outerRadius, fillColor, fillAlpha) {
return this.displayList.add(new Star(this.scene, x, y, points, innerRadius, outerRadius, fillColor, fillAlpha));
});
}
),
/***/
81991: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(57017);
}
if (true) {
renderCanvas = __webpack_require__2(64272);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
57017: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var FillPathWebGL = __webpack_require__2(10441);
var GetCalcMatrix = __webpack_require__2(91296);
var StrokePathWebGL = __webpack_require__2(34682);
var StarWebGLRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
var pipeline = renderer.pipelines.set(src.pipeline);
var result = GetCalcMatrix(src, camera, parentMatrix);
var calcMatrix = pipeline.calcMatrix.copyFrom(result.calc);
var dx = src._displayOriginX;
var dy = src._displayOriginY;
var alpha = camera.alpha * src.alpha;
renderer.pipelines.preBatch(src);
if (src.isFilled) {
FillPathWebGL(pipeline, calcMatrix, src, alpha, dx, dy);
}
if (src.isStroked) {
StrokePathWebGL(pipeline, src, alpha, dx, dy);
}
renderer.pipelines.postBatch(src);
};
module2.exports = StarWebGLRenderer;
}
),
/***/
36931: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Shape = __webpack_require__2(17803);
var GeomTriangle = __webpack_require__2(16483);
var TriangleRender = __webpack_require__2(96195);
var Triangle = new Class({
Extends: Shape,
Mixins: [
TriangleRender
],
initialize: function Triangle2(scene, x, y, x1, y1, x2, y2, x3, y3, fillColor, fillAlpha) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (x1 === void 0) {
x1 = 0;
}
if (y1 === void 0) {
y1 = 128;
}
if (x2 === void 0) {
x2 = 64;
}
if (y2 === void 0) {
y2 = 0;
}
if (x3 === void 0) {
x3 = 128;
}
if (y3 === void 0) {
y3 = 128;
}
Shape.call(this, scene, "Triangle", new GeomTriangle(x1, y1, x2, y2, x3, y3));
var width = this.geom.right - this.geom.left;
var height = this.geom.bottom - this.geom.top;
this.setPosition(x, y);
this.setSize(width, height);
if (fillColor !== void 0) {
this.setFillStyle(fillColor, fillAlpha);
}
this.updateDisplayOrigin();
this.updateData();
},
/**
* Sets the data for the lines that make up this Triangle shape.
*
* @method Phaser.GameObjects.Triangle#setTo
* @since 3.13.0
*
* @param {number} [x1=0] - The horizontal position of the first point in the triangle.
* @param {number} [y1=0] - The vertical position of the first point in the triangle.
* @param {number} [x2=0] - The horizontal position of the second point in the triangle.
* @param {number} [y2=0] - The vertical position of the second point in the triangle.
* @param {number} [x3=0] - The horizontal position of the third point in the triangle.
* @param {number} [y3=0] - The vertical position of the third point in the triangle.
*
* @return {this} This Game Object instance.
*/
setTo: function(x1, y1, x2, y2, x3, y3) {
this.geom.setTo(x1, y1, x2, y2, x3, y3);
return this.updateData();
},
/**
* Internal method that updates the data and path values.
*
* @method Phaser.GameObjects.Triangle#updateData
* @private
* @since 3.13.0
*
* @return {this} This Game Object instance.
*/
updateData: function() {
var path = [];
var tri = this.geom;
var line = this._tempLine;
tri.getLineA(line);
path.push(line.x1, line.y1, line.x2, line.y2);
tri.getLineB(line);
path.push(line.x2, line.y2);
tri.getLineC(line);
path.push(line.x2, line.y2);
this.pathData = path;
return this;
}
});
module2.exports = Triangle;
}
),
/***/
85172: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var FillStyleCanvas = __webpack_require__2(65960);
var LineStyleCanvas = __webpack_require__2(75177);
var SetTransform = __webpack_require__2(20926);
var TriangleCanvasRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
var ctx = renderer.currentContext;
if (SetTransform(renderer, ctx, src, camera, parentMatrix)) {
var dx = src._displayOriginX;
var dy = src._displayOriginY;
var x1 = src.geom.x1 - dx;
var y1 = src.geom.y1 - dy;
var x2 = src.geom.x2 - dx;
var y2 = src.geom.y2 - dy;
var x3 = src.geom.x3 - dx;
var y3 = src.geom.y3 - dy;
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.lineTo(x3, y3);
ctx.closePath();
if (src.isFilled) {
FillStyleCanvas(ctx, src);
ctx.fill();
}
if (src.isStroked) {
LineStyleCanvas(ctx, src);
ctx.stroke();
}
ctx.restore();
}
};
module2.exports = TriangleCanvasRenderer;
}
),
/***/
45245: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var GameObjectFactory = __webpack_require__2(39429);
var Triangle = __webpack_require__2(36931);
GameObjectFactory.register("triangle", function(x, y, x1, y1, x2, y2, x3, y3, fillColor, fillAlpha) {
return this.displayList.add(new Triangle(this.scene, x, y, x1, y1, x2, y2, x3, y3, fillColor, fillAlpha));
});
}
),
/***/
96195: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(83253);
}
if (true) {
renderCanvas = __webpack_require__2(85172);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
83253: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetCalcMatrix = __webpack_require__2(91296);
var StrokePathWebGL = __webpack_require__2(34682);
var Utils = __webpack_require__2(70554);
var TriangleWebGLRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
var pipeline = renderer.pipelines.set(src.pipeline);
var result = GetCalcMatrix(src, camera, parentMatrix);
pipeline.calcMatrix.copyFrom(result.calc);
var dx = src._displayOriginX;
var dy = src._displayOriginY;
var alpha = camera.alpha * src.alpha;
renderer.pipelines.preBatch(src);
if (src.isFilled) {
var fillTint = pipeline.fillTint;
var fillTintColor = Utils.getTintAppendFloatAlpha(src.fillColor, src.fillAlpha * alpha);
fillTint.TL = fillTintColor;
fillTint.TR = fillTintColor;
fillTint.BL = fillTintColor;
fillTint.BR = fillTintColor;
var x1 = src.geom.x1 - dx;
var y1 = src.geom.y1 - dy;
var x2 = src.geom.x2 - dx;
var y2 = src.geom.y2 - dy;
var x3 = src.geom.x3 - dx;
var y3 = src.geom.y3 - dy;
pipeline.batchFillTriangle(
x1,
y1,
x2,
y2,
x3,
y3,
result.sprite,
result.camera
);
}
if (src.isStroked) {
StrokePathWebGL(pipeline, src, alpha, dx, dy);
}
renderer.pipelines.postBatch(src);
};
module2.exports = TriangleWebGLRenderer;
}
),
/***/
68287: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var AnimationState = __webpack_require__2(9674);
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31401);
var GameObject = __webpack_require__2(95643);
var SpriteRender = __webpack_require__2(92751);
var Sprite = new Class({
Extends: GameObject,
Mixins: [
Components.Alpha,
Components.BlendMode,
Components.Depth,
Components.Flip,
Components.GetBounds,
Components.Mask,
Components.Origin,
Components.Pipeline,
Components.PostPipeline,
Components.ScrollFactor,
Components.Size,
Components.TextureCrop,
Components.Tint,
Components.Transform,
Components.Visible,
SpriteRender
],
initialize: function Sprite2(scene, x, y, texture, frame) {
GameObject.call(this, scene, "Sprite");
this._crop = this.resetCropObject();
this.anims = new AnimationState(this);
this.setTexture(texture, frame);
this.setPosition(x, y);
this.setSizeToFrame();
this.setOriginFromFrame();
this.initPipeline();
this.initPostPipeline(true);
},
// Overrides Game Object method
addedToScene: function() {
this.scene.sys.updateList.add(this);
},
// Overrides Game Object method
removedFromScene: function() {
this.scene.sys.updateList.remove(this);
},
/**
* Update this Sprite's animations.
*
* @method Phaser.GameObjects.Sprite#preUpdate
* @protected
* @since 3.0.0
*
* @param {number} time - The current timestamp.
* @param {number} delta - The delta time, in ms, elapsed since the last frame.
*/
preUpdate: function(time, delta) {
this.anims.update(time, delta);
},
/**
* Start playing the given animation on this Sprite.
*
* Animations in Phaser can either belong to the global Animation Manager, or specifically to this Sprite.
*
* The benefit of a global animation is that multiple Sprites can all play the same animation, without
* having to duplicate the data. You can just create it once and then play it on any Sprite.
*
* The following code shows how to create a global repeating animation. The animation will be created
* from all of the frames within the sprite sheet that was loaded with the key 'muybridge':
*
* ```javascript
* var config = {
* key: 'run',
* frames: 'muybridge',
* frameRate: 15,
* repeat: -1
* };
*
* // This code should be run from within a Scene:
* this.anims.create(config);
* ```
*
* However, if you wish to create an animation that is unique to this Sprite, and this Sprite alone,
* you can call the `Animation.create` method instead. It accepts the exact same parameters as when
* creating a global animation, however the resulting data is kept locally in this Sprite.
*
* With the animation created, either globally or locally, you can now play it on this Sprite:
*
* ```javascript
* this.add.sprite(x, y).play('run');
* ```
*
* Alternatively, if you wish to run it at a different frame rate, for example, you can pass a config
* object instead:
*
* ```javascript
* this.add.sprite(x, y).play({ key: 'run', frameRate: 24 });
* ```
*
* When playing an animation on a Sprite it will first check to see if it can find a matching key
* locally within the Sprite. If it can, it will play the local animation. If not, it will then
* search the global Animation Manager and look for it there.
*
* If you need a Sprite to be able to play both local and global animations, make sure they don't
* have conflicting keys.
*
* See the documentation for the `PlayAnimationConfig` config object for more details about this.
*
* Also, see the documentation in the Animation Manager for further details on creating animations.
*
* @method Phaser.GameObjects.Sprite#play
* @fires Phaser.Animations.Events#ANIMATION_START
* @since 3.0.0
*
* @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object.
* @param {boolean} [ignoreIfPlaying=false] - If an animation is already playing then ignore this call.
*
* @return {this} This Game Object.
*/
play: function(key, ignoreIfPlaying) {
return this.anims.play(key, ignoreIfPlaying);
},
/**
* Start playing the given animation on this Sprite, in reverse.
*
* Animations in Phaser can either belong to the global Animation Manager, or specifically to this Sprite.
*
* The benefit of a global animation is that multiple Sprites can all play the same animation, without
* having to duplicate the data. You can just create it once and then play it on any Sprite.
*
* The following code shows how to create a global repeating animation. The animation will be created
* from all of the frames within the sprite sheet that was loaded with the key 'muybridge':
*
* ```javascript
* var config = {
* key: 'run',
* frames: 'muybridge',
* frameRate: 15,
* repeat: -1
* };
*
* // This code should be run from within a Scene:
* this.anims.create(config);
* ```
*
* However, if you wish to create an animation that is unique to this Sprite, and this Sprite alone,
* you can call the `Animation.create` method instead. It accepts the exact same parameters as when
* creating a global animation, however the resulting data is kept locally in this Sprite.
*
* With the animation created, either globally or locally, you can now play it on this Sprite:
*
* ```javascript
* this.add.sprite(x, y).playReverse('run');
* ```
*
* Alternatively, if you wish to run it at a different frame rate, for example, you can pass a config
* object instead:
*
* ```javascript
* this.add.sprite(x, y).playReverse({ key: 'run', frameRate: 24 });
* ```
*
* When playing an animation on a Sprite it will first check to see if it can find a matching key
* locally within the Sprite. If it can, it will play the local animation. If not, it will then
* search the global Animation Manager and look for it there.
*
* If you need a Sprite to be able to play both local and global animations, make sure they don't
* have conflicting keys.
*
* See the documentation for the `PlayAnimationConfig` config object for more details about this.
*
* Also, see the documentation in the Animation Manager for further details on creating animations.
*
* @method Phaser.GameObjects.Sprite#playReverse
* @fires Phaser.Animations.Events#ANIMATION_START
* @since 3.50.0
*
* @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object.
* @param {boolean} [ignoreIfPlaying=false] - If an animation is already playing then ignore this call.
*
* @return {this} This Game Object.
*/
playReverse: function(key, ignoreIfPlaying) {
return this.anims.playReverse(key, ignoreIfPlaying);
},
/**
* Waits for the specified delay, in milliseconds, then starts playback of the given animation.
*
* If the animation _also_ has a delay value set in its config, it will be **added** to the delay given here.
*
* If an animation is already running and a new animation is given to this method, it will wait for
* the given delay before starting the new animation.
*
* If no animation is currently running, the given one begins after the delay.
*
* When playing an animation on a Sprite it will first check to see if it can find a matching key
* locally within the Sprite. If it can, it will play the local animation. If not, it will then
* search the global Animation Manager and look for it there.
*
* Prior to Phaser 3.50 this method was called 'delayedPlay'.
*
* @method Phaser.GameObjects.Sprite#playAfterDelay
* @fires Phaser.Animations.Events#ANIMATION_START
* @since 3.50.0
*
* @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object.
* @param {number} delay - The delay, in milliseconds, to wait before starting the animation playing.
*
* @return {this} This Game Object.
*/
playAfterDelay: function(key, delay) {
return this.anims.playAfterDelay(key, delay);
},
/**
* Waits for the current animation to complete the `repeatCount` number of repeat cycles, then starts playback
* of the given animation.
*
* You can use this to ensure there are no harsh jumps between two sets of animations, i.e. going from an
* idle animation to a walking animation, by making them blend smoothly into each other.
*
* If no animation is currently running, the given one will start immediately.
*
* When playing an animation on a Sprite it will first check to see if it can find a matching key
* locally within the Sprite. If it can, it will play the local animation. If not, it will then
* search the global Animation Manager and look for it there.
*
* @method Phaser.GameObjects.Sprite#playAfterRepeat
* @fires Phaser.Animations.Events#ANIMATION_START
* @since 3.50.0
*
* @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig)} key - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object.
* @param {number} [repeatCount=1] - How many times should the animation repeat before the next one starts?
*
* @return {this} This Game Object.
*/
playAfterRepeat: function(key, repeatCount) {
return this.anims.playAfterRepeat(key, repeatCount);
},
/**
* Sets an animation, or an array of animations, to be played immediately after the current one completes or stops.
*
* The current animation must enter a 'completed' state for this to happen, i.e. finish all of its repeats, delays, etc,
* or have the `stop` method called directly on it.
*
* An animation set to repeat forever will never enter a completed state.
*
* You can chain a new animation at any point, including before the current one starts playing, during it,
* or when it ends (via its `animationcomplete` event).
*
* Chained animations are specific to a Game Object, meaning different Game Objects can have different chained
* animations without impacting the animation they're playing.
*
* Call this method with no arguments to reset all currently chained animations.
*
* When playing an animation on a Sprite it will first check to see if it can find a matching key
* locally within the Sprite. If it can, it will play the local animation. If not, it will then
* search the global Animation Manager and look for it there.
*
* @method Phaser.GameObjects.Sprite#chain
* @since 3.50.0
*
* @param {(string|Phaser.Animations.Animation|Phaser.Types.Animations.PlayAnimationConfig|string[]|Phaser.Animations.Animation[]|Phaser.Types.Animations.PlayAnimationConfig[])} [key] - The string-based key of the animation to play, or an Animation instance, or a `PlayAnimationConfig` object, or an array of them.
*
* @return {this} This Game Object.
*/
chain: function(key) {
return this.anims.chain(key);
},
/**
* Immediately stops the current animation from playing and dispatches the `ANIMATION_STOP` events.
*
* If no animation is playing, no event will be dispatched.
*
* If there is another animation queued (via the `chain` method) then it will start playing immediately.
*
* @method Phaser.GameObjects.Sprite#stop
* @fires Phaser.Animations.Events#ANIMATION_STOP
* @since 3.50.0
*
* @return {this} This Game Object.
*/
stop: function() {
return this.anims.stop();
},
/**
* Stops the current animation from playing after the specified time delay, given in milliseconds.
*
* It then dispatches the `ANIMATION_STOP` event.
*
* If no animation is running, no events will be dispatched.
*
* If there is another animation in the queue (set via the `chain` method) then it will start playing,
* when the current one stops.
*
* @method Phaser.GameObjects.Sprite#stopAfterDelay
* @fires Phaser.Animations.Events#ANIMATION_STOP
* @since 3.50.0
*
* @param {number} delay - The number of milliseconds to wait before stopping this animation.
*
* @return {this} This Game Object.
*/
stopAfterDelay: function(delay) {
return this.anims.stopAfterDelay(delay);
},
/**
* Stops the current animation from playing after the given number of repeats.
*
* It then dispatches the `ANIMATION_STOP` event.
*
* If no animation is running, no events will be dispatched.
*
* If there is another animation in the queue (set via the `chain` method) then it will start playing,
* when the current one stops.
*
* @method Phaser.GameObjects.Sprite#stopAfterRepeat
* @fires Phaser.Animations.Events#ANIMATION_STOP
* @since 3.50.0
*
* @param {number} [repeatCount=1] - How many times should the animation repeat before stopping?
*
* @return {this} This Game Object.
*/
stopAfterRepeat: function(repeatCount) {
return this.anims.stopAfterRepeat(repeatCount);
},
/**
* Stops the current animation from playing when it next sets the given frame.
* If this frame doesn't exist within the animation it will not stop it from playing.
*
* It then dispatches the `ANIMATION_STOP` event.
*
* If no animation is running, no events will be dispatched.
*
* If there is another animation in the queue (set via the `chain` method) then it will start playing,
* when the current one stops.
*
* @method Phaser.GameObjects.Sprite#stopOnFrame
* @fires Phaser.Animations.Events#ANIMATION_STOP
* @since 3.50.0
*
* @param {Phaser.Animations.AnimationFrame} frame - The frame to check before stopping this animation.
*
* @return {this} This Game Object.
*/
stopOnFrame: function(frame) {
return this.anims.stopOnFrame(frame);
},
/**
* Build a JSON representation of this Sprite.
*
* @method Phaser.GameObjects.Sprite#toJSON
* @since 3.0.0
*
* @return {Phaser.Types.GameObjects.JSONGameObject} A JSON representation of the Game Object.
*/
toJSON: function() {
return Components.ToJSON(this);
},
/**
* Handles the pre-destroy step for the Sprite, which removes the Animation component.
*
* @method Phaser.GameObjects.Sprite#preDestroy
* @private
* @since 3.14.0
*/
preDestroy: function() {
this.anims.destroy();
this.anims = void 0;
}
});
module2.exports = Sprite;
}
),
/***/
76552: (
/***/
(module2) => {
var SpriteCanvasRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
renderer.batchSprite(src, src.frame, camera, parentMatrix);
};
module2.exports = SpriteCanvasRenderer;
}
),
/***/
15567: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var BuildGameObject = __webpack_require__2(25305);
var BuildGameObjectAnimation = __webpack_require__2(13059);
var GameObjectCreator = __webpack_require__2(44603);
var GetAdvancedValue = __webpack_require__2(23568);
var Sprite = __webpack_require__2(68287);
GameObjectCreator.register("sprite", function(config, addToScene) {
if (config === void 0) {
config = {};
}
var key = GetAdvancedValue(config, "key", null);
var frame = GetAdvancedValue(config, "frame", null);
var sprite = new Sprite(this.scene, 0, 0, key, frame);
if (addToScene !== void 0) {
config.add = addToScene;
}
BuildGameObject(this.scene, sprite, config);
BuildGameObjectAnimation(sprite, config);
return sprite;
});
}
),
/***/
46409: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var GameObjectFactory = __webpack_require__2(39429);
var Sprite = __webpack_require__2(68287);
GameObjectFactory.register("sprite", function(x, y, texture, frame) {
return this.displayList.add(new Sprite(this.scene, x, y, texture, frame));
});
}
),
/***/
92751: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(9409);
}
if (true) {
renderCanvas = __webpack_require__2(76552);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
9409: (
/***/
(module2) => {
var SpriteWebGLRenderer = function(renderer, src, camera, parentMatrix) {
camera.addToRenderList(src);
src.pipeline.batchSprite(src, camera, parentMatrix);
};
module2.exports = SpriteWebGLRenderer;
}
),
/***/
14220: (
/***/
(module2) => {
var GetTextSize = function(text, size, lines) {
var canvas = text.canvas;
var context = text.context;
var style = text.style;
var lineWidths = [];
var maxLineWidth = 0;
var drawnLines = lines.length;
if (style.maxLines > 0 && style.maxLines < lines.length) {
drawnLines = style.maxLines;
}
style.syncFont(canvas, context);
var letterSpacing = text.letterSpacing;
for (var i = 0; i < drawnLines; i++) {
var lineWidth = style.strokeThickness;
if (letterSpacing === 0) {
lineWidth += context.measureText(lines[i]).width;
} else {
var line = lines[i];
for (var j = 0; j < line.length; j++) {
lineWidth += context.measureText(line[j]).width;
}
if (line.length > 1) {
lineWidth += letterSpacing * (line.length - 1);
}
}
if (style.wordWrap) {
lineWidth -= context.measureText(" ").width;
}
lineWidths[i] = Math.ceil(lineWidth);
maxLineWidth = Math.max(maxLineWidth, lineWidths[i]);
}
var lineHeight = size.fontSize + style.strokeThickness;
var height = lineHeight * drawnLines;
var lineSpacing = text.lineSpacing;
if (drawnLines > 1) {
height += lineSpacing * (drawnLines - 1);
}
return {
width: maxLineWidth,
height,
lines: drawnLines,
lineWidths,
lineSpacing,
lineHeight
};
};
module2.exports = GetTextSize;
}
),
/***/
79557: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CanvasPool = __webpack_require__2(27919);
var MeasureText = function(textStyle) {
var canvas = CanvasPool.create(this);
var context = canvas.getContext("2d", { willReadFrequently: true });
textStyle.syncFont(canvas, context);
var metrics = context.measureText(textStyle.testString);
if ("actualBoundingBoxAscent" in metrics) {
var ascent = metrics.actualBoundingBoxAscent;
var descent = metrics.actualBoundingBoxDescent;
CanvasPool.remove(canvas);
return {
ascent,
descent,
fontSize: ascent + descent
};
}
var width = Math.ceil(metrics.width * textStyle.baselineX);
var baseline = width;
var height = 2 * baseline;
baseline = baseline * textStyle.baselineY | 0;
canvas.width = width;
canvas.height = height;
context.fillStyle = "#f00";
context.fillRect(0, 0, width, height);
context.font = textStyle._font;
context.textBaseline = "alphabetic";
context.fillStyle = "#000";
context.fillText(textStyle.testString, 0, baseline);
var output = {
ascent: 0,
descent: 0,
fontSize: 0
};
var imagedata = context.getImageData(0, 0, width, height);
if (!imagedata) {
output.ascent = baseline;
output.descent = baseline + 6;
output.fontSize = output.ascent + output.descent;
CanvasPool.remove(canvas);
return output;
}
var pixels = imagedata.data;
var numPixels = pixels.length;
var line = width * 4;
var i;
var j;
var idx = 0;
var stop = false;
for (i = 0; i < baseline; i++) {
for (j = 0; j < line; j += 4) {
if (pixels[idx + j] !== 255) {
stop = true;
break;
}
}
if (!stop) {
idx += line;
} else {
break;
}
}
output.ascent = baseline - i;
idx = numPixels - line;
stop = false;
for (i = height; i > baseline; i--) {
for (j = 0; j < line; j += 4) {
if (pixels[idx + j] !== 255) {
stop = true;
break;
}
}
if (!stop) {
idx -= line;
} else {
break;
}
}
output.descent = i - baseline;
output.fontSize = output.ascent + output.descent;
CanvasPool.remove(canvas);
return output;
};
module2.exports = MeasureText;
}
),
/***/
50171: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var AddToDOM = __webpack_require__2(40366);
var CanvasPool = __webpack_require__2(27919);
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31401);
var GameObject = __webpack_require__2(95643);
var GetTextSize = __webpack_require__2(14220);
var GetValue = __webpack_require__2(35154);
var RemoveFromDOM = __webpack_require__2(35846);
var TextRender = __webpack_require__2(61771);
var TextStyle = __webpack_require__2(35762);
var UUID = __webpack_require__2(45650);
var Text = new Class({
Extends: GameObject,
Mixins: [
Components.Alpha,
Components.BlendMode,
Components.ComputedSize,
Components.Crop,
Components.Depth,
Components.Flip,
Components.GetBounds,
Components.Mask,
Components.Origin,
Components.Pipeline,
Components.PostPipeline,
Components.ScrollFactor,
Components.Tint,
Components.Transform,
Components.Visible,
TextRender
],
initialize: function Text2(scene, x, y, text, style) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
GameObject.call(this, scene, "Text");
this.renderer = scene.sys.renderer;
this.setPosition(x, y);
this.setOrigin(0, 0);
this.initPipeline();
this.initPostPipeline(true);
this.canvas = CanvasPool.create(this);
this.context;
this.style = new TextStyle(this, style);
this.autoRound = true;
this.splitRegExp = /(?:\r\n|\r|\n)/;
this._text = void 0;
this.padding = { left: 0, right: 0, top: 0, bottom: 0 };
this.width = 1;
this.height = 1;
this.lineSpacing = 0;
this.letterSpacing = 0;
if (this.style.resolution === 0) {
this.style.resolution = 1;
}
this._crop = this.resetCropObject();
this._textureKey = UUID();
this.texture = scene.sys.textures.addCanvas(this._textureKey, this.canvas);
this.context = this.texture.context;
this.frame = this.texture.get();
this.frame.source.resolution = this.style.resolution;
if (this.renderer && this.renderer.gl) {
this.renderer.deleteTexture(this.frame.source.glTexture);
this.frame.source.glTexture = null;
}
this.initRTL();
this.setText(text);
if (style && style.padding) {
this.setPadding(style.padding);
}
if (style && style.lineSpacing) {
this.setLineSpacing(style.lineSpacing);
}
},
/**
* Initialize right to left text.
*
* @method Phaser.GameObjects.Text#initRTL
* @since 3.0.0
*/
initRTL: function() {
if (!this.style.rtl) {
return;
}
this.canvas.dir = "rtl";
this.context.direction = "rtl";
this.canvas.style.display = "none";
AddToDOM(this.canvas, this.scene.sys.canvas);
this.originX = 1;
},
/**
* Greedy wrapping algorithm that will wrap words as the line grows longer than its horizontal
* bounds.
*
* @method Phaser.GameObjects.Text#runWordWrap
* @since 3.0.0
*
* @param {string} text - The text to perform word wrap detection against.
*
* @return {string} The text after wrapping has been applied.
*/
runWordWrap: function(text) {
var style = this.style;
if (style.wordWrapCallback) {
var wrappedLines = style.wordWrapCallback.call(style.wordWrapCallbackScope, text, this);
if (Array.isArray(wrappedLines)) {
wrappedLines = wrappedLines.join("\n");
}
return wrappedLines;
} else if (style.wordWrapWidth) {
if (style.wordWrapUseAdvanced) {
return this.advancedWordWrap(text, this.context, this.style.wordWrapWidth);
} else {
return this.basicWordWrap(text, this.context, this.style.wordWrapWidth);
}
} else {
return text;
}
},
/**
* Advanced wrapping algorithm that will wrap words as the line grows longer than its horizontal
* bounds. Consecutive spaces will be collapsed and replaced with a single space. Lines will be
* trimmed of white space before processing. Throws an error if wordWrapWidth is less than a
* single character.
*
* @method Phaser.GameObjects.Text#advancedWordWrap
* @since 3.0.0
*
* @param {string} text - The text to perform word wrap detection against.
* @param {CanvasRenderingContext2D} context - The Canvas Rendering Context.
* @param {number} wordWrapWidth - The word wrap width.
*
* @return {string} The wrapped text.
*/
advancedWordWrap: function(text, context, wordWrapWidth) {
var output = "";
var lines = text.replace(/ +/gi, " ").split(this.splitRegExp);
var linesCount = lines.length;
for (var i = 0; i < linesCount; i++) {
var line = lines[i];
var out = "";
line = line.replace(/^ *|\s*$/gi, "");
var lineWidth = context.measureText(line).width;
if (lineWidth < wordWrapWidth) {
output += line + "\n";
continue;
}
var currentLineWidth = wordWrapWidth;
var words = line.split(" ");
for (var j = 0; j < words.length; j++) {
var word = words[j];
var wordWithSpace = word + " ";
var wordWidth = context.measureText(wordWithSpace).width;
if (wordWidth > currentLineWidth) {
if (j === 0) {
var newWord = wordWithSpace;
while (newWord.length) {
newWord = newWord.slice(0, -1);
wordWidth = context.measureText(newWord).width;
if (wordWidth <= currentLineWidth) {
break;
}
}
if (!newWord.length) {
throw new Error("wordWrapWidth < a single character");
}
var secondPart = word.substr(newWord.length);
words[j] = secondPart;
out += newWord;
}
var offset = words[j].length ? j : j + 1;
var remainder = words.slice(offset).join(" ").replace(/[ \n]*$/gi, "");
lines.splice(i + 1, 0, remainder);
linesCount = lines.length;
break;
} else {
out += wordWithSpace;
currentLineWidth -= wordWidth;
}
}
output += out.replace(/[ \n]*$/gi, "") + "\n";
}
output = output.replace(/[\s|\n]*$/gi, "");
return output;
},
/**
* Greedy wrapping algorithm that will wrap words as the line grows longer than its horizontal
* bounds. Spaces are not collapsed and whitespace is not trimmed.
*
* @method Phaser.GameObjects.Text#basicWordWrap
* @since 3.0.0
*
* @param {string} text - The text to perform word wrap detection against.
* @param {CanvasRenderingContext2D} context - The Canvas Rendering Context.
* @param {number} wordWrapWidth - The word wrap width.
*
* @return {string} The wrapped text.
*/
basicWordWrap: function(text, context, wordWrapWidth) {
var result = "";
var lines = text.split(this.splitRegExp);
var lastLineIndex = lines.length - 1;
var whiteSpaceWidth = context.measureText(" ").width;
for (var i = 0; i <= lastLineIndex; i++) {
var spaceLeft = wordWrapWidth;
var words = lines[i].split(" ");
var lastWordIndex = words.length - 1;
for (var j = 0; j <= lastWordIndex; j++) {
var word = words[j];
var wordWidth = context.measureText(word).width;
var wordWidthWithSpace = wordWidth;
if (j < lastWordIndex) {
wordWidthWithSpace += whiteSpaceWidth;
}
if (wordWidthWithSpace > spaceLeft) {
if (j > 0) {
result += "\n";
spaceLeft = wordWrapWidth;
}
}
result += word;
if (j < lastWordIndex) {
result += " ";
spaceLeft -= wordWidthWithSpace;
} else {
spaceLeft -= wordWidth;
}
}
if (i < lastLineIndex) {
result += "\n";
}
}
return result;
},
/**
* Runs the given text through this Text objects word wrapping and returns the results as an
* array, where each element of the array corresponds to a wrapped line of text.
*
* @method Phaser.GameObjects.Text#getWrappedText
* @since 3.0.0
*
* @param {string} [text] - The text for which the wrapping will be calculated. If unspecified, the Text objects current text will be used.
*
* @return {string[]} An array of strings with the pieces of wrapped text.
*/
getWrappedText: function(text) {
if (text === void 0) {
text = this._text;
}
this.style.syncFont(this.canvas, this.context);
var wrappedLines = this.runWordWrap(text);
return wrappedLines.split(this.splitRegExp);
},
/**
* Set the text to display.
*
* An array of strings will be joined with `\n` line breaks.
*
* @method Phaser.GameObjects.Text#setText
* @since 3.0.0
*
* @param {(string|string[])} value - The string, or array of strings, to be set as the content of this Text object.
*
* @return {this} This Text object.
*/
setText: function(value) {
if (!value && value !== 0) {
value = "";
}
if (Array.isArray(value)) {
value = value.join("\n");
}
if (value !== this._text) {
this._text = value.toString();
this.updateText();
}
return this;
},
/**
* Appends the given text to the content already being displayed by this Text object.
*
* An array of strings will be joined with `\n` line breaks.
*
* @method Phaser.GameObjects.Text#appendText
* @since 3.60.0
*
* @param {(string|string[])} value - The string, or array of strings, to be appended to the existing content of this Text object.
* @param {boolean} [addCR=true] - Insert a carriage-return before the string value.
*
* @return {this} This Text object.
*/
appendText: function(value, addCR) {
if (addCR === void 0) {
addCR = true;
}
if (!value && value !== 0) {
value = "";
}
if (Array.isArray(value)) {
value = value.join("\n");
}
value = value.toString();
var newText = this._text.concat(addCR ? "\n" + value : value);
if (newText !== this._text) {
this._text = newText;
this.updateText();
}
return this;
},
/**
* Set the text style.
*
* @example
* text.setStyle({
* fontSize: '64px',
* fontFamily: 'Arial',
* color: '#ffffff',
* align: 'center',
* backgroundColor: '#ff00ff'
* });
*
* @method Phaser.GameObjects.Text#setStyle
* @since 3.0.0
*
* @param {object} style - The style settings to set.
*
* @return {this} This Text object.
*/
setStyle: function(style) {
return this.style.setStyle(style);
},
/**
* Set the font.
*
* If a string is given, the font family is set.
*
* If an object is given, the `fontFamily`, `fontSize` and `fontStyle`
* properties of that object are set.
*
* **Important:** The font name must be quoted if it contains certain combinations of digits or
* special characters:
*
* ```javascript
* Text.setFont('"Press Start 2P"');
* ```
*
* Equally, if you wish to provide a list of fallback fonts, then you should ensure they are all
* quoted properly, too:
*
* ```javascript
* Text.setFont('Georgia, "Goudy Bookletter 1911", Times, serif');
* ```
*
* @method Phaser.GameObjects.Text#setFont
* @since 3.0.0
*
* @param {string} font - The font family or font settings to set.
*
* @return {this} This Text object.
*
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/font-family#Valid_family_names
*/
setFont: function(font) {
return this.style.setFont(font);
},
/**
* Set the font family.
*
* **Important:** The font name must be quoted if it contains certain combinations of digits or
* special characters:
*
* ```javascript
* Text.setFont('"Press Start 2P"');
* ```
*
* Equally, if you wish to provide a list of fallback fonts, then you should ensure they are all
* quoted properly, too:
*
* ```javascript
* Text.setFont('Georgia, "Goudy Bookletter 1911", Times, serif');
* ```
*
* @method Phaser.GameObjects.Text#setFontFamily
* @since 3.0.0
*
* @param {string} family - The font family.
*
* @return {this} This Text object.
*
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/font-family#Valid_family_names
*/
setFontFamily: function(family) {
return this.style.setFontFamily(family);
},
/**
* Set the font size. Can be a string with a valid CSS unit, i.e. `16px`, or a number.
*
* @method Phaser.GameObjects.Text#setFontSize
* @since 3.0.0
*
* @param {(string|number)} size - The font size.
*
* @return {this} This Text object.
*/
setFontSize: function(size) {
return this.style.setFontSize(size);
},
/**
* Set the font style.
*
* @method Phaser.GameObjects.Text#setFontStyle
* @since 3.0.0
*
* @param {string} style - The font style.
*
* @return {this} This Text object.
*/
setFontStyle: function(style) {
return this.style.setFontStyle(style);
},
/**
* Set a fixed width and height for the text.
*
* Pass in `0` for either of these parameters to disable fixed width or height respectively.
*
* @method Phaser.GameObjects.Text#setFixedSize
* @since 3.0.0
*
* @param {number} width - The fixed width to set. `0` disables fixed width.
* @param {number} height - The fixed height to set. `0` disables fixed height.
*
* @return {this} This Text object.
*/
setFixedSize: function(width, height) {
return this.style.setFixedSize(width, height);
},
/**
* Set the background color.
*
* @method Phaser.GameObjects.Text#setBackgroundColor
* @since 3.0.0
*
* @param {string} color - The background color.
*
* @return {this} This Text object.
*/
setBackgroundColor: function(color) {
return this.style.setBackgroundColor(color);
},
/**
* Set the fill style to be used by the Text object.
*
* This can be any valid CanvasRenderingContext2D fillStyle value, such as
* a color (in hex, rgb, rgba, hsl or named values), a gradient or a pattern.
*
* See the [MDN fillStyle docs](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle) for more details.
*
* @method Phaser.GameObjects.Text#setFill
* @since 3.0.0
*
* @param {(string|CanvasGradient|CanvasPattern)} color - The text fill style. Can be any valid CanvasRenderingContext `fillStyle` value.
*
* @return {this} This Text object.
*/
setFill: function(fillStyle) {
return this.style.setFill(fillStyle);
},
/**
* Set the text fill color.
*
* @method Phaser.GameObjects.Text#setColor
* @since 3.0.0
*
* @param {(string|CanvasGradient|CanvasPattern)} color - The text fill color.
*
* @return {this} This Text object.
*/
setColor: function(color) {
return this.style.setColor(color);
},
/**
* Set the stroke settings.
*
* @method Phaser.GameObjects.Text#setStroke
* @since 3.0.0
*
* @param {(string|CanvasGradient|CanvasPattern)} color - The stroke color.
* @param {number} thickness - The stroke thickness.
*
* @return {this} This Text object.
*/
setStroke: function(color, thickness) {
return this.style.setStroke(color, thickness);
},
/**
* Set the shadow settings.
*
* @method Phaser.GameObjects.Text#setShadow
* @since 3.0.0
*
* @param {number} [x=0] - The horizontal shadow offset.
* @param {number} [y=0] - The vertical shadow offset.
* @param {string} [color='#000'] - The shadow color.
* @param {number} [blur=0] - The shadow blur radius.
* @param {boolean} [shadowStroke=false] - Whether to stroke the shadow.
* @param {boolean} [shadowFill=true] - Whether to fill the shadow.
*
* @return {this} This Text object.
*/
setShadow: function(x, y, color, blur, shadowStroke, shadowFill) {
return this.style.setShadow(x, y, color, blur, shadowStroke, shadowFill);
},
/**
* Set the shadow offset.
*
* @method Phaser.GameObjects.Text#setShadowOffset
* @since 3.0.0
*
* @param {number} x - The horizontal shadow offset.
* @param {number} y - The vertical shadow offset.
*
* @return {this} This Text object.
*/
setShadowOffset: function(x, y) {
return this.style.setShadowOffset(x, y);
},
/**
* Set the shadow color.
*
* @method Phaser.GameObjects.Text#setShadowColor
* @since 3.0.0
*
* @param {string} color - The shadow color.
*
* @return {this} This Text object.
*/
setShadowColor: function(color) {
return this.style.setShadowColor(color);
},
/**
* Set the shadow blur radius.
*
* @method Phaser.GameObjects.Text#setShadowBlur
* @since 3.0.0
*
* @param {number} blur - The shadow blur radius.
*
* @return {this} This Text object.
*/
setShadowBlur: function(blur) {
return this.style.setShadowBlur(blur);
},
/**
* Enable or disable shadow stroke.
*
* @method Phaser.GameObjects.Text#setShadowStroke
* @since 3.0.0
*
* @param {boolean} enabled - Whether shadow stroke is enabled or not.
*
* @return {this} This Text object.
*/
setShadowStroke: function(enabled) {
return this.style.setShadowStroke(enabled);
},
/**
* Enable or disable shadow fill.
*
* @method Phaser.GameObjects.Text#setShadowFill
* @since 3.0.0
*
* @param {boolean} enabled - Whether shadow fill is enabled or not.
*
* @return {this} This Text object.
*/
setShadowFill: function(enabled) {
return this.style.setShadowFill(enabled);
},
/**
* Set the width (in pixels) to use for wrapping lines. Pass in null to remove wrapping by width.
*
* @method Phaser.GameObjects.Text#setWordWrapWidth
* @since 3.0.0
*
* @param {number | null} width - The maximum width of a line in pixels. Set to null to remove wrapping.
* @param {boolean} [useAdvancedWrap=false] - Whether or not to use the advanced wrapping
* algorithm. If true, spaces are collapsed and whitespace is trimmed from lines. If false,
* spaces and whitespace are left as is.
*
* @return {this} This Text object.
*/
setWordWrapWidth: function(width, useAdvancedWrap) {
return this.style.setWordWrapWidth(width, useAdvancedWrap);
},
/**
* Set a custom callback for wrapping lines. Pass in null to remove wrapping by callback.
*
* @method Phaser.GameObjects.Text#setWordWrapCallback
* @since 3.0.0
*
* @param {TextStyleWordWrapCallback} callback - A custom function that will be responsible for wrapping the
* text. It will receive two arguments: text (the string to wrap), textObject (this Text
* instance). It should return the wrapped lines either as an array of lines or as a string with
* newline characters in place to indicate where breaks should happen.
* @param {object} [scope=null] - The scope that will be applied when the callback is invoked.
*
* @return {this} This Text object.
*/
setWordWrapCallback: function(callback, scope) {
return this.style.setWordWrapCallback(callback, scope);
},
/**
* Set the alignment of the text in this Text object.
*
* The argument can be one of: `left`, `right`, `center` or `justify`.
*
* Alignment only works if the Text object has more than one line of text.
*
* @method Phaser.GameObjects.Text#setAlign
* @since 3.0.0
*
* @param {string} [align='left'] - The text alignment for multi-line text.
*
* @return {this} This Text object.
*/
setAlign: function(align) {
return this.style.setAlign(align);
},
/**
* Set the resolution used by this Text object.
*
* It allows for much clearer text on High DPI devices, at the cost of memory because it uses larger
* internal Canvas textures for the Text.
*
* Therefore, please use with caution, as the more high res Text you have, the more memory it uses.
*
* @method Phaser.GameObjects.Text#setResolution
* @since 3.12.0
*
* @param {number} value - The resolution for this Text object to use.
*
* @return {this} This Text object.
*/
setResolution: function(value) {
return this.style.setResolution(value);
},
/**
* Sets the line spacing value.
*
* This value is _added_ to the height of the font when calculating the overall line height.
* This only has an effect if this Text object consists of multiple lines of text.
*
* @method Phaser.GameObjects.Text#setLineSpacing
* @since 3.13.0
*
* @param {number} value - The amount to add to the font height to achieve the overall line height.
*
* @return {this} This Text object.
*/
setLineSpacing: function(value) {
this.lineSpacing = value;
return this.updateText();
},
/**
* Sets the letter spacing value.
*
* This will add, or remove spacing between each character of this Text Game Object. The value can be
* either positive or negative. Positive values increase the space between each character, whilst negative
* values decrease it. Note that some fonts are spaced naturally closer together than others.
*
* Please understand that enabling this feature will cause Phaser to render each character in this Text object
* one by one, rather than use a draw for the whole string. This makes it extremely expensive when used with
* either long strings, or lots of strings in total. You will be better off creating bitmap font text if you
* need to display large quantities of characters with fine control over the letter spacing.
*
* @method Phaser.GameObjects.Text#setLetterSpacing
* @since 3.70.0
*
* @param {number} value - The amount to add to the letter width. Set to zero to disable.
*
* @return {this} This Text object.
*/
setLetterSpacing: function(value) {
this.letterSpacing = value;
return this.updateText();
},
/**
* Set the text padding.
*
* 'left' can be an object.
*
* If only 'left' and 'top' are given they are treated as 'x' and 'y'.
*
* @method Phaser.GameObjects.Text#setPadding
* @since 3.0.0
*
* @param {(number|Phaser.Types.GameObjects.Text.TextPadding)} left - The left padding value, or a padding config object.
* @param {number} [top] - The top padding value.
* @param {number} [right] - The right padding value.
* @param {number} [bottom] - The bottom padding value.
*
* @return {this} This Text object.
*/
setPadding: function(left, top, right, bottom) {
if (typeof left === "object") {
var config = left;
var x = GetValue(config, "x", null);
if (x !== null) {
left = x;
right = x;
} else {
left = GetValue(config, "left", 0);
right = GetValue(config, "right", left);
}
var y = GetValue(config, "y", null);
if (y !== null) {
top = y;
bottom = y;
} else {
top = GetValue(config, "top", 0);
bottom = GetValue(config, "bottom", top);
}
} else {
if (left === void 0) {
left = 0;
}
if (top === void 0) {
top = left;
}
if (right === void 0) {
right = left;
}
if (bottom === void 0) {
bottom = top;
}
}
this.padding.left = left;
this.padding.top = top;
this.padding.right = right;
this.padding.bottom = bottom;
return this.updateText();
},
/**
* Set the maximum number of lines to draw.
*
* @method Phaser.GameObjects.Text#setMaxLines
* @since 3.0.0
*
* @param {number} [max=0] - The maximum number of lines to draw.
*
* @return {this} This Text object.
*/
setMaxLines: function(max) {
return this.style.setMaxLines(max);
},
/**
* Render text from right-to-left or left-to-right.
*
* @method Phaser.GameObjects.Text#setRTL
* @since 3.70.0
*
* @param {boolean} [rtl=true] - Set to `true` to render from right-to-left.
*
* @return {this} This Text object.
*/
setRTL: function(rtl) {
if (rtl === void 0) {
rtl = true;
}
var style = this.style;
if (style.rtl === rtl) {
return this;
}
style.rtl = rtl;
if (rtl) {
this.canvas.dir = "rtl";
this.context.direction = "rtl";
this.canvas.style.display = "none";
AddToDOM(this.canvas, this.scene.sys.canvas);
} else {
this.canvas.dir = "ltr";
this.context.direction = "ltr";
}
if (style.align === "left") {
style.align = "right";
} else if (style.align === "right") {
style.align = "left";
}
return this;
},
/**
* Update the displayed text.
*
* @method Phaser.GameObjects.Text#updateText
* @since 3.0.0
*
* @return {this} This Text object.
*/
updateText: function() {
var canvas = this.canvas;
var context = this.context;
var style = this.style;
var resolution = style.resolution;
var size = style.metrics;
style.syncFont(canvas, context);
var outputText = this._text;
if (style.wordWrapWidth || style.wordWrapCallback) {
outputText = this.runWordWrap(this._text);
}
var lines = outputText.split(this.splitRegExp);
var textSize = GetTextSize(this, size, lines);
var padding = this.padding;
var textWidth;
if (style.fixedWidth === 0) {
this.width = textSize.width + padding.left + padding.right;
textWidth = textSize.width;
} else {
this.width = style.fixedWidth;
textWidth = this.width - padding.left - padding.right;
if (textWidth < textSize.width) {
textWidth = textSize.width;
}
}
if (style.fixedHeight === 0) {
this.height = textSize.height + padding.top + padding.bottom;
} else {
this.height = style.fixedHeight;
}
var w = this.width;
var h = this.height;
this.updateDisplayOrigin();
w *= resolution;
h *= resolution;
w = Math.max(w, 1);
h = Math.max(h, 1);
if (canvas.width !== w || canvas.height !== h) {
canvas.width = w;
canvas.height = h;
this.frame.setSize(w, h);
style.syncFont(canvas, context);
if (style.rtl) {
context.direction = "rtl";
}
} else {
context.clearRect(0, 0, w, h);
}
context.save();
context.scale(resolution, resolution);
if (style.backgroundColor) {
context.fillStyle = style.backgroundColor;
context.fillRect(0, 0, w, h);
}
style.syncStyle(canvas, context);
context.translate(padding.left, padding.top);
var linePositionX;
var linePositionY;
for (var i = 0; i < textSize.lines; i++) {
linePositionX = style.strokeThickness / 2;
linePositionY = style.strokeThickness / 2 + i * textSize.lineHeight + size.ascent;
if (i > 0) {
linePositionY += textSize.lineSpacing * i;
}
if (style.rtl) {
linePositionX = w - linePositionX - padding.left - padding.right;
} else if (style.align === "right") {
linePositionX += textWidth - textSize.lineWidths[i];
} else if (style.align === "center") {
linePositionX += (textWidth - textSize.lineWidths[i]) / 2;
} else if (style.align === "justify") {
var minimumLengthToApplyJustification = 0.85;
if (textSize.lineWidths[i] / textSize.width >= minimumLengthToApplyJustification) {
var extraSpace = textSize.width - textSize.lineWidths[i];
var spaceSize = context.measureText(" ").width;
var trimmedLine = lines[i].trim();
var array = trimmedLine.split(" ");
extraSpace += (lines[i].length - trimmedLine.length) * spaceSize;
var extraSpaceCharacters = Math.floor(extraSpace / spaceSize);
var idx = 0;
while (extraSpaceCharacters > 0) {
array[idx] += " ";
idx = (idx + 1) % (array.length - 1 || 1);
--extraSpaceCharacters;
}
lines[i] = array.join(" ");
}
}
if (this.autoRound) {
linePositionX = Math.round(linePositionX);
linePositionY = Math.round(linePositionY);
}
var letterSpacing = this.letterSpacing;
if (style.strokeThickness && letterSpacing === 0) {
style.syncShadow(context, style.shadowStroke);
context.strokeText(lines[i], linePositionX, linePositionY);
}
if (style.color) {
style.syncShadow(context, style.shadowFill);
if (letterSpacing !== 0) {
var charPositionX = 0;
var line = lines[i].split("");
for (var l = 0; l < line.length; l++) {
if (style.strokeThickness) {
style.syncShadow(context, style.shadowStroke);
context.strokeText(line[l], linePositionX + charPositionX, linePositionY);
style.syncShadow(context, style.shadowFill);
}
context.fillText(line[l], linePositionX + charPositionX, linePositionY);
charPositionX += context.measureText(line[l]).width + letterSpacing;
}
} else {
context.fillText(lines[i], linePositionX, linePositionY);
}
}
}
context.restore();
if (this.renderer && this.renderer.gl) {
this.frame.source.glTexture = this.renderer.canvasToTexture(canvas, this.frame.source.glTexture, true);
if (false) {
}
}
var input = this.input;
if (input && !input.customHitArea) {
input.hitArea.width = this.width;
input.hitArea.height = this.height;
}
return this;
},
/**
* Get the current text metrics.
*
* @method Phaser.GameObjects.Text#getTextMetrics
* @since 3.0.0
*
* @return {Phaser.Types.GameObjects.Text.TextMetrics} The text metrics.
*/
getTextMetrics: function() {
return this.style.getTextMetrics();
},
/**
* The text string being rendered by this Text Game Object.
*
* @name Phaser.GameObjects.Text#text
* @type {string}
* @since 3.0.0
*/
text: {
get: function() {
return this._text;
},
set: function(value) {
this.setText(value);
}
},
/**
* Build a JSON representation of the Text object.
*
* @method Phaser.GameObjects.Text#toJSON
* @since 3.0.0
*
* @return {Phaser.Types.GameObjects.JSONGameObject} A JSON representation of the Text object.
*/
toJSON: function() {
var out = Components.ToJSON(this);
var data = {
autoRound: this.autoRound,
text: this._text,
style: this.style.toJSON(),
padding: {
left: this.padding.left,
right: this.padding.right,
top: this.padding.top,
bottom: this.padding.bottom
}
};
out.data = data;
return out;
},
/**
* Internal destroy handler, called as part of the destroy process.
*
* @method Phaser.GameObjects.Text#preDestroy
* @protected
* @since 3.0.0
*/
preDestroy: function() {
RemoveFromDOM(this.canvas);
CanvasPool.remove(this.canvas);
var texture = this.texture;
if (texture) {
texture.destroy();
}
}
/**
* The horizontal origin of this Game Object.
* The origin maps the relationship between the size and position of the Game Object.
* The default value is 0.5, meaning all Game Objects are positioned based on their center.
* Setting the value to 0 means the position now relates to the left of the Game Object.
*
* @name Phaser.GameObjects.Text#originX
* @type {number}
* @default 0
* @since 3.0.0
*/
/**
* The vertical origin of this Game Object.
* The origin maps the relationship between the size and position of the Game Object.
* The default value is 0.5, meaning all Game Objects are positioned based on their center.
* Setting the value to 0 means the position now relates to the top of the Game Object.
*
* @name Phaser.GameObjects.Text#originY
* @type {number}
* @default 0
* @since 3.0.0
*/
});
module2.exports = Text;
}
),
/***/
79724: (
/***/
(module2) => {
var TextCanvasRenderer = function(renderer, src, camera, parentMatrix) {
if (src.width === 0 || src.height === 0) {
return;
}
camera.addToRenderList(src);
renderer.batchSprite(src, src.frame, camera, parentMatrix);
};
module2.exports = TextCanvasRenderer;
}
),
/***/
71259: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var BuildGameObject = __webpack_require__2(25305);
var GameObjectCreator = __webpack_require__2(44603);
var GetAdvancedValue = __webpack_require__2(23568);
var Text = __webpack_require__2(50171);
GameObjectCreator.register("text", function(config, addToScene) {
if (config === void 0) {
config = {};
}
var content = GetAdvancedValue(config, "text", "");
var style = GetAdvancedValue(config, "style", null);
var padding = GetAdvancedValue(config, "padding", null);
if (padding !== null) {
style.padding = padding;
}
var text = new Text(this.scene, 0, 0, content, style);
if (addToScene !== void 0) {
config.add = addToScene;
}
BuildGameObject(this.scene, text, config);
text.autoRound = GetAdvancedValue(config, "autoRound", true);
text.resolution = GetAdvancedValue(config, "resolution", 1);
return text;
});
}
),
/***/
68005: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var Text = __webpack_require__2(50171);
var GameObjectFactory = __webpack_require__2(39429);
GameObjectFactory.register("text", function(x, y, text, style) {
return this.displayList.add(new Text(this.scene, x, y, text, style));
});
}
),
/***/
61771: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(34397);
}
if (true) {
renderCanvas = __webpack_require__2(79724);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
35762: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var GetAdvancedValue = __webpack_require__2(23568);
var GetValue = __webpack_require__2(35154);
var MeasureText = __webpack_require__2(79557);
var propertyMap = {
fontFamily: ["fontFamily", "Courier"],
fontSize: ["fontSize", "16px"],
fontStyle: ["fontStyle", ""],
backgroundColor: ["backgroundColor", null],
color: ["color", "#fff"],
stroke: ["stroke", "#fff"],
strokeThickness: ["strokeThickness", 0],
shadowOffsetX: ["shadow.offsetX", 0],
shadowOffsetY: ["shadow.offsetY", 0],
shadowColor: ["shadow.color", "#000"],
shadowBlur: ["shadow.blur", 0],
shadowStroke: ["shadow.stroke", false],
shadowFill: ["shadow.fill", false],
align: ["align", "left"],
maxLines: ["maxLines", 0],
fixedWidth: ["fixedWidth", 0],
fixedHeight: ["fixedHeight", 0],
resolution: ["resolution", 0],
rtl: ["rtl", false],
testString: ["testString", "|MÉqgy"],
baselineX: ["baselineX", 1.2],
baselineY: ["baselineY", 1.4],
wordWrapWidth: ["wordWrap.width", null],
wordWrapCallback: ["wordWrap.callback", null],
wordWrapCallbackScope: ["wordWrap.callbackScope", null],
wordWrapUseAdvanced: ["wordWrap.useAdvancedWrap", false]
};
var TextStyle = new Class({
initialize: function TextStyle2(text, style) {
this.parent = text;
this.fontFamily;
this.fontSize;
this.fontStyle;
this.backgroundColor;
this.color;
this.stroke;
this.strokeThickness;
this.shadowOffsetX;
this.shadowOffsetY;
this.shadowColor;
this.shadowBlur;
this.shadowStroke;
this.shadowFill;
this.align;
this.maxLines;
this.fixedWidth;
this.fixedHeight;
this.resolution;
this.rtl;
this.testString;
this.baselineX;
this.baselineY;
this.wordWrapWidth;
this.wordWrapCallback;
this.wordWrapCallbackScope;
this.wordWrapUseAdvanced;
this._font;
this.setStyle(style, false, true);
},
/**
* Set the text style.
*
* @example
* text.setStyle({
* fontSize: '64px',
* fontFamily: 'Arial',
* color: '#ffffff',
* align: 'center',
* backgroundColor: '#ff00ff'
* });
*
* @method Phaser.GameObjects.TextStyle#setStyle
* @since 3.0.0
*
* @param {Phaser.Types.GameObjects.Text.TextStyle} style - The style settings to set.
* @param {boolean} [updateText=true] - Whether to update the text immediately.
* @param {boolean} [setDefaults=false] - Use the default values if not set, or the local values.
*
* @return {Phaser.GameObjects.Text} The parent Text object.
*/
setStyle: function(style, updateText, setDefaults) {
if (updateText === void 0) {
updateText = true;
}
if (setDefaults === void 0) {
setDefaults = false;
}
for (var key in propertyMap) {
var value = setDefaults ? propertyMap[key][1] : this[key];
if (key === "wordWrapCallback" || key === "wordWrapCallbackScope") {
this[key] = GetValue(style, propertyMap[key][0], value);
} else if (style && key === "fontSize" && typeof style.fontSize === "number") {
this[key] = style.fontSize.toString() + "px";
} else {
this[key] = GetAdvancedValue(style, propertyMap[key][0], value);
}
}
var font = GetValue(style, "font", null);
if (font !== null) {
this.setFont(font, false);
}
this._font = [this.fontStyle, this.fontSize, this.fontFamily].join(" ").trim();
var fill = GetValue(style, "fill", null);
if (fill !== null) {
this.color = fill;
}
var metrics = GetValue(style, "metrics", false);
if (metrics) {
this.metrics = {
ascent: GetValue(metrics, "ascent", 0),
descent: GetValue(metrics, "descent", 0),
fontSize: GetValue(metrics, "fontSize", 0)
};
} else if (updateText || !this.metrics) {
this.metrics = MeasureText(this);
}
if (updateText) {
return this.parent.updateText();
} else {
return this.parent;
}
},
/**
* Synchronize the font settings to the given Canvas Rendering Context.
*
* @method Phaser.GameObjects.TextStyle#syncFont
* @since 3.0.0
*
* @param {HTMLCanvasElement} canvas - The Canvas Element.
* @param {CanvasRenderingContext2D} context - The Canvas Rendering Context.
*/
syncFont: function(canvas, context) {
context.font = this._font;
},
/**
* Synchronize the text style settings to the given Canvas Rendering Context.
*
* @method Phaser.GameObjects.TextStyle#syncStyle
* @since 3.0.0
*
* @param {HTMLCanvasElement} canvas - The Canvas Element.
* @param {CanvasRenderingContext2D} context - The Canvas Rendering Context.
*/
syncStyle: function(canvas, context) {
context.textBaseline = "alphabetic";
context.fillStyle = this.color;
context.strokeStyle = this.stroke;
context.lineWidth = this.strokeThickness;
context.lineCap = "round";
context.lineJoin = "round";
},
/**
* Synchronize the shadow settings to the given Canvas Rendering Context.
*
* @method Phaser.GameObjects.TextStyle#syncShadow
* @since 3.0.0
*
* @param {CanvasRenderingContext2D} context - The Canvas Rendering Context.
* @param {boolean} enabled - Whether shadows are enabled or not.
*/
syncShadow: function(context, enabled) {
if (enabled) {
context.shadowOffsetX = this.shadowOffsetX;
context.shadowOffsetY = this.shadowOffsetY;
context.shadowColor = this.shadowColor;
context.shadowBlur = this.shadowBlur;
} else {
context.shadowOffsetX = 0;
context.shadowOffsetY = 0;
context.shadowColor = 0;
context.shadowBlur = 0;
}
},
/**
* Update the style settings for the parent Text object.
*
* @method Phaser.GameObjects.TextStyle#update
* @since 3.0.0
*
* @param {boolean} recalculateMetrics - Whether to recalculate font and text metrics.
*
* @return {Phaser.GameObjects.Text} The parent Text object.
*/
update: function(recalculateMetrics) {
if (recalculateMetrics) {
this._font = [this.fontStyle, this.fontSize, this.fontFamily].join(" ").trim();
this.metrics = MeasureText(this);
}
return this.parent.updateText();
},
/**
* Set the font.
*
* If a string is given, the font family is set.
*
* If an object is given, the `fontFamily`, `fontSize` and `fontStyle`
* properties of that object are set.
*
* @method Phaser.GameObjects.TextStyle#setFont
* @since 3.0.0
*
* @param {(string|object)} font - The font family or font settings to set.
* @param {boolean} [updateText=true] - Whether to update the text immediately.
*
* @return {Phaser.GameObjects.Text} The parent Text object.
*/
setFont: function(font, updateText) {
if (updateText === void 0) {
updateText = true;
}
var fontFamily = font;
var fontSize = "";
var fontStyle = "";
if (typeof font !== "string") {
fontFamily = GetValue(font, "fontFamily", "Courier");
fontSize = GetValue(font, "fontSize", "16px");
fontStyle = GetValue(font, "fontStyle", "");
} else {
var fontSplit = font.split(" ");
var i = 0;
fontStyle = fontSplit.length > 2 ? fontSplit[i++] : "";
fontSize = fontSplit[i++] || "16px";
fontFamily = fontSplit[i++] || "Courier";
}
if (fontFamily !== this.fontFamily || fontSize !== this.fontSize || fontStyle !== this.fontStyle) {
this.fontFamily = fontFamily;
this.fontSize = fontSize;
this.fontStyle = fontStyle;
if (updateText) {
this.update(true);
}
}
return this.parent;
},
/**
* Set the font family.
*
* @method Phaser.GameObjects.TextStyle#setFontFamily
* @since 3.0.0
*
* @param {string} family - The font family.
*
* @return {Phaser.GameObjects.Text} The parent Text object.
*/
setFontFamily: function(family) {
if (this.fontFamily !== family) {
this.fontFamily = family;
this.update(true);
}
return this.parent;
},
/**
* Set the font style.
*
* @method Phaser.GameObjects.TextStyle#setFontStyle
* @since 3.0.0
*
* @param {string} style - The font style.
*
* @return {Phaser.GameObjects.Text} The parent Text object.
*/
setFontStyle: function(style) {
if (this.fontStyle !== style) {
this.fontStyle = style;
this.update(true);
}
return this.parent;
},
/**
* Set the font size. Can be a string with a valid CSS unit, i.e. `16px`, or a number.
*
* @method Phaser.GameObjects.TextStyle#setFontSize
* @since 3.0.0
*
* @param {(number|string)} size - The font size.
*
* @return {Phaser.GameObjects.Text} The parent Text object.
*/
setFontSize: function(size) {
if (typeof size === "number") {
size = size.toString() + "px";
}
if (this.fontSize !== size) {
this.fontSize = size;
this.update(true);
}
return this.parent;
},
/**
* Set the test string to use when measuring the font.
*
* @method Phaser.GameObjects.TextStyle#setTestString
* @since 3.0.0
*
* @param {string} string - The test string to use when measuring the font.
*
* @return {Phaser.GameObjects.Text} The parent Text object.
*/
setTestString: function(string) {
this.testString = string;
return this.update(true);
},
/**
* Set a fixed width and height for the text.
*
* Pass in `0` for either of these parameters to disable fixed width or height respectively.
*
* @method Phaser.GameObjects.TextStyle#setFixedSize
* @since 3.0.0
*
* @param {number} width - The fixed width to set.
* @param {number} height - The fixed height to set.
*
* @return {Phaser.GameObjects.Text} The parent Text object.
*/
setFixedSize: function(width, height) {
this.fixedWidth = width;
this.fixedHeight = height;
if (width) {
this.parent.width = width;
}
if (height) {
this.parent.height = height;
}
return this.update(false);
},
/**
* Set the background color.
*
* @method Phaser.GameObjects.TextStyle#setBackgroundColor
* @since 3.0.0
*
* @param {string} color - The background color.
*
* @return {Phaser.GameObjects.Text} The parent Text object.
*/
setBackgroundColor: function(color) {
this.backgroundColor = color;
return this.update(false);
},
/**
* Set the text fill color.
*
* @method Phaser.GameObjects.TextStyle#setFill
* @since 3.0.0
*
* @param {(string|CanvasGradient|CanvasPattern)} color - The text fill color.
*
* @return {Phaser.GameObjects.Text} The parent Text object.
*/
setFill: function(color) {
this.color = color;
return this.update(false);
},
/**
* Set the text fill color.
*
* @method Phaser.GameObjects.TextStyle#setColor
* @since 3.0.0
*
* @param {(string|CanvasGradient|CanvasPattern)} color - The text fill color.
*
* @return {Phaser.GameObjects.Text} The parent Text object.
*/
setColor: function(color) {
this.color = color;
return this.update(false);
},
/**
* Set the resolution used by the Text object.
*
* It allows for much clearer text on High DPI devices, at the cost of memory because
* it uses larger internal Canvas textures for the Text.
*
* Please use with caution, as the more high res Text you have, the more memory it uses up.
*
* @method Phaser.GameObjects.TextStyle#setResolution
* @since 3.12.0
*
* @param {number} value - The resolution for this Text object to use.
*
* @return {Phaser.GameObjects.Text} The parent Text object.
*/
setResolution: function(value) {
this.resolution = value;
return this.update(false);
},
/**
* Set the stroke settings.
*
* @method Phaser.GameObjects.TextStyle#setStroke
* @since 3.0.0
*
* @param {(string|CanvasGradient|CanvasPattern)} color - The stroke color.
* @param {number} thickness - The stroke thickness.
*
* @return {Phaser.GameObjects.Text} The parent Text object.
*/
setStroke: function(color, thickness) {
if (thickness === void 0) {
thickness = this.strokeThickness;
}
if (color === void 0 && this.strokeThickness !== 0) {
this.strokeThickness = 0;
this.update(true);
} else if (this.stroke !== color || this.strokeThickness !== thickness) {
this.stroke = color;
this.strokeThickness = thickness;
this.update(true);
}
return this.parent;
},
/**
* Set the shadow settings.
*
* Calling this method always re-measures the parent Text object,
* so only call it when you actually change the shadow settings.
*
* @method Phaser.GameObjects.TextStyle#setShadow
* @since 3.0.0
*
* @param {number} [x=0] - The horizontal shadow offset.
* @param {number} [y=0] - The vertical shadow offset.
* @param {string} [color='#000'] - The shadow color.
* @param {number} [blur=0] - The shadow blur radius.
* @param {boolean} [shadowStroke=false] - Whether to stroke the shadow.
* @param {boolean} [shadowFill=true] - Whether to fill the shadow.
*
* @return {Phaser.GameObjects.Text} The parent Text object.
*/
setShadow: function(x, y, color, blur, shadowStroke, shadowFill) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (color === void 0) {
color = "#000";
}
if (blur === void 0) {
blur = 0;
}
if (shadowStroke === void 0) {
shadowStroke = false;
}
if (shadowFill === void 0) {
shadowFill = true;
}
this.shadowOffsetX = x;
this.shadowOffsetY = y;
this.shadowColor = color;
this.shadowBlur = blur;
this.shadowStroke = shadowStroke;
this.shadowFill = shadowFill;
return this.update(false);
},
/**
* Set the shadow offset.
*
* @method Phaser.GameObjects.TextStyle#setShadowOffset
* @since 3.0.0
*
* @param {number} [x=0] - The horizontal shadow offset.
* @param {number} [y=0] - The vertical shadow offset.
*
* @return {Phaser.GameObjects.Text} The parent Text object.
*/
setShadowOffset: function(x, y) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = x;
}
this.shadowOffsetX = x;
this.shadowOffsetY = y;
return this.update(false);
},
/**
* Set the shadow color.
*
* @method Phaser.GameObjects.TextStyle#setShadowColor
* @since 3.0.0
*
* @param {string} [color='#000'] - The shadow color.
*
* @return {Phaser.GameObjects.Text} The parent Text object.
*/
setShadowColor: function(color) {
if (color === void 0) {
color = "#000";
}
this.shadowColor = color;
return this.update(false);
},
/**
* Set the shadow blur radius.
*
* @method Phaser.GameObjects.TextStyle#setShadowBlur
* @since 3.0.0
*
* @param {number} [blur=0] - The shadow blur radius.
*
* @return {Phaser.GameObjects.Text} The parent Text object.
*/
setShadowBlur: function(blur) {
if (blur === void 0) {
blur = 0;
}
this.shadowBlur = blur;
return this.update(false);
},
/**
* Enable or disable shadow stroke.
*
* @method Phaser.GameObjects.TextStyle#setShadowStroke
* @since 3.0.0
*
* @param {boolean} enabled - Whether shadow stroke is enabled or not.
*
* @return {Phaser.GameObjects.Text} The parent Text object.
*/
setShadowStroke: function(enabled) {
this.shadowStroke = enabled;
return this.update(false);
},
/**
* Enable or disable shadow fill.
*
* @method Phaser.GameObjects.TextStyle#setShadowFill
* @since 3.0.0
*
* @param {boolean} enabled - Whether shadow fill is enabled or not.
*
* @return {Phaser.GameObjects.Text} The parent Text object.
*/
setShadowFill: function(enabled) {
this.shadowFill = enabled;
return this.update(false);
},
/**
* Set the width (in pixels) to use for wrapping lines.
*
* Pass in null to remove wrapping by width.
*
* @method Phaser.GameObjects.TextStyle#setWordWrapWidth
* @since 3.0.0
*
* @param {number | null} width - The maximum width of a line in pixels. Set to null to remove wrapping.
* @param {boolean} [useAdvancedWrap=false] - Whether or not to use the advanced wrapping
* algorithm. If true, spaces are collapsed and whitespace is trimmed from lines. If false,
* spaces and whitespace are left as is.
*
* @return {Phaser.GameObjects.Text} The parent Text object.
*/
setWordWrapWidth: function(width, useAdvancedWrap) {
if (useAdvancedWrap === void 0) {
useAdvancedWrap = false;
}
this.wordWrapWidth = width;
this.wordWrapUseAdvanced = useAdvancedWrap;
return this.update(false);
},
/**
* Set a custom callback for wrapping lines.
*
* Pass in null to remove wrapping by callback.
*
* @method Phaser.GameObjects.TextStyle#setWordWrapCallback
* @since 3.0.0
*
* @param {TextStyleWordWrapCallback} callback - A custom function that will be responsible for wrapping the
* text. It will receive two arguments: text (the string to wrap), textObject (this Text
* instance). It should return the wrapped lines either as an array of lines or as a string with
* newline characters in place to indicate where breaks should happen.
* @param {object} [scope=null] - The scope that will be applied when the callback is invoked.
*
* @return {Phaser.GameObjects.Text} The parent Text object.
*/
setWordWrapCallback: function(callback, scope) {
if (scope === void 0) {
scope = null;
}
this.wordWrapCallback = callback;
this.wordWrapCallbackScope = scope;
return this.update(false);
},
/**
* Set the alignment of the text in this Text object.
*
* The argument can be one of: `left`, `right`, `center` or `justify`.
*
* Alignment only works if the Text object has more than one line of text.
*
* @method Phaser.GameObjects.TextStyle#setAlign
* @since 3.0.0
*
* @param {string} [align='left'] - The text alignment for multi-line text.
*
* @return {Phaser.GameObjects.Text} The parent Text object.
*/
setAlign: function(align) {
if (align === void 0) {
align = "left";
}
this.align = align;
return this.update(false);
},
/**
* Set the maximum number of lines to draw.
*
* @method Phaser.GameObjects.TextStyle#setMaxLines
* @since 3.0.0
*
* @param {number} [max=0] - The maximum number of lines to draw.
*
* @return {Phaser.GameObjects.Text} The parent Text object.
*/
setMaxLines: function(max) {
if (max === void 0) {
max = 0;
}
this.maxLines = max;
return this.update(false);
},
/**
* Get the current text metrics.
*
* @method Phaser.GameObjects.TextStyle#getTextMetrics
* @since 3.0.0
*
* @return {Phaser.Types.GameObjects.Text.TextMetrics} The text metrics.
*/
getTextMetrics: function() {
var metrics = this.metrics;
return {
ascent: metrics.ascent,
descent: metrics.descent,
fontSize: metrics.fontSize
};
},
/**
* Build a JSON representation of this Text Style.
*
* @method Phaser.GameObjects.TextStyle#toJSON
* @since 3.0.0
*
* @return {object} A JSON representation of this Text Style.
*/
toJSON: function() {
var output = {};
for (var key in propertyMap) {
output[key] = this[key];
}
output.metrics = this.getTextMetrics();
return output;
},
/**
* Destroy this Text Style.
*
* @method Phaser.GameObjects.TextStyle#destroy
* @since 3.0.0
*/
destroy: function() {
this.parent = void 0;
}
});
module2.exports = TextStyle;
}
),
/***/
34397: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Utils = __webpack_require__2(70554);
var TextWebGLRenderer = function(renderer, src, camera, parentMatrix) {
if (src.width === 0 || src.height === 0) {
return;
}
camera.addToRenderList(src);
var frame = src.frame;
var width = frame.width;
var height = frame.height;
var getTint = Utils.getTintAppendFloatAlpha;
var pipeline = renderer.pipelines.set(src.pipeline, src);
var textureUnit = pipeline.setTexture2D(frame.glTexture, src);
pipeline.batchTexture(
src,
frame.glTexture,
width,
height,
src.x,
src.y,
width / src.style.resolution,
height / src.style.resolution,
src.scaleX,
src.scaleY,
src.rotation,
src.flipX,
src.flipY,
src.scrollFactorX,
src.scrollFactorY,
src.displayOriginX,
src.displayOriginY,
0,
0,
width,
height,
getTint(src.tintTopLeft, camera.alpha * src._alphaTL),
getTint(src.tintTopRight, camera.alpha * src._alphaTR),
getTint(src.tintBottomLeft, camera.alpha * src._alphaBL),
getTint(src.tintBottomRight, camera.alpha * src._alphaBR),
src.tintFill,
0,
0,
camera,
parentMatrix,
false,
textureUnit
);
};
module2.exports = TextWebGLRenderer;
}
),
/***/
20839: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CanvasPool = __webpack_require__2(27919);
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31401);
var GameObject = __webpack_require__2(95643);
var GetPowerOfTwo = __webpack_require__2(98439);
var Smoothing = __webpack_require__2(68703);
var TileSpriteRender = __webpack_require__2(56295);
var UUID = __webpack_require__2(45650);
var Vector2 = __webpack_require__2(26099);
var _FLAG = 8;
var TileSprite = new Class({
Extends: GameObject,
Mixins: [
Components.Alpha,
Components.BlendMode,
Components.ComputedSize,
Components.Crop,
Components.Depth,
Components.Flip,
Components.GetBounds,
Components.Mask,
Components.Origin,
Components.Pipeline,
Components.PostPipeline,
Components.ScrollFactor,
Components.Tint,
Components.Transform,
Components.Visible,
TileSpriteRender
],
initialize: function TileSprite2(scene, x, y, width, height, textureKey, frameKey) {
var renderer = scene.sys.renderer;
GameObject.call(this, scene, "TileSprite");
var displayTexture = scene.sys.textures.get(textureKey);
var displayFrame = displayTexture.get(frameKey);
if (displayFrame.source.compressionAlgorithm) {
console.warn("TileSprite cannot use compressed texture");
displayTexture = scene.sys.textures.get("__MISSING");
displayFrame = displayTexture.get();
}
if (displayTexture.type === "DynamicTexture") {
console.warn("TileSprite cannot use Dynamic Texture");
displayTexture = scene.sys.textures.get("__MISSING");
displayFrame = displayTexture.get();
}
if (!width || !height) {
width = width ? width : displayFrame.width;
height = height ? height : displayFrame.height;
} else {
width = Math.floor(width);
height = Math.floor(height);
}
this._tilePosition = new Vector2();
this._tileScale = new Vector2(1, 1);
this.dirty = false;
this.renderer = renderer;
this.canvas = CanvasPool.create(this, width, height);
this.context = this.canvas.getContext("2d", { willReadFrequently: false });
this.displayTexture = displayTexture;
this.displayFrame = displayFrame;
this._crop = this.resetCropObject();
this._textureKey = UUID();
this.texture = scene.sys.textures.addCanvas(this._textureKey, this.canvas);
this.frame = this.texture.get();
this.potWidth = GetPowerOfTwo(displayFrame.width);
this.potHeight = GetPowerOfTwo(displayFrame.height);
this.fillCanvas = CanvasPool.create2D(this, this.potWidth, this.potHeight);
this.fillContext = this.fillCanvas.getContext("2d", { willReadFrequently: false });
this.fillPattern = null;
this.setPosition(x, y);
this.setSize(width, height);
this.setFrame(frameKey);
this.setOriginFromFrame();
this.initPipeline();
this.initPostPipeline(true);
},
/**
* Sets the texture and frame this Game Object will use to render with.
*
* Textures are referenced by their string-based keys, as stored in the Texture Manager.
*
* @method Phaser.GameObjects.TileSprite#setTexture
* @since 3.0.0
*
* @param {string} key - The key of the texture to be used, as stored in the Texture Manager.
* @param {(string|number)} [frame] - The name or index of the frame within the Texture.
*
* @return {this} This Game Object instance.
*/
setTexture: function(key, frame) {
this.displayTexture = this.scene.sys.textures.get(key);
return this.setFrame(frame);
},
/**
* Sets the frame this Game Object will use to render with.
*
* The Frame has to belong to the current Texture being used.
*
* It can be either a string or an index.
*
* @method Phaser.GameObjects.TileSprite#setFrame
* @since 3.0.0
*
* @param {(string|number)} frame - The name or index of the frame within the Texture.
*
* @return {this} This Game Object instance.
*/
setFrame: function(frame) {
var newFrame = this.displayTexture.get(frame);
this.potWidth = GetPowerOfTwo(newFrame.width);
this.potHeight = GetPowerOfTwo(newFrame.height);
this.canvas.width = 0;
if (!newFrame.cutWidth || !newFrame.cutHeight) {
this.renderFlags &= ~_FLAG;
} else {
this.renderFlags |= _FLAG;
}
this.displayFrame = newFrame;
this.dirty = true;
this.updateTileTexture();
return this;
},
/**
* Sets {@link Phaser.GameObjects.TileSprite#tilePositionX} and {@link Phaser.GameObjects.TileSprite#tilePositionY}.
*
* @method Phaser.GameObjects.TileSprite#setTilePosition
* @since 3.3.0
*
* @param {number} [x] - The x position of this sprite's tiling texture.
* @param {number} [y] - The y position of this sprite's tiling texture.
*
* @return {this} This Tile Sprite instance.
*/
setTilePosition: function(x, y) {
if (x !== void 0) {
this.tilePositionX = x;
}
if (y !== void 0) {
this.tilePositionY = y;
}
return this;
},
/**
* Sets {@link Phaser.GameObjects.TileSprite#tileScaleX} and {@link Phaser.GameObjects.TileSprite#tileScaleY}.
*
* @method Phaser.GameObjects.TileSprite#setTileScale
* @since 3.12.0
*
* @param {number} [x] - The horizontal scale of the tiling texture. If not given it will use the current `tileScaleX` value.
* @param {number} [y=x] - The vertical scale of the tiling texture. If not given it will use the `x` value.
*
* @return {this} This Tile Sprite instance.
*/
setTileScale: function(x, y) {
if (x === void 0) {
x = this.tileScaleX;
}
if (y === void 0) {
y = x;
}
this.tileScaleX = x;
this.tileScaleY = y;
return this;
},
/**
* Render the tile texture if it is dirty, or if the frame has changed.
*
* @method Phaser.GameObjects.TileSprite#updateTileTexture
* @private
* @since 3.0.0
*/
updateTileTexture: function() {
if (!this.dirty || !this.renderer) {
return;
}
var frame = this.displayFrame;
if (frame.source.isRenderTexture || frame.source.isGLTexture) {
console.warn("TileSprites can only use Image or Canvas based textures");
this.dirty = false;
return;
}
var ctx = this.fillContext;
var canvas = this.fillCanvas;
var fw = this.potWidth;
var fh = this.potHeight;
if (!this.renderer || !this.renderer.gl) {
fw = frame.cutWidth;
fh = frame.cutHeight;
}
ctx.clearRect(0, 0, fw, fh);
canvas.width = fw;
canvas.height = fh;
ctx.drawImage(
frame.source.image,
frame.cutX,
frame.cutY,
frame.cutWidth,
frame.cutHeight,
0,
0,
fw,
fh
);
if (this.renderer && this.renderer.gl) {
this.fillPattern = this.renderer.canvasToTexture(canvas, this.fillPattern);
if (false) {
}
} else {
this.fillPattern = ctx.createPattern(canvas, "repeat");
}
this.updateCanvas();
this.dirty = false;
},
/**
* Draw the fill pattern to the internal canvas.
*
* @method Phaser.GameObjects.TileSprite#updateCanvas
* @private
* @since 3.12.0
*/
updateCanvas: function() {
var canvas = this.canvas;
if (canvas.width !== this.width || canvas.height !== this.height) {
canvas.width = this.width;
canvas.height = this.height;
this.frame.setSize(this.width, this.height);
this.updateDisplayOrigin();
this.dirty = true;
}
if (!this.dirty || this.renderer && this.renderer.gl) {
this.dirty = false;
return;
}
var ctx = this.context;
if (!this.scene.sys.game.config.antialias) {
Smoothing.disable(ctx);
}
var scaleX = this._tileScale.x;
var scaleY = this._tileScale.y;
var positionX = this._tilePosition.x;
var positionY = this._tilePosition.y;
ctx.clearRect(0, 0, this.width, this.height);
ctx.save();
ctx.scale(scaleX, scaleY);
ctx.translate(-positionX, -positionY);
ctx.fillStyle = this.fillPattern;
ctx.fillRect(positionX, positionY, this.width / scaleX, this.height / scaleY);
ctx.restore();
this.dirty = false;
},
/**
* Internal destroy handler, called as part of the destroy process.
*
* @method Phaser.GameObjects.TileSprite#preDestroy
* @protected
* @since 3.9.0
*/
preDestroy: function() {
if (this.renderer && this.renderer.gl) {
this.renderer.deleteTexture(this.fillPattern);
}
CanvasPool.remove(this.canvas);
CanvasPool.remove(this.fillCanvas);
this.fillPattern = null;
this.fillContext = null;
this.fillCanvas = null;
this.displayTexture = null;
this.displayFrame = null;
var texture = this.texture;
if (texture) {
texture.destroy();
}
this.renderer = null;
},
/**
* The horizontal scroll position of the Tile Sprite.
*
* @name Phaser.GameObjects.TileSprite#tilePositionX
* @type {number}
* @default 0
* @since 3.0.0
*/
tilePositionX: {
get: function() {
return this._tilePosition.x;
},
set: function(value) {
this._tilePosition.x = value;
this.dirty = true;
}
},
/**
* The vertical scroll position of the Tile Sprite.
*
* @name Phaser.GameObjects.TileSprite#tilePositionY
* @type {number}
* @default 0
* @since 3.0.0
*/
tilePositionY: {
get: function() {
return this._tilePosition.y;
},
set: function(value) {
this._tilePosition.y = value;
this.dirty = true;
}
},
/**
* The horizontal scale of the Tile Sprite texture.
*
* @name Phaser.GameObjects.TileSprite#tileScaleX
* @type {number}
* @default 1
* @since 3.11.0
*/
tileScaleX: {
get: function() {
return this._tileScale.x;
},
set: function(value) {
this._tileScale.x = value;
this.dirty = true;
}
},
/**
* The vertical scale of the Tile Sprite texture.
*
* @name Phaser.GameObjects.TileSprite#tileScaleY
* @type {number}
* @default 1
* @since 3.11.0
*/
tileScaleY: {
get: function() {
return this._tileScale.y;
},
set: function(value) {
this._tileScale.y = value;
this.dirty = true;
}
}
});
module2.exports = TileSprite;
}
),
/***/
46992: (
/***/
(module2) => {
var TileSpriteCanvasRenderer = function(renderer, src, camera, parentMatrix) {
src.updateCanvas();
camera.addToRenderList(src);
renderer.batchSprite(src, src.frame, camera, parentMatrix);
};
module2.exports = TileSpriteCanvasRenderer;
}
),
/***/
14167: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var BuildGameObject = __webpack_require__2(25305);
var GameObjectCreator = __webpack_require__2(44603);
var GetAdvancedValue = __webpack_require__2(23568);
var TileSprite = __webpack_require__2(20839);
GameObjectCreator.register("tileSprite", function(config, addToScene) {
if (config === void 0) {
config = {};
}
var x = GetAdvancedValue(config, "x", 0);
var y = GetAdvancedValue(config, "y", 0);
var width = GetAdvancedValue(config, "width", 512);
var height = GetAdvancedValue(config, "height", 512);
var key = GetAdvancedValue(config, "key", "");
var frame = GetAdvancedValue(config, "frame", "");
var tile = new TileSprite(this.scene, x, y, width, height, key, frame);
if (addToScene !== void 0) {
config.add = addToScene;
}
BuildGameObject(this.scene, tile, config);
return tile;
});
}
),
/***/
91681: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var TileSprite = __webpack_require__2(20839);
var GameObjectFactory = __webpack_require__2(39429);
GameObjectFactory.register("tileSprite", function(x, y, width, height, texture, frame) {
return this.displayList.add(new TileSprite(this.scene, x, y, width, height, texture, frame));
});
}
),
/***/
56295: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(18553);
}
if (true) {
renderCanvas = __webpack_require__2(46992);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
18553: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Utils = __webpack_require__2(70554);
var TileSpriteWebGLRenderer = function(renderer, src, camera, parentMatrix) {
src.updateCanvas();
var width = src.width;
var height = src.height;
if (width === 0 || height === 0) {
return;
}
camera.addToRenderList(src);
var getTint = Utils.getTintAppendFloatAlpha;
var pipeline = renderer.pipelines.set(src.pipeline, src);
var textureUnit = pipeline.setTexture2D(src.fillPattern, src);
pipeline.batchTexture(
src,
src.fillPattern,
src.displayFrame.width * src.tileScaleX,
src.displayFrame.height * src.tileScaleY,
src.x,
src.y,
width,
height,
src.scaleX,
src.scaleY,
src.rotation,
src.flipX,
src.flipY,
src.scrollFactorX,
src.scrollFactorY,
src.originX * width,
src.originY * height,
0,
0,
width,
height,
getTint(src.tintTopLeft, camera.alpha * src._alphaTL),
getTint(src.tintTopRight, camera.alpha * src._alphaTR),
getTint(src.tintBottomLeft, camera.alpha * src._alphaBL),
getTint(src.tintBottomRight, camera.alpha * src._alphaBR),
src.tintFill,
src.tilePositionX % src.displayFrame.width / src.displayFrame.width,
src.tilePositionY % src.displayFrame.height / src.displayFrame.height,
camera,
parentMatrix,
false,
textureUnit
);
};
module2.exports = TileSpriteWebGLRenderer;
}
),
/***/
18471: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Clamp = __webpack_require__2(45319);
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31401);
var Events = __webpack_require__2(51708);
var GameEvents = __webpack_require__2(8443);
var GameObject = __webpack_require__2(95643);
var MATH_CONST = __webpack_require__2(36383);
var SoundEvents = __webpack_require__2(14463);
var UUID = __webpack_require__2(45650);
var VideoRender = __webpack_require__2(10247);
var Video = new Class({
Extends: GameObject,
Mixins: [
Components.Alpha,
Components.BlendMode,
Components.ComputedSize,
Components.Depth,
Components.Flip,
Components.GetBounds,
Components.Mask,
Components.Origin,
Components.Pipeline,
Components.PostPipeline,
Components.ScrollFactor,
Components.TextureCrop,
Components.Tint,
Components.Transform,
Components.Visible,
VideoRender
],
initialize: function Video2(scene, x, y, key) {
GameObject.call(this, scene, "Video");
this.video;
this.videoTexture;
this.videoTextureSource;
this.snapshotTexture;
this.flipY = false;
this._key = UUID();
this.touchLocked = false;
this.playWhenUnlocked = false;
this.frameReady = false;
this.isStalled = false;
this.failedPlayAttempts = 0;
this.metadata;
this.retry = 0;
this.retryInterval = 500;
this._systemMuted = false;
this._codeMuted = false;
this._systemPaused = false;
this._codePaused = false;
this._callbacks = {
ended: this.completeHandler.bind(this),
legacy: this.legacyPlayHandler.bind(this),
playing: this.playingHandler.bind(this),
seeked: this.seekedHandler.bind(this),
seeking: this.seekingHandler.bind(this),
stalled: this.stalledHandler.bind(this),
suspend: this.stalledHandler.bind(this),
waiting: this.stalledHandler.bind(this)
};
this._loadCallbackHandler = this.loadErrorHandler.bind(this);
this._metadataCallbackHandler = this.metadataHandler.bind(this);
this._crop = this.resetCropObject();
this.markers = {};
this._markerIn = 0;
this._markerOut = 0;
this._playingMarker = false;
this._lastUpdate = 0;
this.cacheKey = "";
this.isSeeking = false;
this._playCalled = false;
this._getFrame = false;
this._rfvCallbackId = 0;
var game = scene.sys.game;
this._device = game.device.video;
this.setPosition(x, y);
this.setSize(256, 256);
this.initPipeline();
this.initPostPipeline(true);
game.events.on(GameEvents.PAUSE, this.globalPause, this);
game.events.on(GameEvents.RESUME, this.globalResume, this);
var sound = scene.sys.sound;
if (sound) {
sound.on(SoundEvents.GLOBAL_MUTE, this.globalMute, this);
}
if (key) {
this.load(key);
}
},
// Overrides Game Object method
addedToScene: function() {
this.scene.sys.updateList.add(this);
},
// Overrides Game Object method
removedFromScene: function() {
this.scene.sys.updateList.remove(this);
},
/**
* Loads a Video from the Video Cache, ready for playback with the `Video.play` method.
*
* If a video is already playing, this method allows you to change the source of the current video element.
* It works by first stopping the current video and then starts playback of the new source through the existing video element.
*
* The reason you may wish to do this is because videos that require interaction to unlock, remain in an unlocked
* state, even if you change the source of the video. By changing the source to a new video you avoid having to
* go through the unlock process again.
*
* @method Phaser.GameObjects.Video#load
* @since 3.60.0
*
* @param {string} key - The key of the Video this Game Object will play, as stored in the Video Cache.
*
* @return {this} This Video Game Object for method chaining.
*/
load: function(key) {
var video = this.scene.sys.cache.video.get(key);
if (video) {
this.cacheKey = key;
this.loadHandler(video.url, video.noAudio, video.crossOrigin);
} else {
console.warn("No video in cache for key: " + key);
}
return this;
},
/**
* This method allows you to change the source of the current video element. It works by first stopping the
* current video, if playing. Then deleting the video texture, if one has been created. Finally, it makes a
* new video texture and starts playback of the new source through the existing video element.
*
* The reason you may wish to do this is because videos that require interaction to unlock, remain in an unlocked
* state, even if you change the source of the video. By changing the source to a new video you avoid having to
* go through the unlock process again.
*
* @method Phaser.GameObjects.Video#changeSource
* @since 3.20.0
*
* @param {string} key - The key of the Video this Game Object will swap to playing, as stored in the Video Cache.
* @param {boolean} [autoplay=true] - Should the video start playing immediately, once the swap is complete?
* @param {boolean} [loop=false] - Should the video loop automatically when it reaches the end? Please note that not all browsers support _seamless_ video looping for all encoding formats.
* @param {number} [markerIn] - Optional in marker time, in seconds, for playback of a sequence of the video.
* @param {number} [markerOut] - Optional out marker time, in seconds, for playback of a sequence of the video.
*
* @return {this} This Video Game Object for method chaining.
*/
changeSource: function(key, autoplay, loop, markerIn, markerOut) {
if (autoplay === void 0) {
autoplay = true;
}
if (loop === void 0) {
loop = false;
}
if (this.cacheKey !== key) {
this.load(key);
if (autoplay) {
this.play(loop, markerIn, markerOut);
}
}
},
/**
* Returns the key of the currently played video, as stored in the Video Cache.
*
* If the video did not come from the cache this will return an empty string.
*
* @method Phaser.GameObjects.Video#getVideoKey
* @since 3.20.0
*
* @return {string} The key of the video being played from the Video Cache, if any.
*/
getVideoKey: function() {
return this.cacheKey;
},
/**
* Loads a Video from the given URL, ready for playback with the `Video.play` method.
*
* If a video is already playing, this method allows you to change the source of the current video element.
* It works by first stopping the current video and then starts playback of the new source through the existing video element.
*
* The reason you may wish to do this is because videos that require interaction to unlock, remain in an unlocked
* state, even if you change the source of the video. By changing the source to a new video you avoid having to
* go through the unlock process again.
*
* @method Phaser.GameObjects.Video#loadURL
* @since 3.60.0
*
* @param {(string|string[]|Phaser.Types.Loader.FileTypes.VideoFileURLConfig|Phaser.Types.Loader.FileTypes.VideoFileURLConfig[])} [urls] - The absolute or relative URL to load the video files from.
* @param {boolean} [noAudio=false] - Does the video have an audio track? If not you can enable auto-playing on it.
* @param {string} [crossOrigin] - The value to use for the `crossOrigin` property in the video load request. Either undefined, `anonymous` or `use-credentials`. If no value is given, `crossorigin` will not be set in the request.
*
* @return {this} This Video Game Object for method chaining.
*/
loadURL: function(urls, noAudio, crossOrigin) {
if (noAudio === void 0) {
noAudio = false;
}
var urlConfig = this._device.getVideoURL(urls);
if (!urlConfig) {
console.warn("No supported video format found for " + urls);
} else {
this.cacheKey = "";
this.loadHandler(urlConfig.url, noAudio, crossOrigin);
}
return this;
},
/**
* Loads a Video from the given MediaStream object, ready for playback with the `Video.play` method.
*
* @method Phaser.GameObjects.Video#loadMediaStream
* @since 3.50.0
*
* @param {string} stream - The MediaStream object.
* @param {boolean} [noAudio=false] - Does the video have an audio track? If not you can enable auto-playing on it.
* @param {string} [crossOrigin] - The value to use for the `crossOrigin` property in the video load request. Either undefined, `anonymous` or `use-credentials`. If no value is given, `crossorigin` will not be set in the request.
*
* @return {this} This Video Game Object for method chaining.
*/
loadMediaStream: function(stream, noAudio, crossOrigin) {
return this.loadHandler(null, noAudio, crossOrigin, stream);
},
/**
* Internal method that loads a Video from the given URL, ready for playback with the
* `Video.play` method.
*
* Normally you don't call this method directly, but instead use the `Video.loadURL` method,
* or the `Video.load` method if you have preloaded the video.
*
* Calling this method will skip checking if the browser supports the given format in
* the URL, where-as the other two methods enforce these checks.
*
* @method Phaser.GameObjects.Video#loadHandler
* @since 3.60.0
*
* @param {string} [url] - The absolute or relative URL to load the video file from. Set to `null` if passing in a MediaStream object.
* @param {boolean} [noAudio] - Does the video have an audio track? If not you can enable auto-playing on it.
* @param {string} [crossOrigin] - The value to use for the `crossOrigin` property in the video load request. Either undefined, `anonymous` or `use-credentials`. If no value is given, `crossorigin` will not be set in the request.
* @param {string} [stream] - A MediaStream object if this is playing a stream instead of a file.
*
* @return {this} This Video Game Object for method chaining.
*/
loadHandler: function(url, noAudio, crossOrigin, stream) {
if (!noAudio) {
noAudio = false;
}
var video = this.video;
if (video) {
this.removeLoadEventHandlers();
this.stop();
} else {
video = document.createElement("video");
video.controls = false;
video.setAttribute("playsinline", "playsinline");
video.setAttribute("preload", "auto");
video.setAttribute("disablePictureInPicture", "true");
}
if (noAudio) {
video.muted = true;
video.defaultMuted = true;
video.setAttribute("autoplay", "autoplay");
} else {
video.muted = false;
video.defaultMuted = false;
video.removeAttribute("autoplay");
}
if (!crossOrigin) {
video.removeAttribute("crossorigin");
} else {
video.setAttribute("crossorigin", crossOrigin);
}
if (stream) {
if ("srcObject" in video) {
try {
video.srcObject = stream;
} catch (err) {
if (err.name !== "TypeError") {
throw err;
}
video.src = URL.createObjectURL(stream);
}
} else {
video.src = URL.createObjectURL(stream);
}
} else {
video.src = url;
}
this.retry = 0;
this.video = video;
this._playCalled = false;
video.load();
this.addLoadEventHandlers();
var texture = this.scene.sys.textures.get(this._key);
this.setTexture(texture);
return this;
},
/**
* This method handles the Request Video Frame callback.
*
* It is called by the browser when a new video frame is ready to be displayed.
*
* It's also responsible for the creation of the video texture, if it doesn't
* already exist. If it does, it updates the texture as required.
*
* For more details about the Request Video Frame callback, see:
* https://web.dev/requestvideoframecallback-rvfc
*
* @method Phaser.GameObjects.Video#requestVideoFrame
* @fires Phaser.GameObjects.Events#VIDEO_CREATED
* @fires Phaser.GameObjects.Events#VIDEO_LOOP
* @fires Phaser.GameObjects.Events#VIDEO_COMPLETE
* @fires Phaser.GameObjects.Events#VIDEO_PLAY
* @fires Phaser.GameObjects.Events#VIDEO_TEXTURE
* @since 3.60.0
*
* @param {DOMHighResTimeStamp} now - The current time in milliseconds.
* @param {VideoFrameCallbackMetadata} metadata - Useful metadata about the video frame that was most recently presented for composition. See https://wicg.github.io/video-rvfc/#video-frame-metadata-callback
*/
requestVideoFrame: function(now, metadata) {
var video = this.video;
if (!video) {
return;
}
var width = metadata.width;
var height = metadata.height;
var texture = this.videoTexture;
var textureSource = this.videoTextureSource;
var newVideo = !texture || textureSource.source !== video;
if (newVideo) {
this._codePaused = video.paused;
this._codeMuted = video.muted;
if (!texture) {
texture = this.scene.sys.textures.create(this._key, video, width, height);
texture.add("__BASE", 0, 0, 0, width, height);
this.setTexture(texture);
this.videoTexture = texture;
this.videoTextureSource = texture.source[0];
this.videoTextureSource.setFlipY(this.flipY);
this.emit(Events.VIDEO_TEXTURE, this, texture);
} else {
textureSource.source = video;
textureSource.width = width;
textureSource.height = height;
texture.get().setSize(width, height);
}
this.setSizeToFrame();
this.updateDisplayOrigin();
} else {
textureSource.update();
}
this.isStalled = false;
this.metadata = metadata;
var currentTime = metadata.mediaTime;
if (newVideo) {
this._lastUpdate = currentTime;
this.emit(Events.VIDEO_CREATED, this, width, height);
if (!this.frameReady) {
this.frameReady = true;
this.emit(Events.VIDEO_PLAY, this);
}
}
if (this._playingMarker) {
if (currentTime >= this._markerOut) {
if (video.loop) {
video.currentTime = this._markerIn;
this.emit(Events.VIDEO_LOOP, this);
} else {
this.stop(false);
this.emit(Events.VIDEO_COMPLETE, this);
}
}
} else if (currentTime < this._lastUpdate) {
this.emit(Events.VIDEO_LOOP, this);
}
this._lastUpdate = currentTime;
if (this._getFrame) {
this.removeEventHandlers();
video.pause();
this._getFrame = false;
} else {
this._rfvCallbackId = this.video.requestVideoFrameCallback(this.requestVideoFrame.bind(this));
}
},
/**
* Starts this video playing.
*
* If the video is already playing, or has been queued to play with `changeSource` then this method just returns.
*
* Videos can only autoplay if the browser has been unlocked. This happens if you have interacted with the browser, i.e.
* by clicking on it or pressing a key, or due to server settings. The policies that control autoplaying are vast and
* vary between browser. You can read more here: https://developer.mozilla.org/en-US/docs/Web/Media/Autoplay_guide
*
* If your video doesn't contain any audio, then set the `noAudio` parameter to `true` when the video is loaded,
* and it will often allow the video to play immediately:
*
* ```javascript
* preload () {
* this.load.video('pixar', 'nemo.mp4', true);
* }
* ```
*
* The 3rd parameter in the load call tells Phaser that the video doesn't contain any audio tracks. Video without
* audio can autoplay without requiring a user interaction. Video with audio cannot do this unless it satisfies
* the browsers MEI settings. See the MDN Autoplay Guide for details.
*
* If you need audio in your videos, then you'll have to consider the fact that the video cannot start playing until the
* user has interacted with the browser, into your game flow.
*
* @method Phaser.GameObjects.Video#play
* @since 3.20.0
*
* @param {boolean} [loop=false] - Should the video loop automatically when it reaches the end? Please note that not all browsers support _seamless_ video looping for all encoding formats.
* @param {number} [markerIn] - Optional in marker time, in seconds, for playback of a sequence of the video.
* @param {number} [markerOut] - Optional out marker time, in seconds, for playback of a sequence of the video.
*
* @return {this} This Video Game Object for method chaining.
*/
play: function(loop, markerIn, markerOut) {
if (markerIn === void 0) {
markerIn = -1;
}
if (markerOut === void 0) {
markerOut = MATH_CONST.MAX_SAFE_INTEGER;
}
var video = this.video;
if (!video || this.isPlaying()) {
if (!video) {
console.warn("Video not loaded");
}
return this;
}
if (loop === void 0) {
loop = video.loop;
}
video.loop = loop;
this._markerIn = markerIn;
this._markerOut = markerOut;
this._playingMarker = markerIn > -1 && markerOut > markerIn && markerOut < MATH_CONST.MAX_SAFE_INTEGER;
if (!this._playCalled) {
this._getFrame = false;
this._rfvCallbackId = video.requestVideoFrameCallback(this.requestVideoFrame.bind(this));
this._playCalled = true;
this.createPlayPromise();
}
return this;
},
/**
* Attempts to get the first frame of the video by running the `requestVideoFrame` callback once,
* then stopping. This is useful if you need to grab the first frame of the video to display behind
* a 'play' button, without actually calling the 'play' method.
*
* If the video is already playing, or has been queued to play with `changeSource` then this method just returns.
*
* @method Phaser.GameObjects.Video#getFirstFrame
* @since 3.85.0
*
* @return {this} This Video Game Object for method chaining.
*/
getFirstFrame: function() {
var video = this.video;
if (!video || this.isPlaying()) {
if (!video) {
console.warn("Video not loaded");
}
return this;
}
if (!this._playCalled) {
this._getFrame = true;
this._rfvCallbackId = video.requestVideoFrameCallback(this.requestVideoFrame.bind(this));
this.createPlayPromise();
}
return this;
},
/**
* Adds the loading specific event handlers to the video element.
*
* @method Phaser.GameObjects.Video#addLoadEventHandlers
* @since 3.60.0
*/
addLoadEventHandlers: function() {
var video = this.video;
if (video) {
video.addEventListener("error", this._loadCallbackHandler);
video.addEventListener("abort", this._loadCallbackHandler);
video.addEventListener("loadedmetadata", this._metadataCallbackHandler);
}
},
/**
* Removes the loading specific event handlers from the video element.
*
* @method Phaser.GameObjects.Video#removeLoadEventHandlers
* @since 3.60.0
*/
removeLoadEventHandlers: function() {
var video = this.video;
if (video) {
video.removeEventListener("error", this._loadCallbackHandler);
video.removeEventListener("abort", this._loadCallbackHandler);
}
},
/**
* Adds the playback specific event handlers to the video element.
*
* @method Phaser.GameObjects.Video#addEventHandlers
* @since 3.60.0
*/
addEventHandlers: function() {
var video = this.video;
if (video) {
var callbacks = this._callbacks;
for (var callback in callbacks) {
video.addEventListener(callback, callbacks[callback]);
}
}
},
/**
* Removes the playback specific event handlers from the video element.
*
* @method Phaser.GameObjects.Video#removeEventHandlers
* @since 3.60.0
*/
removeEventHandlers: function() {
var video = this.video;
if (video) {
var callbacks = this._callbacks;
for (var callback in callbacks) {
video.removeEventListener(callback, callbacks[callback]);
}
}
},
/**
* Creates the video.play promise and adds the success and error handlers to it.
*
* Not all browsers support the video.play promise, so this method will fall back to
* the old-school way of handling the video.play call.
*
* See https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/play#browser_compatibility for details.
*
* @method Phaser.GameObjects.Video#createPlayPromise
* @since 3.60.0
*
* @param {boolean} [catchError=true] - Should the error be caught and the video marked as failed to play?
*/
createPlayPromise: function(catchError) {
if (catchError === void 0) {
catchError = true;
}
var video = this.video;
var playPromise = video.play();
if (playPromise !== void 0) {
var success = this.playSuccess.bind(this);
var error = this.playError.bind(this);
if (!catchError) {
var _this = this;
error = function() {
_this.failedPlayAttempts++;
};
}
playPromise.then(success).catch(error);
} else {
video.addEventListener("playing", this._callbacks.legacy);
if (!catchError) {
this.failedPlayAttempts++;
}
}
},
/**
* Adds a sequence marker to this video.
*
* Markers allow you to split a video up into sequences, delineated by a start and end time, given in seconds.
*
* You can then play back specific markers via the `playMarker` method.
*
* Note that marker timing is _not_ frame-perfect. You should construct your videos in such a way that you allow for
* plenty of extra padding before and after each sequence to allow for discrepancies in browser seek and currentTime accuracy.
*
* See https://github.com/w3c/media-and-entertainment/issues/4 for more details about this issue.
*
* @method Phaser.GameObjects.Video#addMarker
* @since 3.20.0
*
* @param {string} key - A unique name to give this marker.
* @param {number} markerIn - The time, in seconds, representing the start of this marker.
* @param {number} markerOut - The time, in seconds, representing the end of this marker.
*
* @return {this} This Video Game Object for method chaining.
*/
addMarker: function(key, markerIn, markerOut) {
if (!isNaN(markerIn) && markerIn >= 0 && !isNaN(markerOut) && markerOut > markerIn) {
this.markers[key] = [markerIn, markerOut];
}
return this;
},
/**
* Plays a pre-defined sequence in this video.
*
* Markers allow you to split a video up into sequences, delineated by a start and end time, given in seconds and
* specified via the `addMarker` method.
*
* Note that marker timing is _not_ frame-perfect. You should construct your videos in such a way that you allow for
* plenty of extra padding before and after each sequence to allow for discrepancies in browser seek and currentTime accuracy.
*
* See https://github.com/w3c/media-and-entertainment/issues/4 for more details about this issue.
*
* @method Phaser.GameObjects.Video#playMarker
* @since 3.20.0
*
* @param {string} key - The name of the marker sequence to play.
* @param {boolean} [loop=false] - Should the video loop automatically when it reaches the end? Please note that not all browsers support _seamless_ video looping for all encoding formats.
*
* @return {this} This Video Game Object for method chaining.
*/
playMarker: function(key, loop) {
var marker = this.markers[key];
if (marker) {
this.play(loop, marker[0], marker[1]);
}
return this;
},
/**
* Removes a previously set marker from this video.
*
* If the marker is currently playing it will _not_ stop playback.
*
* @method Phaser.GameObjects.Video#removeMarker
* @since 3.20.0
*
* @param {string} key - The name of the marker to remove.
*
* @return {this} This Video Game Object for method chaining.
*/
removeMarker: function(key) {
delete this.markers[key];
return this;
},
/**
* Takes a snapshot of the current frame of the video and renders it to a CanvasTexture object,
* which is then returned. You can optionally resize the grab by passing a width and height.
*
* This method returns a reference to the `Video.snapshotTexture` object. Calling this method
* multiple times will overwrite the previous snapshot with the most recent one.
*
* @method Phaser.GameObjects.Video#snapshot
* @since 3.20.0
*
* @param {number} [width] - The width of the resulting CanvasTexture.
* @param {number} [height] - The height of the resulting CanvasTexture.
*
* @return {Phaser.Textures.CanvasTexture}
*/
snapshot: function(width, height) {
if (width === void 0) {
width = this.width;
}
if (height === void 0) {
height = this.height;
}
return this.snapshotArea(0, 0, this.width, this.height, width, height);
},
/**
* Takes a snapshot of the specified area of the current frame of the video and renders it to a CanvasTexture object,
* which is then returned. You can optionally resize the grab by passing a different `destWidth` and `destHeight`.
*
* This method returns a reference to the `Video.snapshotTexture` object. Calling this method
* multiple times will overwrite the previous snapshot with the most recent one.
*
* @method Phaser.GameObjects.Video#snapshotArea
* @since 3.20.0
*
* @param {number} [x=0] - The horizontal location of the top-left of the area to grab from.
* @param {number} [y=0] - The vertical location of the top-left of the area to grab from.
* @param {number} [srcWidth] - The width of area to grab from the video. If not given it will grab the full video dimensions.
* @param {number} [srcHeight] - The height of area to grab from the video. If not given it will grab the full video dimensions.
* @param {number} [destWidth] - The destination width of the grab, allowing you to resize it.
* @param {number} [destHeight] - The destination height of the grab, allowing you to resize it.
*
* @return {Phaser.Textures.CanvasTexture}
*/
snapshotArea: function(x, y, srcWidth, srcHeight, destWidth, destHeight) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (srcWidth === void 0) {
srcWidth = this.width;
}
if (srcHeight === void 0) {
srcHeight = this.height;
}
if (destWidth === void 0) {
destWidth = srcWidth;
}
if (destHeight === void 0) {
destHeight = srcHeight;
}
var video = this.video;
var snap = this.snapshotTexture;
if (!snap) {
snap = this.scene.sys.textures.createCanvas(UUID(), destWidth, destHeight);
this.snapshotTexture = snap;
if (video) {
snap.context.drawImage(video, x, y, srcWidth, srcHeight, 0, 0, destWidth, destHeight);
}
} else {
snap.setSize(destWidth, destHeight);
if (video) {
snap.context.drawImage(video, x, y, srcWidth, srcHeight, 0, 0, destWidth, destHeight);
}
}
return snap.update();
},
/**
* Stores a copy of this Videos `snapshotTexture` in the Texture Manager using the given key.
*
* This texture is created when the `snapshot` or `snapshotArea` methods are called.
*
* After doing this, any texture based Game Object, such as a Sprite, can use the contents of the
* snapshot by using the texture key:
*
* ```javascript
* var vid = this.add.video(0, 0, 'intro');
*
* vid.snapshot();
*
* vid.saveSnapshotTexture('doodle');
*
* this.add.image(400, 300, 'doodle');
* ```
*
* Updating the contents of the `snapshotTexture`, for example by calling `snapshot` again,
* will automatically update _any_ Game Object that is using it as a texture.
* Calling `saveSnapshotTexture` again will not save another copy of the same texture,
* it will just rename the existing one.
*
* By default it will create a single base texture. You can add frames to the texture
* by using the `Texture.add` method. After doing this, you can then allow Game Objects
* to use a specific frame.
*
* @method Phaser.GameObjects.Video#saveSnapshotTexture
* @since 3.20.0
*
* @param {string} key - The unique key to store the texture as within the global Texture Manager.
*
* @return {Phaser.Textures.CanvasTexture} The Texture that was saved.
*/
saveSnapshotTexture: function(key) {
if (this.snapshotTexture) {
this.scene.sys.textures.renameTexture(this.snapshotTexture.key, key);
} else {
this.snapshotTexture = this.scene.sys.textures.createCanvas(key, this.width, this.height);
}
return this.snapshotTexture;
},
/**
* This internal method is called automatically if the playback Promise resolves successfully.
*
* @method Phaser.GameObjects.Video#playSuccess
* @fires Phaser.GameObjects.Events#VIDEO_UNLOCKED
* @since 3.60.0
*/
playSuccess: function() {
if (!this._playCalled) {
return;
}
this.addEventHandlers();
this._codePaused = false;
if (this.touchLocked) {
this.touchLocked = false;
this.emit(Events.VIDEO_UNLOCKED, this);
}
var sound = this.scene.sys.sound;
if (sound && sound.mute) {
this.setMute(true);
}
if (this._markerIn > -1) {
this.video.currentTime = this._markerIn;
}
},
/**
* This internal method is called automatically if the playback Promise fails to resolve.
*
* @method Phaser.GameObjects.Video#playError
* @fires Phaser.GameObjects.Events#VIDEO_ERROR
* @fires Phaser.GameObjects.Events#VIDEO_UNSUPPORTED
* @fires Phaser.GameObjects.Events#VIDEO_LOCKED
* @since 3.60.0
*
* @param {DOMException} error - The Promise DOM Exception error.
*/
playError: function(error) {
var name = error.name;
if (name === "NotAllowedError") {
this.touchLocked = true;
this.playWhenUnlocked = true;
this.failedPlayAttempts = 1;
this.emit(Events.VIDEO_LOCKED, this);
} else if (name === "NotSupportedError") {
this.stop(false);
this.emit(Events.VIDEO_UNSUPPORTED, this, error);
} else {
this.stop(false);
this.emit(Events.VIDEO_ERROR, this, error);
}
},
/**
* Called when the video emits a `playing` event.
*
* This is the legacy handler for browsers that don't support Promise based playback.
*
* @method Phaser.GameObjects.Video#legacyPlayHandler
* @since 3.60.0
*/
legacyPlayHandler: function() {
var video = this.video;
if (video) {
this.playSuccess();
video.removeEventListener("playing", this._callbacks.legacy);
}
},
/**
* Called when the video emits a `playing` event.
*
* @method Phaser.GameObjects.Video#playingHandler
* @fires Phaser.GameObjects.Events#VIDEO_PLAYING
* @since 3.60.0
*/
playingHandler: function() {
this.isStalled = false;
this.emit(Events.VIDEO_PLAYING, this);
},
/**
* This internal method is called automatically if the video fails to load.
*
* @method Phaser.GameObjects.Video#loadErrorHandler
* @fires Phaser.GameObjects.Events#VIDEO_ERROR
* @since 3.20.0
*
* @param {Event} event - The error Event.
*/
loadErrorHandler: function(event) {
this.stop(false);
this.emit(Events.VIDEO_ERROR, this, event);
},
/**
* This internal method is called automatically when the video metadata is available.
*
* @method Phaser.GameObjects.Video#metadataHandler
* @fires Phaser.GameObjects.Events#VIDEO_METADATA
* @since 3.80.0
*
* @param {Event} event - The loadedmetadata Event.
*/
metadataHandler: function(event) {
this.emit(Events.VIDEO_METADATA, this, event);
},
/**
* Sets the size of this Game Object to be that of the given Frame.
*
* This will not change the size that the Game Object is rendered in-game.
* For that you need to either set the scale of the Game Object (`setScale`) or call the
* `setDisplaySize` method, which is the same thing as changing the scale but allows you
* to do so by giving pixel values.
*
* If you have enabled this Game Object for input, changing the size will _not_ change the
* size of the hit area. To do this you should adjust the `input.hitArea` object directly.
*
* @method Phaser.GameObjects.Video#setSizeToFrame
* @since 3.0.0
*
* @param {Phaser.Textures.Frame|boolean} [frame] - The frame to base the size of this Game Object on.
*
* @return {this} This Game Object instance.
*/
setSizeToFrame: function(frame) {
if (!frame) {
frame = this.frame;
}
this.width = frame.realWidth;
this.height = frame.realHeight;
if (this.scaleX !== 1) {
this.scaleX = this.displayWidth / this.width;
}
if (this.scaleY !== 1) {
this.scaleY = this.displayHeight / this.height;
}
var input = this.input;
if (input && !input.customHitArea) {
input.hitArea.width = this.width;
input.hitArea.height = this.height;
}
return this;
},
/**
* This internal method is called automatically if the video stalls, for whatever reason.
*
* @method Phaser.GameObjects.Video#stalledHandler
* @fires Phaser.GameObjects.Events#VIDEO_STALLED
* @since 3.60.0
*
* @param {Event} event - The error Event.
*/
stalledHandler: function(event) {
this.isStalled = true;
this.emit(Events.VIDEO_STALLED, this, event);
},
/**
* Called when the video completes playback, i.e. reaches an `ended` state.
*
* This will never happen if the video is coming from a live stream, where the duration is `Infinity`.
*
* @method Phaser.GameObjects.Video#completeHandler
* @fires Phaser.GameObjects.Events#VIDEO_COMPLETE
* @since 3.20.0
*/
completeHandler: function() {
this._playCalled = false;
this.emit(Events.VIDEO_COMPLETE, this);
},
/**
* The internal update step.
*
* @method Phaser.GameObjects.Video#preUpdate
* @private
* @since 3.20.0
*
* @param {number} time - The current timestamp.
* @param {number} delta - The delta time in ms since the last frame.
*/
preUpdate: function(time, delta) {
var video = this.video;
if (!video || !this._playCalled) {
return;
}
if (this.touchLocked && this.playWhenUnlocked) {
this.retry += delta;
if (this.retry >= this.retryInterval) {
this.createPlayPromise(false);
this.retry = 0;
}
}
},
/**
* Seeks to a given point in the video. The value is given as a float between 0 and 1,
* where 0 represents the start of the video and 1 represents the end.
*
* Seeking only works if the video has a duration, so will not work for live streams.
*
* When seeking begins, this video will emit a `seeking` event. When the video completes
* seeking (i.e. reaches its designated timestamp) it will emit a `seeked` event.
*
* If you wish to seek based on time instead, use the `Video.setCurrentTime` method.
*
* Unfortunately, the DOM video element does not guarantee frame-accurate seeking.
* This has been an ongoing subject of discussion: https://github.com/w3c/media-and-entertainment/issues/4
*
* @method Phaser.GameObjects.Video#seekTo
* @since 3.20.0
*
* @param {number} value - The point in the video to seek to. A value between 0 and 1.
*
* @return {this} This Video Game Object for method chaining.
*/
seekTo: function(value) {
var video = this.video;
if (video) {
var duration = video.duration;
if (duration !== Infinity && !isNaN(duration)) {
var seekTime = duration * value;
this.setCurrentTime(seekTime);
}
}
return this;
},
/**
* A double-precision floating-point value indicating the current playback time in seconds.
*
* If the media has not started to play and has not been seeked, this value is the media's initial playback time.
*
* For a more accurate value, use the `Video.metadata.mediaTime` property instead.
*
* @method Phaser.GameObjects.Video#getCurrentTime
* @since 3.20.0
*
* @return {number} A double-precision floating-point value indicating the current playback time in seconds.
*/
getCurrentTime: function() {
return this.video ? this.video.currentTime : 0;
},
/**
* Seeks to a given playback time in the video. The value is given in _seconds_ or as a string.
*
* Seeking only works if the video has a duration, so will not work for live streams.
*
* When seeking begins, this video will emit a `seeking` event. When the video completes
* seeking (i.e. reaches its designated timestamp) it will emit a `seeked` event.
*
* You can provide a string prefixed with either a `+` or a `-`, such as `+2.5` or `-2.5`.
* In this case it will seek to +/- the value given, relative to the _current time_.
*
* If you wish to seek based on a duration percentage instead, use the `Video.seekTo` method.
*
* @method Phaser.GameObjects.Video#setCurrentTime
* @since 3.20.0
*
* @param {(string|number)} value - The playback time to seek to in seconds. Can be expressed as a string, such as `+2` to seek 2 seconds ahead from the current time.
*
* @return {this} This Video Game Object for method chaining.
*/
setCurrentTime: function(value) {
var video = this.video;
if (video) {
if (typeof value === "string") {
var op = value[0];
var num = parseFloat(value.substr(1));
if (op === "+") {
value = video.currentTime + num;
} else if (op === "-") {
value = video.currentTime - num;
}
}
video.currentTime = value;
}
return this;
},
/**
* Internal seeking handler.
*
* @method Phaser.GameObjects.Video#seekingHandler
* @fires Phaser.GameObjects.Events#VIDEO_SEEKING
* @private
* @since 3.20.0
*/
seekingHandler: function() {
this.isSeeking = true;
this.emit(Events.VIDEO_SEEKING, this);
},
/**
* Internal seeked handler.
*
* @method Phaser.GameObjects.Video#seekedHandler
* @fires Phaser.GameObjects.Events#VIDEO_SEEKED
* @private
* @since 3.20.0
*/
seekedHandler: function() {
this.isSeeking = false;
this.emit(Events.VIDEO_SEEKED, this);
},
/**
* Returns the current progress of the video as a float.
*
* Progress is defined as a value between 0 (the start) and 1 (the end).
*
* Progress can only be returned if the video has a duration. Some videos,
* such as those coming from a live stream, do not have a duration. In this
* case the method will return -1.
*
* @method Phaser.GameObjects.Video#getProgress
* @since 3.20.0
*
* @return {number} The current progress of playback. If the video has no duration, will always return -1.
*/
getProgress: function() {
var video = this.video;
if (video) {
var duration = video.duration;
if (duration !== Infinity && !isNaN(duration)) {
return video.currentTime / duration;
}
}
return -1;
},
/**
* A double-precision floating-point value which indicates the duration (total length) of the media in seconds,
* on the media's timeline. If no media is present on the element, or the media is not valid, the returned value is NaN.
*
* If the media has no known end (such as for live streams of unknown duration, web radio, media incoming from WebRTC,
* and so forth), this value is +Infinity.
*
* If no video has been loaded, this method will return 0.
*
* @method Phaser.GameObjects.Video#getDuration
* @since 3.20.0
*
* @return {number} A double-precision floating-point value indicating the duration of the media in seconds.
*/
getDuration: function() {
return this.video ? this.video.duration : 0;
},
/**
* Sets the muted state of the currently playing video, if one is loaded.
*
* @method Phaser.GameObjects.Video#setMute
* @since 3.20.0
*
* @param {boolean} [value=true] - The mute value. `true` if the video should be muted, otherwise `false`.
*
* @return {this} This Video Game Object for method chaining.
*/
setMute: function(value) {
if (value === void 0) {
value = true;
}
this._codeMuted = value;
var video = this.video;
if (video) {
video.muted = this._systemMuted ? true : value;
}
return this;
},
/**
* Returns a boolean indicating if this Video is currently muted.
*
* @method Phaser.GameObjects.Video#isMuted
* @since 3.20.0
*
* @return {boolean} A boolean indicating if this Video is currently muted, or not.
*/
isMuted: function() {
return this._codeMuted;
},
/**
* Internal global mute handler. Will mute the video, if playing, if the global sound system mutes.
*
* @method Phaser.GameObjects.Video#globalMute
* @private
* @since 3.20.0
*
* @param {(Phaser.Sound.WebAudioSoundManager|Phaser.Sound.HTML5AudioSoundManager)} soundManager - A reference to the Sound Manager that emitted the event.
* @param {boolean} mute - The mute value. `true` if the Sound Manager is now muted, otherwise `false`.
*/
globalMute: function(soundManager, value) {
this._systemMuted = value;
var video = this.video;
if (video) {
video.muted = this._codeMuted ? true : value;
}
},
/**
* Internal global pause handler. Will pause the video if the Game itself pauses.
*
* @method Phaser.GameObjects.Video#globalPause
* @private
* @since 3.20.0
*/
globalPause: function() {
this._systemPaused = true;
if (this.video && !this.video.ended) {
this.removeEventHandlers();
this.video.pause();
}
},
/**
* Internal global resume handler. Will resume a paused video if the Game itself resumes.
*
* @method Phaser.GameObjects.Video#globalResume
* @private
* @since 3.20.0
*/
globalResume: function() {
this._systemPaused = false;
if (this.video && !this._codePaused && !this.video.ended) {
this.createPlayPromise();
}
},
/**
* Sets the paused state of the currently loaded video.
*
* If the video is playing, calling this method with `true` will pause playback.
* If the video is paused, calling this method with `false` will resume playback.
*
* If no video is loaded, this method does nothing.
*
* If the video has not yet been played, `Video.play` will be called with no parameters.
*
* If the video has ended, this method will do nothing.
*
* @method Phaser.GameObjects.Video#setPaused
* @since 3.20.0
*
* @param {boolean} [value=true] - The paused value. `true` if the video should be paused, `false` to resume it.
*
* @return {this} This Video Game Object for method chaining.
*/
setPaused: function(value) {
if (value === void 0) {
value = true;
}
var video = this.video;
this._codePaused = value;
if (video && !video.ended) {
if (value) {
if (!video.paused) {
this.removeEventHandlers();
video.pause();
}
} else if (!value) {
if (!this._playCalled) {
this.play();
} else if (video.paused && !this._systemPaused) {
this.createPlayPromise();
}
}
}
return this;
},
/**
* Pauses the current Video, if one is playing.
*
* If no video is loaded, this method does nothing.
*
* Call `Video.resume` to resume playback.
*
* @method Phaser.GameObjects.Video#pause
* @since 3.60.0
*
* @return {this} This Video Game Object for method chaining.
*/
pause: function() {
return this.setPaused(true);
},
/**
* Resumes the current Video, if one was previously playing and has been paused.
*
* If no video is loaded, this method does nothing.
*
* Call `Video.pause` to pause playback.
*
* @method Phaser.GameObjects.Video#resume
* @since 3.60.0
*
* @return {this} This Video Game Object for method chaining.
*/
resume: function() {
return this.setPaused(false);
},
/**
* Returns a double indicating the audio volume, from 0.0 (silent) to 1.0 (loudest).
*
* @method Phaser.GameObjects.Video#getVolume
* @since 3.20.0
*
* @return {number} A double indicating the audio volume, from 0.0 (silent) to 1.0 (loudest).
*/
getVolume: function() {
return this.video ? this.video.volume : 1;
},
/**
* Sets the volume of the currently playing video.
*
* The value given is a double indicating the audio volume, from 0.0 (silent) to 1.0 (loudest).
*
* @method Phaser.GameObjects.Video#setVolume
* @since 3.20.0
*
* @param {number} [value=1] - A double indicating the audio volume, from 0.0 (silent) to 1.0 (loudest).
*
* @return {this} This Video Game Object for method chaining.
*/
setVolume: function(value) {
if (value === void 0) {
value = 1;
}
if (this.video) {
this.video.volume = Clamp(value, 0, 1);
}
return this;
},
/**
* Returns a double that indicates the rate at which the media is being played back.
*
* @method Phaser.GameObjects.Video#getPlaybackRate
* @since 3.20.0
*
* @return {number} A double that indicates the rate at which the media is being played back.
*/
getPlaybackRate: function() {
return this.video ? this.video.playbackRate : 1;
},
/**
* Sets the playback rate of the current video.
*
* The value given is a double that indicates the rate at which the media is being played back.
*
* @method Phaser.GameObjects.Video#setPlaybackRate
* @since 3.20.0
*
* @param {number} [rate] - A double that indicates the rate at which the media is being played back.
*
* @return {this} This Video Game Object for method chaining.
*/
setPlaybackRate: function(rate) {
if (this.video) {
this.video.playbackRate = rate;
}
return this;
},
/**
* Returns a boolean which indicates whether the media element should start over when it reaches the end.
*
* @method Phaser.GameObjects.Video#getLoop
* @since 3.20.0
*
* @return {boolean} A boolean which indicates whether the media element will start over when it reaches the end.
*/
getLoop: function() {
return this.video ? this.video.loop : false;
},
/**
* Sets the loop state of the current video.
*
* The value given is a boolean which indicates whether the media element will start over when it reaches the end.
*
* Not all videos can loop, for example live streams.
*
* Please note that not all browsers support _seamless_ video looping for all encoding formats.
*
* @method Phaser.GameObjects.Video#setLoop
* @since 3.20.0
*
* @param {boolean} [value=true] - A boolean which indicates whether the media element will start over when it reaches the end.
*
* @return {this} This Video Game Object for method chaining.
*/
setLoop: function(value) {
if (value === void 0) {
value = true;
}
if (this.video) {
this.video.loop = value;
}
return this;
},
/**
* Returns a boolean which indicates whether the video is currently playing.
*
* @method Phaser.GameObjects.Video#isPlaying
* @since 3.20.0
*
* @return {boolean} A boolean which indicates whether the video is playing, or not.
*/
isPlaying: function() {
return this.video ? !(this.video.paused || this.video.ended) : false;
},
/**
* Returns a boolean which indicates whether the video is currently paused.
*
* @method Phaser.GameObjects.Video#isPaused
* @since 3.20.0
*
* @return {boolean} A boolean which indicates whether the video is paused, or not.
*/
isPaused: function() {
return this.video && this._playCalled && this.video.paused || this._codePaused || this._systemPaused;
},
/**
* Stores this Video in the Texture Manager using the given key as a dynamic texture,
* which any texture-based Game Object, such as a Sprite, can use as its source:
*
* ```javascript
* const vid = this.add.video(0, 0, 'intro');
*
* vid.play();
*
* vid.saveTexture('doodle');
*
* this.add.image(400, 300, 'doodle');
* ```
*
* If the video is not yet playing then you need to listen for the `TEXTURE_READY` event before
* you can use this texture on a Game Object:
*
* ```javascript
* const vid = this.add.video(0, 0, 'intro');
*
* vid.play();
*
* vid.once('textureready', (video, texture, key) => {
*
* this.add.image(400, 300, key);
*
* });
*
* vid.saveTexture('doodle');
* ```
*
* The saved texture is automatically updated as the video plays. If you pause this video,
* or change its source, then the saved texture updates instantly.
*
* Calling `saveTexture` again will not save another copy of the same texture, it will just rename the existing one.
*
* By default it will create a single base texture. You can add frames to the texture
* by using the `Texture.add` method. After doing this, you can then allow Game Objects
* to use a specific frame.
*
* If you intend to save the texture so you can use it as the input for a Shader, you may need to set the
* `flipY` parameter to `true` if you find the video renders upside down in your shader.
*
* @method Phaser.GameObjects.Video#saveTexture
* @since 3.20.0
*
* @param {string} key - The unique key to store the texture as within the global Texture Manager.
* @param {boolean} [flipY=false] - Should the WebGL Texture set `UNPACK_MULTIPLY_FLIP_Y` during upload?
*
* @return {boolean} Returns `true` if the texture is available immediately, otherwise returns `false` and you should listen for the `TEXTURE_READY` event.
*/
saveTexture: function(key, flipY) {
if (flipY === void 0) {
flipY = false;
}
if (this.videoTexture) {
this.scene.sys.textures.renameTexture(this._key, key);
this.videoTextureSource.setFlipY(flipY);
}
this._key = key;
this.flipY = flipY;
return this.videoTexture ? true : false;
},
/**
* Stops the video playing and clears all internal event listeners.
*
* If you only wish to pause playback of the video, and resume it a later time, use the `Video.pause` method instead.
*
* If the video hasn't finished downloading, calling this method will not abort the download. To do that you need to
* call `destroy` instead.
*
* @method Phaser.GameObjects.Video#stop
* @fires Phaser.GameObjects.Events#VIDEO_STOP
* @since 3.20.0
*
* @param {boolean} [emitStopEvent=true] - Should the `VIDEO_STOP` event be emitted?
*
* @return {this} This Video Game Object for method chaining.
*/
stop: function(emitStopEvent) {
if (emitStopEvent === void 0) {
emitStopEvent = true;
}
var video = this.video;
if (video) {
this.removeEventHandlers();
video.cancelVideoFrameCallback(this._rfvCallbackId);
video.pause();
}
this.retry = 0;
this._playCalled = false;
if (emitStopEvent) {
this.emit(Events.VIDEO_STOP, this);
}
return this;
},
/**
* Removes the Video element from the DOM by calling parentNode.removeChild on itself.
*
* Also removes the autoplay and src attributes and nulls the `Video.video` reference.
*
* If you loaded an external video via `Video.loadURL` then you should call this function
* to clear up once you are done with the instance, but don't want to destroy this
* Video Game Object.
*
* This method is called automatically by `Video.destroy`.
*
* @method Phaser.GameObjects.Video#removeVideoElement
* @since 3.20.0
*/
removeVideoElement: function() {
var video = this.video;
if (!video) {
return;
}
if (video.parentNode) {
video.parentNode.removeChild(video);
}
while (video.hasChildNodes()) {
video.removeChild(video.firstChild);
}
video.removeAttribute("autoplay");
video.removeAttribute("src");
this.video = null;
},
/**
* Handles the pre-destroy step for the Video object.
*
* This calls `Video.stop` and optionally `Video.removeVideoElement`.
*
* If any Sprites are using this Video as their texture it is up to you to manage those.
*
* @method Phaser.GameObjects.Video#preDestroy
* @private
* @since 3.21.0
*/
preDestroy: function() {
this.stop(false);
this.removeLoadEventHandlers();
this.removeVideoElement();
var game = this.scene.sys.game.events;
game.off(GameEvents.PAUSE, this.globalPause, this);
game.off(GameEvents.RESUME, this.globalResume, this);
var sound = this.scene.sys.sound;
if (sound) {
sound.off(SoundEvents.GLOBAL_MUTE, this.globalMute, this);
}
}
});
module2.exports = Video;
}
),
/***/
58352: (
/***/
(module2) => {
var VideoCanvasRenderer = function(renderer, src, camera, parentMatrix) {
if (src.videoTexture) {
camera.addToRenderList(src);
renderer.batchSprite(src, src.frame, camera, parentMatrix);
}
};
module2.exports = VideoCanvasRenderer;
}
),
/***/
11511: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var BuildGameObject = __webpack_require__2(25305);
var GameObjectCreator = __webpack_require__2(44603);
var GetAdvancedValue = __webpack_require__2(23568);
var Video = __webpack_require__2(18471);
GameObjectCreator.register("video", function(config, addToScene) {
if (config === void 0) {
config = {};
}
var key = GetAdvancedValue(config, "key", null);
var video = new Video(this.scene, 0, 0, key);
if (addToScene !== void 0) {
config.add = addToScene;
}
BuildGameObject(this.scene, video, config);
return video;
});
}
),
/***/
89025: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var Video = __webpack_require__2(18471);
var GameObjectFactory = __webpack_require__2(39429);
GameObjectFactory.register("video", function(x, y, key) {
return this.displayList.add(new Video(this.scene, x, y, key));
});
}
),
/***/
10247: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(29849);
}
if (true) {
renderCanvas = __webpack_require__2(58352);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
29849: (
/***/
(module2) => {
var VideoWebGLRenderer = function(renderer, src, camera, parentMatrix) {
if (src.videoTexture) {
camera.addToRenderList(src);
src.pipeline.batchSprite(src, camera, parentMatrix);
}
};
module2.exports = VideoWebGLRenderer;
}
),
/***/
41481: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BlendModes = __webpack_require__2(10312);
var Circle = __webpack_require__2(96503);
var CircleContains = __webpack_require__2(87902);
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31401);
var GameObject = __webpack_require__2(95643);
var Rectangle = __webpack_require__2(87841);
var RectangleContains = __webpack_require__2(37303);
var Zone = new Class({
Extends: GameObject,
Mixins: [
Components.Depth,
Components.GetBounds,
Components.Origin,
Components.Transform,
Components.ScrollFactor,
Components.Visible
],
initialize: function Zone2(scene, x, y, width, height) {
if (width === void 0) {
width = 1;
}
if (height === void 0) {
height = width;
}
GameObject.call(this, scene, "Zone");
this.setPosition(x, y);
this.width = width;
this.height = height;
this.blendMode = BlendModes.NORMAL;
this.updateDisplayOrigin();
},
/**
* The displayed width of this Game Object.
* This value takes into account the scale factor.
*
* @name Phaser.GameObjects.Zone#displayWidth
* @type {number}
* @since 3.0.0
*/
displayWidth: {
get: function() {
return this.scaleX * this.width;
},
set: function(value) {
this.scaleX = value / this.width;
}
},
/**
* The displayed height of this Game Object.
* This value takes into account the scale factor.
*
* @name Phaser.GameObjects.Zone#displayHeight
* @type {number}
* @since 3.0.0
*/
displayHeight: {
get: function() {
return this.scaleY * this.height;
},
set: function(value) {
this.scaleY = value / this.height;
}
},
/**
* Sets the size of this Game Object.
*
* @method Phaser.GameObjects.Zone#setSize
* @since 3.0.0
*
* @param {number} width - The width of this Game Object.
* @param {number} height - The height of this Game Object.
* @param {boolean} [resizeInput=true] - If this Zone has a Rectangle for a hit area this argument will resize the hit area as well.
*
* @return {this} This Game Object.
*/
setSize: function(width, height, resizeInput) {
if (resizeInput === void 0) {
resizeInput = true;
}
this.width = width;
this.height = height;
this.updateDisplayOrigin();
var input = this.input;
if (resizeInput && input && !input.customHitArea) {
input.hitArea.width = width;
input.hitArea.height = height;
}
return this;
},
/**
* Sets the display size of this Game Object.
* Calling this will adjust the scale.
*
* @method Phaser.GameObjects.Zone#setDisplaySize
* @since 3.0.0
*
* @param {number} width - The width of this Game Object.
* @param {number} height - The height of this Game Object.
*
* @return {this} This Game Object.
*/
setDisplaySize: function(width, height) {
this.displayWidth = width;
this.displayHeight = height;
return this;
},
/**
* Sets this Zone to be a Circular Drop Zone.
* The circle is centered on this Zones `x` and `y` coordinates.
*
* @method Phaser.GameObjects.Zone#setCircleDropZone
* @since 3.0.0
*
* @param {number} radius - The radius of the Circle that will form the Drop Zone.
*
* @return {this} This Game Object.
*/
setCircleDropZone: function(radius) {
return this.setDropZone(new Circle(0, 0, radius), CircleContains);
},
/**
* Sets this Zone to be a Rectangle Drop Zone.
* The rectangle is centered on this Zones `x` and `y` coordinates.
*
* @method Phaser.GameObjects.Zone#setRectangleDropZone
* @since 3.0.0
*
* @param {number} width - The width of the rectangle drop zone.
* @param {number} height - The height of the rectangle drop zone.
*
* @return {this} This Game Object.
*/
setRectangleDropZone: function(width, height) {
return this.setDropZone(new Rectangle(0, 0, width, height), RectangleContains);
},
/**
* Allows you to define your own Geometry shape to be used as a Drop Zone.
*
* @method Phaser.GameObjects.Zone#setDropZone
* @since 3.0.0
*
* @param {object} [hitArea] - A Geometry shape instance, such as Phaser.Geom.Ellipse, or your own custom shape. If not given it will try to create a Rectangle based on the size of this zone.
* @param {Phaser.Types.Input.HitAreaCallback} [hitAreaCallback] - A function that will return `true` if the given x/y coords it is sent are within the shape. If you provide a shape you must also provide a callback.
*
* @return {this} This Game Object.
*/
setDropZone: function(hitArea, hitAreaCallback) {
if (!this.input) {
this.setInteractive(hitArea, hitAreaCallback, true);
}
return this;
},
/**
* A NOOP method so you can pass a Zone to a Container.
* Calling this method will do nothing. It is intentionally empty.
*
* @method Phaser.GameObjects.Zone#setAlpha
* @private
* @since 3.11.0
*/
setAlpha: function() {
},
/**
* A NOOP method so you can pass a Zone to a Container in Canvas.
* Calling this method will do nothing. It is intentionally empty.
*
* @method Phaser.GameObjects.Zone#setBlendMode
* @private
* @since 3.16.2
*/
setBlendMode: function() {
},
/**
* A Zone does not render.
*
* @method Phaser.GameObjects.Zone#renderCanvas
* @private
* @since 3.53.0
*
* @param {Phaser.Renderer.Canvas.CanvasRenderer} renderer - A reference to the current active Canvas renderer.
* @param {Phaser.GameObjects.Image} src - The Game Object being rendered in this call.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
* @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
*/
renderCanvas: function(renderer, src, camera) {
camera.addToRenderList(src);
},
/**
* A Zone does not render.
*
* @method Phaser.GameObjects.Zone#renderWebGL
* @private
* @since 3.53.0
*
* @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer.
* @param {Phaser.GameObjects.Image} src - The Game Object being rendered in this call.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
* @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
*/
renderWebGL: function(renderer, src, camera) {
camera.addToRenderList(src);
}
});
module2.exports = Zone;
}
),
/***/
95261: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var GameObjectCreator = __webpack_require__2(44603);
var GetAdvancedValue = __webpack_require__2(23568);
var Zone = __webpack_require__2(41481);
GameObjectCreator.register("zone", function(config) {
var x = GetAdvancedValue(config, "x", 0);
var y = GetAdvancedValue(config, "y", 0);
var width = GetAdvancedValue(config, "width", 1);
var height = GetAdvancedValue(config, "height", width);
return new Zone(this.scene, x, y, width, height);
});
}
),
/***/
84175: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var Zone = __webpack_require__2(41481);
var GameObjectFactory = __webpack_require__2(39429);
GameObjectFactory.register("zone", function(x, y, width, height) {
return this.displayList.add(new Zone(this.scene, x, y, width, height));
});
}
),
/***/
95166: (
/***/
(module2) => {
var Area = function(circle) {
return circle.radius > 0 ? Math.PI * circle.radius * circle.radius : 0;
};
module2.exports = Area;
}
),
/***/
96503: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Contains = __webpack_require__2(87902);
var GetPoint = __webpack_require__2(26241);
var GetPoints = __webpack_require__2(79124);
var GEOM_CONST = __webpack_require__2(23777);
var Random = __webpack_require__2(28176);
var Circle = new Class({
initialize: function Circle2(x, y, radius) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (radius === void 0) {
radius = 0;
}
this.type = GEOM_CONST.CIRCLE;
this.x = x;
this.y = y;
this._radius = radius;
this._diameter = radius * 2;
},
/**
* Check to see if the Circle contains the given x / y coordinates.
*
* @method Phaser.Geom.Circle#contains
* @since 3.0.0
*
* @param {number} x - The x coordinate to check within the circle.
* @param {number} y - The y coordinate to check within the circle.
*
* @return {boolean} True if the coordinates are within the circle, otherwise false.
*/
contains: function(x, y) {
return Contains(this, x, y);
},
/**
* Returns a Point object containing the coordinates of a point on the circumference of the Circle
* based on the given angle normalized to the range 0 to 1. I.e. a value of 0.5 will give the point
* at 180 degrees around the circle.
*
* @method Phaser.Geom.Circle#getPoint
* @since 3.0.0
*
* @generic {Phaser.Geom.Point} O - [out,$return]
*
* @param {number} position - A value between 0 and 1, where 0 equals 0 degrees, 0.5 equals 180 degrees and 1 equals 360 around the circle.
* @param {(Phaser.Geom.Point|object)} [out] - An object to store the return values in. If not given a Point object will be created.
*
* @return {(Phaser.Geom.Point|object)} A Point, or point-like object, containing the coordinates of the point around the circle.
*/
getPoint: function(position, point) {
return GetPoint(this, position, point);
},
/**
* Returns an array of Point objects containing the coordinates of the points around the circumference of the Circle,
* based on the given quantity or stepRate values.
*
* @method Phaser.Geom.Circle#getPoints
* @since 3.0.0
*
* @generic {Phaser.Geom.Point[]} O - [output,$return]
*
* @param {number} quantity - The amount of points to return. If a falsey value the quantity will be derived from the `stepRate` instead.
* @param {number} [stepRate] - Sets the quantity by getting the circumference of the circle and dividing it by the stepRate.
* @param {(array|Phaser.Geom.Point[])} [output] - An array to insert the points in to. If not provided a new array will be created.
*
* @return {(array|Phaser.Geom.Point[])} An array of Point objects pertaining to the points around the circumference of the circle.
*/
getPoints: function(quantity, stepRate, output) {
return GetPoints(this, quantity, stepRate, output);
},
/**
* Returns a uniformly distributed random point from anywhere within the Circle.
*
* @method Phaser.Geom.Circle#getRandomPoint
* @since 3.0.0
*
* @generic {Phaser.Geom.Point} O - [point,$return]
*
* @param {(Phaser.Geom.Point|object)} [point] - A Point or point-like object to set the random `x` and `y` values in.
*
* @return {(Phaser.Geom.Point|object)} A Point object with the random values set in the `x` and `y` properties.
*/
getRandomPoint: function(point) {
return Random(this, point);
},
/**
* Sets the x, y and radius of this circle.
*
* @method Phaser.Geom.Circle#setTo
* @since 3.0.0
*
* @param {number} [x=0] - The x position of the center of the circle.
* @param {number} [y=0] - The y position of the center of the circle.
* @param {number} [radius=0] - The radius of the circle.
*
* @return {this} This Circle object.
*/
setTo: function(x, y, radius) {
this.x = x;
this.y = y;
this._radius = radius;
this._diameter = radius * 2;
return this;
},
/**
* Sets this Circle to be empty with a radius of zero.
* Does not change its position.
*
* @method Phaser.Geom.Circle#setEmpty
* @since 3.0.0
*
* @return {this} This Circle object.
*/
setEmpty: function() {
this._radius = 0;
this._diameter = 0;
return this;
},
/**
* Sets the position of this Circle.
*
* @method Phaser.Geom.Circle#setPosition
* @since 3.0.0
*
* @param {number} [x=0] - The x position of the center of the circle.
* @param {number} [y=0] - The y position of the center of the circle.
*
* @return {this} This Circle object.
*/
setPosition: function(x, y) {
if (y === void 0) {
y = x;
}
this.x = x;
this.y = y;
return this;
},
/**
* Checks to see if the Circle is empty: has a radius of zero.
*
* @method Phaser.Geom.Circle#isEmpty
* @since 3.0.0
*
* @return {boolean} True if the Circle is empty, otherwise false.
*/
isEmpty: function() {
return this._radius <= 0;
},
/**
* The radius of the Circle.
*
* @name Phaser.Geom.Circle#radius
* @type {number}
* @since 3.0.0
*/
radius: {
get: function() {
return this._radius;
},
set: function(value) {
this._radius = value;
this._diameter = value * 2;
}
},
/**
* The diameter of the Circle.
*
* @name Phaser.Geom.Circle#diameter
* @type {number}
* @since 3.0.0
*/
diameter: {
get: function() {
return this._diameter;
},
set: function(value) {
this._diameter = value;
this._radius = value * 0.5;
}
},
/**
* The left position of the Circle.
*
* @name Phaser.Geom.Circle#left
* @type {number}
* @since 3.0.0
*/
left: {
get: function() {
return this.x - this._radius;
},
set: function(value) {
this.x = value + this._radius;
}
},
/**
* The right position of the Circle.
*
* @name Phaser.Geom.Circle#right
* @type {number}
* @since 3.0.0
*/
right: {
get: function() {
return this.x + this._radius;
},
set: function(value) {
this.x = value - this._radius;
}
},
/**
* The top position of the Circle.
*
* @name Phaser.Geom.Circle#top
* @type {number}
* @since 3.0.0
*/
top: {
get: function() {
return this.y - this._radius;
},
set: function(value) {
this.y = value + this._radius;
}
},
/**
* The bottom position of the Circle.
*
* @name Phaser.Geom.Circle#bottom
* @type {number}
* @since 3.0.0
*/
bottom: {
get: function() {
return this.y + this._radius;
},
set: function(value) {
this.y = value - this._radius;
}
}
});
module2.exports = Circle;
}
),
/***/
71562: (
/***/
(module2) => {
var Circumference = function(circle) {
return 2 * (Math.PI * circle.radius);
};
module2.exports = Circumference;
}
),
/***/
92110: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
var CircumferencePoint = function(circle, angle, out) {
if (out === void 0) {
out = new Point();
}
out.x = circle.x + circle.radius * Math.cos(angle);
out.y = circle.y + circle.radius * Math.sin(angle);
return out;
};
module2.exports = CircumferencePoint;
}
),
/***/
42250: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Circle = __webpack_require__2(96503);
var Clone = function(source) {
return new Circle(source.x, source.y, source.radius);
};
module2.exports = Clone;
}
),
/***/
87902: (
/***/
(module2) => {
var Contains = function(circle, x, y) {
if (circle.radius > 0 && x >= circle.left && x <= circle.right && y >= circle.top && y <= circle.bottom) {
var dx = (circle.x - x) * (circle.x - x);
var dy = (circle.y - y) * (circle.y - y);
return dx + dy <= circle.radius * circle.radius;
} else {
return false;
}
};
module2.exports = Contains;
}
),
/***/
5698: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Contains = __webpack_require__2(87902);
var ContainsPoint = function(circle, point) {
return Contains(circle, point.x, point.y);
};
module2.exports = ContainsPoint;
}
),
/***/
70588: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Contains = __webpack_require__2(87902);
var ContainsRect = function(circle, rect) {
return Contains(circle, rect.x, rect.y) && Contains(circle, rect.right, rect.y) && Contains(circle, rect.x, rect.bottom) && Contains(circle, rect.right, rect.bottom);
};
module2.exports = ContainsRect;
}
),
/***/
26394: (
/***/
(module2) => {
var CopyFrom = function(source, dest) {
return dest.setTo(source.x, source.y, source.radius);
};
module2.exports = CopyFrom;
}
),
/***/
76278: (
/***/
(module2) => {
var Equals = function(circle, toCompare) {
return circle.x === toCompare.x && circle.y === toCompare.y && circle.radius === toCompare.radius;
};
module2.exports = Equals;
}
),
/***/
2074: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Rectangle = __webpack_require__2(87841);
var GetBounds = function(circle, out) {
if (out === void 0) {
out = new Rectangle();
}
out.x = circle.left;
out.y = circle.top;
out.width = circle.diameter;
out.height = circle.diameter;
return out;
};
module2.exports = GetBounds;
}
),
/***/
26241: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CircumferencePoint = __webpack_require__2(92110);
var FromPercent = __webpack_require__2(62945);
var MATH_CONST = __webpack_require__2(36383);
var Point = __webpack_require__2(2141);
var GetPoint = function(circle, position, out) {
if (out === void 0) {
out = new Point();
}
var angle = FromPercent(position, 0, MATH_CONST.PI2);
return CircumferencePoint(circle, angle, out);
};
module2.exports = GetPoint;
}
),
/***/
79124: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Circumference = __webpack_require__2(71562);
var CircumferencePoint = __webpack_require__2(92110);
var FromPercent = __webpack_require__2(62945);
var MATH_CONST = __webpack_require__2(36383);
var GetPoints = function(circle, quantity, stepRate, out) {
if (out === void 0) {
out = [];
}
if (!quantity && stepRate > 0) {
quantity = Circumference(circle) / stepRate;
}
for (var i = 0; i < quantity; i++) {
var angle = FromPercent(i / quantity, 0, MATH_CONST.PI2);
out.push(CircumferencePoint(circle, angle));
}
return out;
};
module2.exports = GetPoints;
}
),
/***/
50884: (
/***/
(module2) => {
var Offset = function(circle, x, y) {
circle.x += x;
circle.y += y;
return circle;
};
module2.exports = Offset;
}
),
/***/
39212: (
/***/
(module2) => {
var OffsetPoint = function(circle, point) {
circle.x += point.x;
circle.y += point.y;
return circle;
};
module2.exports = OffsetPoint;
}
),
/***/
28176: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
var Random = function(circle, out) {
if (out === void 0) {
out = new Point();
}
var t = 2 * Math.PI * Math.random();
var u = Math.random() + Math.random();
var r = u > 1 ? 2 - u : u;
var x = r * Math.cos(t);
var y = r * Math.sin(t);
out.x = circle.x + x * circle.radius;
out.y = circle.y + y * circle.radius;
return out;
};
module2.exports = Random;
}
),
/***/
88911: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Circle = __webpack_require__2(96503);
Circle.Area = __webpack_require__2(95166);
Circle.Circumference = __webpack_require__2(71562);
Circle.CircumferencePoint = __webpack_require__2(92110);
Circle.Clone = __webpack_require__2(42250);
Circle.Contains = __webpack_require__2(87902);
Circle.ContainsPoint = __webpack_require__2(5698);
Circle.ContainsRect = __webpack_require__2(70588);
Circle.CopyFrom = __webpack_require__2(26394);
Circle.Equals = __webpack_require__2(76278);
Circle.GetBounds = __webpack_require__2(2074);
Circle.GetPoint = __webpack_require__2(26241);
Circle.GetPoints = __webpack_require__2(79124);
Circle.Offset = __webpack_require__2(50884);
Circle.OffsetPoint = __webpack_require__2(39212);
Circle.Random = __webpack_require__2(28176);
module2.exports = Circle;
}
),
/***/
23777: (
/***/
(module2) => {
var GEOM_CONST = {
/**
* A Circle Geometry object type.
*
* @name Phaser.Geom.CIRCLE
* @type {number}
* @since 3.19.0
*/
CIRCLE: 0,
/**
* An Ellipse Geometry object type.
*
* @name Phaser.Geom.ELLIPSE
* @type {number}
* @since 3.19.0
*/
ELLIPSE: 1,
/**
* A Line Geometry object type.
*
* @name Phaser.Geom.LINE
* @type {number}
* @since 3.19.0
*/
LINE: 2,
/**
* A Point Geometry object type.
*
* @name Phaser.Geom.POINT
* @type {number}
* @since 3.19.0
*/
POINT: 3,
/**
* A Polygon Geometry object type.
*
* @name Phaser.Geom.POLYGON
* @type {number}
* @since 3.19.0
*/
POLYGON: 4,
/**
* A Rectangle Geometry object type.
*
* @name Phaser.Geom.RECTANGLE
* @type {number}
* @since 3.19.0
*/
RECTANGLE: 5,
/**
* A Triangle Geometry object type.
*
* @name Phaser.Geom.TRIANGLE
* @type {number}
* @since 3.19.0
*/
TRIANGLE: 6
};
module2.exports = GEOM_CONST;
}
),
/***/
78874: (
/***/
(module2) => {
var Area = function(ellipse) {
if (ellipse.isEmpty()) {
return 0;
}
return ellipse.getMajorRadius() * ellipse.getMinorRadius() * Math.PI;
};
module2.exports = Area;
}
),
/***/
92990: (
/***/
(module2) => {
var Circumference = function(ellipse) {
var rx = ellipse.width / 2;
var ry = ellipse.height / 2;
var h = Math.pow(rx - ry, 2) / Math.pow(rx + ry, 2);
return Math.PI * (rx + ry) * (1 + 3 * h / (10 + Math.sqrt(4 - 3 * h)));
};
module2.exports = Circumference;
}
),
/***/
79522: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
var CircumferencePoint = function(ellipse, angle, out) {
if (out === void 0) {
out = new Point();
}
var halfWidth = ellipse.width / 2;
var halfHeight = ellipse.height / 2;
out.x = ellipse.x + halfWidth * Math.cos(angle);
out.y = ellipse.y + halfHeight * Math.sin(angle);
return out;
};
module2.exports = CircumferencePoint;
}
),
/***/
58102: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Ellipse = __webpack_require__2(8497);
var Clone = function(source) {
return new Ellipse(source.x, source.y, source.width, source.height);
};
module2.exports = Clone;
}
),
/***/
81154: (
/***/
(module2) => {
var Contains = function(ellipse, x, y) {
if (ellipse.width <= 0 || ellipse.height <= 0) {
return false;
}
var normx = (x - ellipse.x) / ellipse.width;
var normy = (y - ellipse.y) / ellipse.height;
normx *= normx;
normy *= normy;
return normx + normy < 0.25;
};
module2.exports = Contains;
}
),
/***/
46662: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Contains = __webpack_require__2(81154);
var ContainsPoint = function(ellipse, point) {
return Contains(ellipse, point.x, point.y);
};
module2.exports = ContainsPoint;
}
),
/***/
1632: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Contains = __webpack_require__2(81154);
var ContainsRect = function(ellipse, rect) {
return Contains(ellipse, rect.x, rect.y) && Contains(ellipse, rect.right, rect.y) && Contains(ellipse, rect.x, rect.bottom) && Contains(ellipse, rect.right, rect.bottom);
};
module2.exports = ContainsRect;
}
),
/***/
65534: (
/***/
(module2) => {
var CopyFrom = function(source, dest) {
return dest.setTo(source.x, source.y, source.width, source.height);
};
module2.exports = CopyFrom;
}
),
/***/
8497: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Contains = __webpack_require__2(81154);
var GetPoint = __webpack_require__2(90549);
var GetPoints = __webpack_require__2(48320);
var GEOM_CONST = __webpack_require__2(23777);
var Random = __webpack_require__2(24820);
var Ellipse = new Class({
initialize: function Ellipse2(x, y, width, height) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (width === void 0) {
width = 0;
}
if (height === void 0) {
height = 0;
}
this.type = GEOM_CONST.ELLIPSE;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
},
/**
* Check to see if the Ellipse contains the given x / y coordinates.
*
* @method Phaser.Geom.Ellipse#contains
* @since 3.0.0
*
* @param {number} x - The x coordinate to check within the ellipse.
* @param {number} y - The y coordinate to check within the ellipse.
*
* @return {boolean} True if the coordinates are within the ellipse, otherwise false.
*/
contains: function(x, y) {
return Contains(this, x, y);
},
/**
* Returns a Point object containing the coordinates of a point on the circumference of the Ellipse
* based on the given angle normalized to the range 0 to 1. I.e. a value of 0.5 will give the point
* at 180 degrees around the circle.
*
* @method Phaser.Geom.Ellipse#getPoint
* @since 3.0.0
*
* @generic {Phaser.Geom.Point} O - [out,$return]
*
* @param {number} position - A value between 0 and 1, where 0 equals 0 degrees, 0.5 equals 180 degrees and 1 equals 360 around the ellipse.
* @param {(Phaser.Geom.Point|object)} [out] - An object to store the return values in. If not given a Point object will be created.
*
* @return {(Phaser.Geom.Point|object)} A Point, or point-like object, containing the coordinates of the point around the ellipse.
*/
getPoint: function(position, point) {
return GetPoint(this, position, point);
},
/**
* Returns an array of Point objects containing the coordinates of the points around the circumference of the Ellipse,
* based on the given quantity or stepRate values.
*
* @method Phaser.Geom.Ellipse#getPoints
* @since 3.0.0
*
* @generic {Phaser.Geom.Point[]} O - [output,$return]
*
* @param {number} quantity - The amount of points to return. If a falsey value the quantity will be derived from the `stepRate` instead.
* @param {number} [stepRate] - Sets the quantity by getting the circumference of the ellipse and dividing it by the stepRate.
* @param {(array|Phaser.Geom.Point[])} [output] - An array to insert the points in to. If not provided a new array will be created.
*
* @return {(array|Phaser.Geom.Point[])} An array of Point objects pertaining to the points around the circumference of the ellipse.
*/
getPoints: function(quantity, stepRate, output) {
return GetPoints(this, quantity, stepRate, output);
},
/**
* Returns a uniformly distributed random point from anywhere within the given Ellipse.
*
* @method Phaser.Geom.Ellipse#getRandomPoint
* @since 3.0.0
*
* @generic {Phaser.Geom.Point} O - [point,$return]
*
* @param {(Phaser.Geom.Point|object)} [point] - A Point or point-like object to set the random `x` and `y` values in.
*
* @return {(Phaser.Geom.Point|object)} A Point object with the random values set in the `x` and `y` properties.
*/
getRandomPoint: function(point) {
return Random(this, point);
},
/**
* Sets the x, y, width and height of this ellipse.
*
* @method Phaser.Geom.Ellipse#setTo
* @since 3.0.0
*
* @param {number} x - The x position of the center of the ellipse.
* @param {number} y - The y position of the center of the ellipse.
* @param {number} width - The width of the ellipse.
* @param {number} height - The height of the ellipse.
*
* @return {this} This Ellipse object.
*/
setTo: function(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
return this;
},
/**
* Sets this Ellipse to be empty with a width and height of zero.
* Does not change its position.
*
* @method Phaser.Geom.Ellipse#setEmpty
* @since 3.0.0
*
* @return {this} This Ellipse object.
*/
setEmpty: function() {
this.width = 0;
this.height = 0;
return this;
},
/**
* Sets the position of this Ellipse.
*
* @method Phaser.Geom.Ellipse#setPosition
* @since 3.0.0
*
* @param {number} x - The x position of the center of the ellipse.
* @param {number} y - The y position of the center of the ellipse.
*
* @return {this} This Ellipse object.
*/
setPosition: function(x, y) {
if (y === void 0) {
y = x;
}
this.x = x;
this.y = y;
return this;
},
/**
* Sets the size of this Ellipse.
* Does not change its position.
*
* @method Phaser.Geom.Ellipse#setSize
* @since 3.0.0
*
* @param {number} width - The width of the ellipse.
* @param {number} [height=width] - The height of the ellipse.
*
* @return {this} This Ellipse object.
*/
setSize: function(width, height) {
if (height === void 0) {
height = width;
}
this.width = width;
this.height = height;
return this;
},
/**
* Checks to see if the Ellipse is empty: has a width or height equal to zero.
*
* @method Phaser.Geom.Ellipse#isEmpty
* @since 3.0.0
*
* @return {boolean} True if the Ellipse is empty, otherwise false.
*/
isEmpty: function() {
return this.width <= 0 || this.height <= 0;
},
/**
* Returns the minor radius of the ellipse. Also known as the Semi Minor Axis.
*
* @method Phaser.Geom.Ellipse#getMinorRadius
* @since 3.0.0
*
* @return {number} The minor radius.
*/
getMinorRadius: function() {
return Math.min(this.width, this.height) / 2;
},
/**
* Returns the major radius of the ellipse. Also known as the Semi Major Axis.
*
* @method Phaser.Geom.Ellipse#getMajorRadius
* @since 3.0.0
*
* @return {number} The major radius.
*/
getMajorRadius: function() {
return Math.max(this.width, this.height) / 2;
},
/**
* The left position of the Ellipse.
*
* @name Phaser.Geom.Ellipse#left
* @type {number}
* @since 3.0.0
*/
left: {
get: function() {
return this.x - this.width / 2;
},
set: function(value) {
this.x = value + this.width / 2;
}
},
/**
* The right position of the Ellipse.
*
* @name Phaser.Geom.Ellipse#right
* @type {number}
* @since 3.0.0
*/
right: {
get: function() {
return this.x + this.width / 2;
},
set: function(value) {
this.x = value - this.width / 2;
}
},
/**
* The top position of the Ellipse.
*
* @name Phaser.Geom.Ellipse#top
* @type {number}
* @since 3.0.0
*/
top: {
get: function() {
return this.y - this.height / 2;
},
set: function(value) {
this.y = value + this.height / 2;
}
},
/**
* The bottom position of the Ellipse.
*
* @name Phaser.Geom.Ellipse#bottom
* @type {number}
* @since 3.0.0
*/
bottom: {
get: function() {
return this.y + this.height / 2;
},
set: function(value) {
this.y = value - this.height / 2;
}
}
});
module2.exports = Ellipse;
}
),
/***/
36146: (
/***/
(module2) => {
var Equals = function(ellipse, toCompare) {
return ellipse.x === toCompare.x && ellipse.y === toCompare.y && ellipse.width === toCompare.width && ellipse.height === toCompare.height;
};
module2.exports = Equals;
}
),
/***/
23694: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Rectangle = __webpack_require__2(87841);
var GetBounds = function(ellipse, out) {
if (out === void 0) {
out = new Rectangle();
}
out.x = ellipse.left;
out.y = ellipse.top;
out.width = ellipse.width;
out.height = ellipse.height;
return out;
};
module2.exports = GetBounds;
}
),
/***/
90549: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CircumferencePoint = __webpack_require__2(79522);
var FromPercent = __webpack_require__2(62945);
var MATH_CONST = __webpack_require__2(36383);
var Point = __webpack_require__2(2141);
var GetPoint = function(ellipse, position, out) {
if (out === void 0) {
out = new Point();
}
var angle = FromPercent(position, 0, MATH_CONST.PI2);
return CircumferencePoint(ellipse, angle, out);
};
module2.exports = GetPoint;
}
),
/***/
48320: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Circumference = __webpack_require__2(92990);
var CircumferencePoint = __webpack_require__2(79522);
var FromPercent = __webpack_require__2(62945);
var MATH_CONST = __webpack_require__2(36383);
var GetPoints = function(ellipse, quantity, stepRate, out) {
if (out === void 0) {
out = [];
}
if (!quantity && stepRate > 0) {
quantity = Circumference(ellipse) / stepRate;
}
for (var i = 0; i < quantity; i++) {
var angle = FromPercent(i / quantity, 0, MATH_CONST.PI2);
out.push(CircumferencePoint(ellipse, angle));
}
return out;
};
module2.exports = GetPoints;
}
),
/***/
73424: (
/***/
(module2) => {
var Offset = function(ellipse, x, y) {
ellipse.x += x;
ellipse.y += y;
return ellipse;
};
module2.exports = Offset;
}
),
/***/
44808: (
/***/
(module2) => {
var OffsetPoint = function(ellipse, point) {
ellipse.x += point.x;
ellipse.y += point.y;
return ellipse;
};
module2.exports = OffsetPoint;
}
),
/***/
24820: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
var Random = function(ellipse, out) {
if (out === void 0) {
out = new Point();
}
var p = Math.random() * Math.PI * 2;
var s = Math.sqrt(Math.random());
out.x = ellipse.x + s * Math.cos(p) * ellipse.width / 2;
out.y = ellipse.y + s * Math.sin(p) * ellipse.height / 2;
return out;
};
module2.exports = Random;
}
),
/***/
49203: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Ellipse = __webpack_require__2(8497);
Ellipse.Area = __webpack_require__2(78874);
Ellipse.Circumference = __webpack_require__2(92990);
Ellipse.CircumferencePoint = __webpack_require__2(79522);
Ellipse.Clone = __webpack_require__2(58102);
Ellipse.Contains = __webpack_require__2(81154);
Ellipse.ContainsPoint = __webpack_require__2(46662);
Ellipse.ContainsRect = __webpack_require__2(1632);
Ellipse.CopyFrom = __webpack_require__2(65534);
Ellipse.Equals = __webpack_require__2(36146);
Ellipse.GetBounds = __webpack_require__2(23694);
Ellipse.GetPoint = __webpack_require__2(90549);
Ellipse.GetPoints = __webpack_require__2(48320);
Ellipse.Offset = __webpack_require__2(73424);
Ellipse.OffsetPoint = __webpack_require__2(44808);
Ellipse.Random = __webpack_require__2(24820);
module2.exports = Ellipse;
}
),
/***/
55738: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(23777);
var Extend = __webpack_require__2(79291);
var Geom = {
Circle: __webpack_require__2(88911),
Ellipse: __webpack_require__2(49203),
Intersects: __webpack_require__2(91865),
Line: __webpack_require__2(2529),
Mesh: __webpack_require__2(73090),
Point: __webpack_require__2(43711),
Polygon: __webpack_require__2(58423),
Rectangle: __webpack_require__2(93232),
Triangle: __webpack_require__2(84435)
};
Geom = Extend(false, Geom, CONST);
module2.exports = Geom;
}
),
/***/
2044: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var DistanceBetween = __webpack_require__2(20339);
var CircleToCircle = function(circleA, circleB) {
return DistanceBetween(circleA.x, circleA.y, circleB.x, circleB.y) <= circleA.radius + circleB.radius;
};
module2.exports = CircleToCircle;
}
),
/***/
81491: (
/***/
(module2) => {
var CircleToRectangle = function(circle, rect) {
var halfWidth = rect.width / 2;
var halfHeight = rect.height / 2;
var cx = Math.abs(circle.x - rect.x - halfWidth);
var cy = Math.abs(circle.y - rect.y - halfHeight);
var xDist = halfWidth + circle.radius;
var yDist = halfHeight + circle.radius;
if (cx > xDist || cy > yDist) {
return false;
} else if (cx <= halfWidth || cy <= halfHeight) {
return true;
} else {
var xCornerDist = cx - halfWidth;
var yCornerDist = cy - halfHeight;
var xCornerDistSq = xCornerDist * xCornerDist;
var yCornerDistSq = yCornerDist * yCornerDist;
var maxCornerDistSq = circle.radius * circle.radius;
return xCornerDistSq + yCornerDistSq <= maxCornerDistSq;
}
};
module2.exports = CircleToRectangle;
}
),
/***/
63376: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
var CircleToCircle = __webpack_require__2(2044);
var GetCircleToCircle = function(circleA, circleB, out) {
if (out === void 0) {
out = [];
}
if (CircleToCircle(circleA, circleB)) {
var x0 = circleA.x;
var y0 = circleA.y;
var r0 = circleA.radius;
var x1 = circleB.x;
var y1 = circleB.y;
var r1 = circleB.radius;
var coefficientA, coefficientB, coefficientC, lambda, x;
if (y0 === y1) {
x = (r1 * r1 - r0 * r0 - x1 * x1 + x0 * x0) / (2 * (x0 - x1));
coefficientA = 1;
coefficientB = -2 * y1;
coefficientC = x1 * x1 + x * x - 2 * x1 * x + y1 * y1 - r1 * r1;
lambda = coefficientB * coefficientB - 4 * coefficientA * coefficientC;
if (lambda === 0) {
out.push(new Point(x, -coefficientB / (2 * coefficientA)));
} else if (lambda > 0) {
out.push(new Point(x, (-coefficientB + Math.sqrt(lambda)) / (2 * coefficientA)));
out.push(new Point(x, (-coefficientB - Math.sqrt(lambda)) / (2 * coefficientA)));
}
} else {
var v1 = (x0 - x1) / (y0 - y1);
var n = (r1 * r1 - r0 * r0 - x1 * x1 + x0 * x0 - y1 * y1 + y0 * y0) / (2 * (y0 - y1));
coefficientA = v1 * v1 + 1;
coefficientB = 2 * y0 * v1 - 2 * n * v1 - 2 * x0;
coefficientC = x0 * x0 + y0 * y0 + n * n - r0 * r0 - 2 * y0 * n;
lambda = coefficientB * coefficientB - 4 * coefficientA * coefficientC;
if (lambda === 0) {
x = -coefficientB / (2 * coefficientA);
out.push(new Point(x, n - x * v1));
} else if (lambda > 0) {
x = (-coefficientB + Math.sqrt(lambda)) / (2 * coefficientA);
out.push(new Point(x, n - x * v1));
x = (-coefficientB - Math.sqrt(lambda)) / (2 * coefficientA);
out.push(new Point(x, n - x * v1));
}
}
}
return out;
};
module2.exports = GetCircleToCircle;
}
),
/***/
97439: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetLineToCircle = __webpack_require__2(4042);
var CircleToRectangle = __webpack_require__2(81491);
var GetCircleToRectangle = function(circle, rect, out) {
if (out === void 0) {
out = [];
}
if (CircleToRectangle(circle, rect)) {
var lineA = rect.getLineA();
var lineB = rect.getLineB();
var lineC = rect.getLineC();
var lineD = rect.getLineD();
GetLineToCircle(lineA, circle, out);
GetLineToCircle(lineB, circle, out);
GetLineToCircle(lineC, circle, out);
GetLineToCircle(lineD, circle, out);
}
return out;
};
module2.exports = GetCircleToRectangle;
}
),
/***/
4042: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
var LineToCircle = __webpack_require__2(80462);
var GetLineToCircle = function(line, circle, out) {
if (out === void 0) {
out = [];
}
if (LineToCircle(line, circle)) {
var lx1 = line.x1;
var ly1 = line.y1;
var lx2 = line.x2;
var ly2 = line.y2;
var cx = circle.x;
var cy = circle.y;
var cr = circle.radius;
var lDirX = lx2 - lx1;
var lDirY = ly2 - ly1;
var oDirX = lx1 - cx;
var oDirY = ly1 - cy;
var coefficientA = lDirX * lDirX + lDirY * lDirY;
var coefficientB = 2 * (lDirX * oDirX + lDirY * oDirY);
var coefficientC = oDirX * oDirX + oDirY * oDirY - cr * cr;
var lambda = coefficientB * coefficientB - 4 * coefficientA * coefficientC;
var x, y;
if (lambda === 0) {
var root = -coefficientB / (2 * coefficientA);
x = lx1 + root * lDirX;
y = ly1 + root * lDirY;
if (root >= 0 && root <= 1) {
out.push(new Point(x, y));
}
} else if (lambda > 0) {
var root1 = (-coefficientB - Math.sqrt(lambda)) / (2 * coefficientA);
x = lx1 + root1 * lDirX;
y = ly1 + root1 * lDirY;
if (root1 >= 0 && root1 <= 1) {
out.push(new Point(x, y));
}
var root2 = (-coefficientB + Math.sqrt(lambda)) / (2 * coefficientA);
x = lx1 + root2 * lDirX;
y = ly1 + root2 * lDirY;
if (root2 >= 0 && root2 <= 1) {
out.push(new Point(x, y));
}
}
}
return out;
};
module2.exports = GetLineToCircle;
}
),
/***/
36100: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Vector3 = __webpack_require__2(25836);
var GetLineToLine = function(line1, line2, isRay, out) {
if (isRay === void 0) {
isRay = false;
}
var x1 = line1.x1;
var y1 = line1.y1;
var x2 = line1.x2;
var y2 = line1.y2;
var x3 = line2.x1;
var y3 = line2.y1;
var x4 = line2.x2;
var y4 = line2.y2;
var dx1 = x2 - x1;
var dy1 = y2 - y1;
var dx2 = x4 - x3;
var dy2 = y4 - y3;
var denom = dx1 * dy2 - dy1 * dx2;
if (denom === 0) {
return null;
}
var t;
var u;
var s;
if (isRay) {
t = (dx1 * (y3 - y1) + dy1 * (x1 - x3)) / (dx2 * dy1 - dy2 * dx1);
if (dx1 !== 0) {
u = (x3 + dx2 * t - x1) / dx1;
} else if (dy1 !== 0) {
u = (y3 + dy2 * t - y1) / dy1;
} else {
return null;
}
if (u < 0 || t < 0 || t > 1) {
return null;
}
s = u;
} else {
t = ((x3 - x1) * dy2 - (y3 - y1) * dx2) / denom;
u = ((y1 - y3) * dx1 - (x1 - x3) * dy1) / denom;
if (t < 0 || t > 1 || u < 0 || u > 1) {
return null;
}
s = t;
}
if (out === void 0) {
out = new Vector3();
}
return out.set(
x1 + dx1 * s,
y1 + dy1 * s,
s
);
};
module2.exports = GetLineToLine;
}
),
/***/
3073: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetLineToLine = __webpack_require__2(36100);
var Line = __webpack_require__2(23031);
var Vector3 = __webpack_require__2(25836);
var segment = new Line();
var tempIntersect = new Vector3();
var GetLineToPoints = function(line, points, isRay, out) {
if (isRay === void 0) {
isRay = false;
}
if (out === void 0) {
out = new Vector3();
}
var closestIntersect = false;
out.set();
tempIntersect.set();
var prev = points[points.length - 1];
for (var i = 0; i < points.length; i++) {
var current = points[i];
segment.setTo(prev.x, prev.y, current.x, current.y);
prev = current;
if (GetLineToLine(line, segment, isRay, tempIntersect)) {
if (!closestIntersect || tempIntersect.z < out.z) {
out.copy(tempIntersect);
closestIntersect = true;
}
}
}
return closestIntersect ? out : null;
};
module2.exports = GetLineToPoints;
}
),
/***/
56362: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Vector3 = __webpack_require__2(25836);
var Vector4 = __webpack_require__2(61369);
var GetLineToPoints = __webpack_require__2(3073);
var tempIntersect = new Vector3();
var GetLineToPolygon = function(line, polygons, isRay, out) {
if (out === void 0) {
out = new Vector4();
}
if (!Array.isArray(polygons)) {
polygons = [polygons];
}
var closestIntersect = false;
out.set();
tempIntersect.set();
for (var i = 0; i < polygons.length; i++) {
if (GetLineToPoints(line, polygons[i].points, isRay, tempIntersect)) {
if (!closestIntersect || tempIntersect.z < out.z) {
out.set(tempIntersect.x, tempIntersect.y, tempIntersect.z, i);
closestIntersect = true;
}
}
}
return closestIntersect ? out : null;
};
module2.exports = GetLineToPolygon;
}
),
/***/
60646: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
var LineToLine = __webpack_require__2(76112);
var LineToRectangle = __webpack_require__2(92773);
var GetLineToRectangle = function(line, rect, out) {
if (out === void 0) {
out = [];
}
if (LineToRectangle(line, rect)) {
var lineA = rect.getLineA();
var lineB = rect.getLineB();
var lineC = rect.getLineC();
var lineD = rect.getLineD();
var output = [new Point(), new Point(), new Point(), new Point()];
var result = [
LineToLine(lineA, line, output[0]),
LineToLine(lineB, line, output[1]),
LineToLine(lineC, line, output[2]),
LineToLine(lineD, line, output[3])
];
for (var i = 0; i < 4; i++) {
if (result[i]) {
out.push(output[i]);
}
}
}
return out;
};
module2.exports = GetLineToRectangle;
}
),
/***/
71147: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Vector4 = __webpack_require__2(61369);
var GetLineToPolygon = __webpack_require__2(56362);
var Line = __webpack_require__2(23031);
var segment = new Line();
function CheckIntersects(angle, x, y, polygons, intersects) {
var dx = Math.cos(angle);
var dy = Math.sin(angle);
segment.setTo(x, y, x + dx, y + dy);
var closestIntersect = GetLineToPolygon(segment, polygons, true);
if (closestIntersect) {
intersects.push(new Vector4(closestIntersect.x, closestIntersect.y, angle, closestIntersect.w));
}
}
function SortIntersects(a, b) {
return a.z - b.z;
}
var GetRaysFromPointToPolygon = function(x, y, polygons) {
if (!Array.isArray(polygons)) {
polygons = [polygons];
}
var intersects = [];
var angles = [];
for (var i = 0; i < polygons.length; i++) {
var points = polygons[i].points;
for (var p = 0; p < points.length; p++) {
var angle = Math.atan2(points[p].y - y, points[p].x - x);
if (angles.indexOf(angle) === -1) {
CheckIntersects(angle, x, y, polygons, intersects);
CheckIntersects(angle - 1e-5, x, y, polygons, intersects);
CheckIntersects(angle + 1e-5, x, y, polygons, intersects);
angles.push(angle);
}
}
}
return intersects.sort(SortIntersects);
};
module2.exports = GetRaysFromPointToPolygon;
}
),
/***/
68389: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Rectangle = __webpack_require__2(87841);
var RectangleToRectangle = __webpack_require__2(59996);
var GetRectangleIntersection = function(rectA, rectB, output) {
if (output === void 0) {
output = new Rectangle();
}
if (RectangleToRectangle(rectA, rectB)) {
output.x = Math.max(rectA.x, rectB.x);
output.y = Math.max(rectA.y, rectB.y);
output.width = Math.min(rectA.right, rectB.right) - output.x;
output.height = Math.min(rectA.bottom, rectB.bottom) - output.y;
}
return output;
};
module2.exports = GetRectangleIntersection;
}
),
/***/
52784: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetLineToRectangle = __webpack_require__2(60646);
var RectangleToRectangle = __webpack_require__2(59996);
var GetRectangleToRectangle = function(rectA, rectB, out) {
if (out === void 0) {
out = [];
}
if (RectangleToRectangle(rectA, rectB)) {
var lineA = rectA.getLineA();
var lineB = rectA.getLineB();
var lineC = rectA.getLineC();
var lineD = rectA.getLineD();
GetLineToRectangle(lineA, rectB, out);
GetLineToRectangle(lineB, rectB, out);
GetLineToRectangle(lineC, rectB, out);
GetLineToRectangle(lineD, rectB, out);
}
return out;
};
module2.exports = GetRectangleToRectangle;
}
),
/***/
26341: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var RectangleToTriangle = __webpack_require__2(89265);
var GetLineToRectangle = __webpack_require__2(60646);
var GetRectangleToTriangle = function(rect, triangle, out) {
if (out === void 0) {
out = [];
}
if (RectangleToTriangle(rect, triangle)) {
var lineA = triangle.getLineA();
var lineB = triangle.getLineB();
var lineC = triangle.getLineC();
GetLineToRectangle(lineA, rect, out);
GetLineToRectangle(lineB, rect, out);
GetLineToRectangle(lineC, rect, out);
}
return out;
};
module2.exports = GetRectangleToTriangle;
}
),
/***/
38720: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetLineToCircle = __webpack_require__2(4042);
var TriangleToCircle = __webpack_require__2(67636);
var GetTriangleToCircle = function(triangle, circle, out) {
if (out === void 0) {
out = [];
}
if (TriangleToCircle(triangle, circle)) {
var lineA = triangle.getLineA();
var lineB = triangle.getLineB();
var lineC = triangle.getLineC();
GetLineToCircle(lineA, circle, out);
GetLineToCircle(lineB, circle, out);
GetLineToCircle(lineC, circle, out);
}
return out;
};
module2.exports = GetTriangleToCircle;
}
),
/***/
13882: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
var TriangleToLine = __webpack_require__2(2822);
var LineToLine = __webpack_require__2(76112);
var GetTriangleToLine = function(triangle, line, out) {
if (out === void 0) {
out = [];
}
if (TriangleToLine(triangle, line)) {
var lineA = triangle.getLineA();
var lineB = triangle.getLineB();
var lineC = triangle.getLineC();
var output = [new Point(), new Point(), new Point()];
var result = [
LineToLine(lineA, line, output[0]),
LineToLine(lineB, line, output[1]),
LineToLine(lineC, line, output[2])
];
for (var i = 0; i < 3; i++) {
if (result[i]) {
out.push(output[i]);
}
}
}
return out;
};
module2.exports = GetTriangleToLine;
}
),
/***/
75636: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var TriangleToTriangle = __webpack_require__2(82944);
var GetTriangleToLine = __webpack_require__2(13882);
var GetTriangleToTriangle = function(triangleA, triangleB, out) {
if (out === void 0) {
out = [];
}
if (TriangleToTriangle(triangleA, triangleB)) {
var lineA = triangleB.getLineA();
var lineB = triangleB.getLineB();
var lineC = triangleB.getLineC();
GetTriangleToLine(triangleA, lineA, out);
GetTriangleToLine(triangleA, lineB, out);
GetTriangleToLine(triangleA, lineC, out);
}
return out;
};
module2.exports = GetTriangleToTriangle;
}
),
/***/
80462: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Contains = __webpack_require__2(87902);
var Point = __webpack_require__2(2141);
var tmp = new Point();
var LineToCircle = function(line, circle, nearest) {
if (nearest === void 0) {
nearest = tmp;
}
if (Contains(circle, line.x1, line.y1)) {
nearest.x = line.x1;
nearest.y = line.y1;
return true;
}
if (Contains(circle, line.x2, line.y2)) {
nearest.x = line.x2;
nearest.y = line.y2;
return true;
}
var dx = line.x2 - line.x1;
var dy = line.y2 - line.y1;
var lcx = circle.x - line.x1;
var lcy = circle.y - line.y1;
var dLen2 = dx * dx + dy * dy;
var px = dx;
var py = dy;
if (dLen2 > 0) {
var dp = (lcx * dx + lcy * dy) / dLen2;
px *= dp;
py *= dp;
}
nearest.x = line.x1 + px;
nearest.y = line.y1 + py;
var pLen2 = px * px + py * py;
return pLen2 <= dLen2 && px * dx + py * dy >= 0 && Contains(circle, nearest.x, nearest.y);
};
module2.exports = LineToCircle;
}
),
/***/
76112: (
/***/
(module2) => {
var LineToLine = function(line1, line2, out) {
var x1 = line1.x1;
var y1 = line1.y1;
var x2 = line1.x2;
var y2 = line1.y2;
var x3 = line2.x1;
var y3 = line2.y1;
var x4 = line2.x2;
var y4 = line2.y2;
if (x1 === x2 && y1 === y2 || x3 === x4 && y3 === y4) {
return false;
}
var denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
if (denom === 0) {
return false;
}
var ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denom;
var ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denom;
if (ua < 0 || ua > 1 || ub < 0 || ub > 1) {
return false;
} else {
if (out) {
out.x = x1 + ua * (x2 - x1);
out.y = y1 + ua * (y2 - y1);
}
return true;
}
};
module2.exports = LineToLine;
}
),
/***/
92773: (
/***/
(module2) => {
var LineToRectangle = function(line, rect) {
var x1 = line.x1;
var y1 = line.y1;
var x2 = line.x2;
var y2 = line.y2;
var bx1 = rect.x;
var by1 = rect.y;
var bx2 = rect.right;
var by2 = rect.bottom;
var t = 0;
if (x1 >= bx1 && x1 <= bx2 && y1 >= by1 && y1 <= by2 || x2 >= bx1 && x2 <= bx2 && y2 >= by1 && y2 <= by2) {
return true;
}
if (x1 < bx1 && x2 >= bx1) {
t = y1 + (y2 - y1) * (bx1 - x1) / (x2 - x1);
if (t > by1 && t <= by2) {
return true;
}
} else if (x1 > bx2 && x2 <= bx2) {
t = y1 + (y2 - y1) * (bx2 - x1) / (x2 - x1);
if (t >= by1 && t <= by2) {
return true;
}
}
if (y1 < by1 && y2 >= by1) {
t = x1 + (x2 - x1) * (by1 - y1) / (y2 - y1);
if (t >= bx1 && t <= bx2) {
return true;
}
} else if (y1 > by2 && y2 <= by2) {
t = x1 + (x2 - x1) * (by2 - y1) / (y2 - y1);
if (t >= bx1 && t <= bx2) {
return true;
}
}
return false;
};
module2.exports = LineToRectangle;
}
),
/***/
16204: (
/***/
(module2) => {
var PointToLine = function(point, line, lineThickness) {
if (lineThickness === void 0) {
lineThickness = 1;
}
var x1 = line.x1;
var y1 = line.y1;
var x2 = line.x2;
var y2 = line.y2;
var px = point.x;
var py = point.y;
var L2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
if (L2 === 0) {
return false;
}
var r = ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / L2;
if (r < 0) {
return Math.sqrt((x1 - px) * (x1 - px) + (y1 - py) * (y1 - py)) <= lineThickness;
} else if (r >= 0 && r <= 1) {
var s = ((y1 - py) * (x2 - x1) - (x1 - px) * (y2 - y1)) / L2;
return Math.abs(s) * Math.sqrt(L2) <= lineThickness;
} else {
return Math.sqrt((x2 - px) * (x2 - px) + (y2 - py) * (y2 - py)) <= lineThickness;
}
};
module2.exports = PointToLine;
}
),
/***/
14199: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PointToLine = __webpack_require__2(16204);
var PointToLineSegment = function(point, line) {
if (!PointToLine(point, line)) {
return false;
}
var xMin = Math.min(line.x1, line.x2);
var xMax = Math.max(line.x1, line.x2);
var yMin = Math.min(line.y1, line.y2);
var yMax = Math.max(line.y1, line.y2);
return point.x >= xMin && point.x <= xMax && (point.y >= yMin && point.y <= yMax);
};
module2.exports = PointToLineSegment;
}
),
/***/
59996: (
/***/
(module2) => {
var RectangleToRectangle = function(rectA, rectB) {
if (rectA.width <= 0 || rectA.height <= 0 || rectB.width <= 0 || rectB.height <= 0) {
return false;
}
return !(rectA.right < rectB.x || rectA.bottom < rectB.y || rectA.x > rectB.right || rectA.y > rectB.bottom);
};
module2.exports = RectangleToRectangle;
}
),
/***/
89265: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var LineToLine = __webpack_require__2(76112);
var Contains = __webpack_require__2(37303);
var ContainsArray = __webpack_require__2(48653);
var Decompose = __webpack_require__2(77493);
var RectangleToTriangle = function(rect, triangle) {
if (triangle.left > rect.right || triangle.right < rect.left || triangle.top > rect.bottom || triangle.bottom < rect.top) {
return false;
}
var triA = triangle.getLineA();
var triB = triangle.getLineB();
var triC = triangle.getLineC();
if (Contains(rect, triA.x1, triA.y1) || Contains(rect, triA.x2, triA.y2)) {
return true;
}
if (Contains(rect, triB.x1, triB.y1) || Contains(rect, triB.x2, triB.y2)) {
return true;
}
if (Contains(rect, triC.x1, triC.y1) || Contains(rect, triC.x2, triC.y2)) {
return true;
}
var rectA = rect.getLineA();
var rectB = rect.getLineB();
var rectC = rect.getLineC();
var rectD = rect.getLineD();
if (LineToLine(triA, rectA) || LineToLine(triA, rectB) || LineToLine(triA, rectC) || LineToLine(triA, rectD)) {
return true;
}
if (LineToLine(triB, rectA) || LineToLine(triB, rectB) || LineToLine(triB, rectC) || LineToLine(triB, rectD)) {
return true;
}
if (LineToLine(triC, rectA) || LineToLine(triC, rectB) || LineToLine(triC, rectC) || LineToLine(triC, rectD)) {
return true;
}
var points = Decompose(rect);
var within = ContainsArray(triangle, points, true);
return within.length > 0;
};
module2.exports = RectangleToTriangle;
}
),
/***/
84411: (
/***/
(module2) => {
var RectangleToValues = function(rect, left, right, top, bottom, tolerance) {
if (tolerance === void 0) {
tolerance = 0;
}
return !(left > rect.right + tolerance || right < rect.left - tolerance || top > rect.bottom + tolerance || bottom < rect.top - tolerance);
};
module2.exports = RectangleToValues;
}
),
/***/
67636: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var LineToCircle = __webpack_require__2(80462);
var Contains = __webpack_require__2(10690);
var TriangleToCircle = function(triangle, circle) {
if (triangle.left > circle.right || triangle.right < circle.left || triangle.top > circle.bottom || triangle.bottom < circle.top) {
return false;
}
if (Contains(triangle, circle.x, circle.y)) {
return true;
}
if (LineToCircle(triangle.getLineA(), circle)) {
return true;
}
if (LineToCircle(triangle.getLineB(), circle)) {
return true;
}
if (LineToCircle(triangle.getLineC(), circle)) {
return true;
}
return false;
};
module2.exports = TriangleToCircle;
}
),
/***/
2822: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var LineToLine = __webpack_require__2(76112);
var TriangleToLine = function(triangle, line) {
if (triangle.contains(line.x1, line.y1) || triangle.contains(line.x2, line.y2)) {
return true;
}
if (LineToLine(triangle.getLineA(), line)) {
return true;
}
if (LineToLine(triangle.getLineB(), line)) {
return true;
}
if (LineToLine(triangle.getLineC(), line)) {
return true;
}
return false;
};
module2.exports = TriangleToLine;
}
),
/***/
82944: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var ContainsArray = __webpack_require__2(48653);
var Decompose = __webpack_require__2(71694);
var LineToLine = __webpack_require__2(76112);
var TriangleToTriangle = function(triangleA, triangleB) {
if (triangleA.left > triangleB.right || triangleA.right < triangleB.left || triangleA.top > triangleB.bottom || triangleA.bottom < triangleB.top) {
return false;
}
var lineAA = triangleA.getLineA();
var lineAB = triangleA.getLineB();
var lineAC = triangleA.getLineC();
var lineBA = triangleB.getLineA();
var lineBB = triangleB.getLineB();
var lineBC = triangleB.getLineC();
if (LineToLine(lineAA, lineBA) || LineToLine(lineAA, lineBB) || LineToLine(lineAA, lineBC)) {
return true;
}
if (LineToLine(lineAB, lineBA) || LineToLine(lineAB, lineBB) || LineToLine(lineAB, lineBC)) {
return true;
}
if (LineToLine(lineAC, lineBA) || LineToLine(lineAC, lineBB) || LineToLine(lineAC, lineBC)) {
return true;
}
var points = Decompose(triangleA);
var within = ContainsArray(triangleB, points, true);
if (within.length > 0) {
return true;
}
points = Decompose(triangleB);
within = ContainsArray(triangleA, points, true);
if (within.length > 0) {
return true;
}
return false;
};
module2.exports = TriangleToTriangle;
}
),
/***/
91865: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
CircleToCircle: __webpack_require__2(2044),
CircleToRectangle: __webpack_require__2(81491),
GetCircleToCircle: __webpack_require__2(63376),
GetCircleToRectangle: __webpack_require__2(97439),
GetLineToCircle: __webpack_require__2(4042),
GetLineToLine: __webpack_require__2(36100),
GetLineToPoints: __webpack_require__2(3073),
GetLineToPolygon: __webpack_require__2(56362),
GetLineToRectangle: __webpack_require__2(60646),
GetRaysFromPointToPolygon: __webpack_require__2(71147),
GetRectangleIntersection: __webpack_require__2(68389),
GetRectangleToRectangle: __webpack_require__2(52784),
GetRectangleToTriangle: __webpack_require__2(26341),
GetTriangleToCircle: __webpack_require__2(38720),
GetTriangleToLine: __webpack_require__2(13882),
GetTriangleToTriangle: __webpack_require__2(75636),
LineToCircle: __webpack_require__2(80462),
LineToLine: __webpack_require__2(76112),
LineToRectangle: __webpack_require__2(92773),
PointToLine: __webpack_require__2(16204),
PointToLineSegment: __webpack_require__2(14199),
RectangleToRectangle: __webpack_require__2(59996),
RectangleToTriangle: __webpack_require__2(89265),
RectangleToValues: __webpack_require__2(84411),
TriangleToCircle: __webpack_require__2(67636),
TriangleToLine: __webpack_require__2(2822),
TriangleToTriangle: __webpack_require__2(82944)
};
}
),
/***/
91938: (
/***/
(module2) => {
var Angle = function(line) {
return Math.atan2(line.y2 - line.y1, line.x2 - line.x1);
};
module2.exports = Angle;
}
),
/***/
84993: (
/***/
(module2) => {
var BresenhamPoints = function(line, stepRate, results) {
if (stepRate === void 0) {
stepRate = 1;
}
if (results === void 0) {
results = [];
}
var x1 = Math.round(line.x1);
var y1 = Math.round(line.y1);
var x2 = Math.round(line.x2);
var y2 = Math.round(line.y2);
var dx = Math.abs(x2 - x1);
var dy = Math.abs(y2 - y1);
var sx = x1 < x2 ? 1 : -1;
var sy = y1 < y2 ? 1 : -1;
var err = dx - dy;
results.push({ x: x1, y: y1 });
var i = 1;
while (!(x1 === x2 && y1 === y2)) {
var e2 = err << 1;
if (e2 > -dy) {
err -= dy;
x1 += sx;
}
if (e2 < dx) {
err += dx;
y1 += sy;
}
if (i % stepRate === 0) {
results.push({ x: x1, y: y1 });
}
i++;
}
return results;
};
module2.exports = BresenhamPoints;
}
),
/***/
36469: (
/***/
(module2) => {
var CenterOn = function(line, x, y) {
var tx = x - (line.x1 + line.x2) / 2;
var ty = y - (line.y1 + line.y2) / 2;
line.x1 += tx;
line.y1 += ty;
line.x2 += tx;
line.y2 += ty;
return line;
};
module2.exports = CenterOn;
}
),
/***/
31116: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Line = __webpack_require__2(23031);
var Clone = function(source) {
return new Line(source.x1, source.y1, source.x2, source.y2);
};
module2.exports = Clone;
}
),
/***/
59944: (
/***/
(module2) => {
var CopyFrom = function(source, dest) {
return dest.setTo(source.x1, source.y1, source.x2, source.y2);
};
module2.exports = CopyFrom;
}
),
/***/
59220: (
/***/
(module2) => {
var Equals = function(line, toCompare) {
return line.x1 === toCompare.x1 && line.y1 === toCompare.y1 && line.x2 === toCompare.x2 && line.y2 === toCompare.y2;
};
module2.exports = Equals;
}
),
/***/
78177: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Length = __webpack_require__2(35001);
var Extend = function(line, left, right) {
if (right === void 0) {
right = left;
}
var length = Length(line);
var slopX = line.x2 - line.x1;
var slopY = line.y2 - line.y1;
if (left) {
line.x1 = line.x1 - slopX / length * left;
line.y1 = line.y1 - slopY / length * left;
}
if (right) {
line.x2 = line.x2 + slopX / length * right;
line.y2 = line.y2 + slopY / length * right;
}
return line;
};
module2.exports = Extend;
}
),
/***/
26708: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var DistanceBetweenPoints = __webpack_require__2(52816);
var GetEaseFunction = __webpack_require__2(6113);
var Point = __webpack_require__2(2141);
var GetEasedPoints = function(line, ease, quantity, collinearThreshold, easeParams) {
if (collinearThreshold === void 0) {
collinearThreshold = 0;
}
if (easeParams === void 0) {
easeParams = [];
}
var results = [];
var x1 = line.x1;
var y1 = line.y1;
var spaceX = line.x2 - x1;
var spaceY = line.y2 - y1;
var easeFunc = GetEaseFunction(ease, easeParams);
var i;
var v;
var q = quantity - 1;
for (i = 0; i < q; i++) {
v = easeFunc(i / q);
results.push(new Point(x1 + spaceX * v, y1 + spaceY * v));
}
v = easeFunc(1);
results.push(new Point(x1 + spaceX * v, y1 + spaceY * v));
if (collinearThreshold > 0) {
var prevPoint = results[0];
var sortedResults = [prevPoint];
for (i = 1; i < results.length - 1; i++) {
var point = results[i];
if (DistanceBetweenPoints(prevPoint, point) >= collinearThreshold) {
sortedResults.push(point);
prevPoint = point;
}
}
var endPoint = results[results.length - 1];
if (DistanceBetweenPoints(prevPoint, endPoint) < collinearThreshold) {
sortedResults.pop();
}
sortedResults.push(endPoint);
return sortedResults;
} else {
return results;
}
};
module2.exports = GetEasedPoints;
}
),
/***/
32125: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
var GetMidPoint = function(line, out) {
if (out === void 0) {
out = new Point();
}
out.x = (line.x1 + line.x2) / 2;
out.y = (line.y1 + line.y2) / 2;
return out;
};
module2.exports = GetMidPoint;
}
),
/***/
99569: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
var GetNearestPoint = function(line, point, out) {
if (out === void 0) {
out = new Point();
}
var x1 = line.x1;
var y1 = line.y1;
var x2 = line.x2;
var y2 = line.y2;
var L2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
if (L2 === 0) {
return out;
}
var r = ((point.x - x1) * (x2 - x1) + (point.y - y1) * (y2 - y1)) / L2;
out.x = x1 + r * (x2 - x1);
out.y = y1 + r * (y2 - y1);
return out;
};
module2.exports = GetNearestPoint;
}
),
/***/
34638: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var MATH_CONST = __webpack_require__2(36383);
var Angle = __webpack_require__2(91938);
var Point = __webpack_require__2(2141);
var GetNormal = function(line, out) {
if (out === void 0) {
out = new Point();
}
var a = Angle(line) - MATH_CONST.TAU;
out.x = Math.cos(a);
out.y = Math.sin(a);
return out;
};
module2.exports = GetNormal;
}
),
/***/
13151: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
var GetPoint = function(line, position, out) {
if (out === void 0) {
out = new Point();
}
out.x = line.x1 + (line.x2 - line.x1) * position;
out.y = line.y1 + (line.y2 - line.y1) * position;
return out;
};
module2.exports = GetPoint;
}
),
/***/
15258: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Length = __webpack_require__2(35001);
var Point = __webpack_require__2(2141);
var GetPoints = function(line, quantity, stepRate, out) {
if (out === void 0) {
out = [];
}
if (!quantity && stepRate > 0) {
quantity = Length(line) / stepRate;
}
var x1 = line.x1;
var y1 = line.y1;
var x2 = line.x2;
var y2 = line.y2;
for (var i = 0; i < quantity; i++) {
var position = i / quantity;
var x = x1 + (x2 - x1) * position;
var y = y1 + (y2 - y1) * position;
out.push(new Point(x, y));
}
return out;
};
module2.exports = GetPoints;
}
),
/***/
26408: (
/***/
(module2) => {
var GetShortestDistance = function(line, point) {
var x1 = line.x1;
var y1 = line.y1;
var x2 = line.x2;
var y2 = line.y2;
var L2 = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
if (L2 === 0) {
return false;
}
var s = ((y1 - point.y) * (x2 - x1) - (x1 - point.x) * (y2 - y1)) / L2;
return Math.abs(s) * Math.sqrt(L2);
};
module2.exports = GetShortestDistance;
}
),
/***/
98770: (
/***/
(module2) => {
var Height = function(line) {
return Math.abs(line.y1 - line.y2);
};
module2.exports = Height;
}
),
/***/
35001: (
/***/
(module2) => {
var Length = function(line) {
return Math.sqrt((line.x2 - line.x1) * (line.x2 - line.x1) + (line.y2 - line.y1) * (line.y2 - line.y1));
};
module2.exports = Length;
}
),
/***/
23031: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var GetPoint = __webpack_require__2(13151);
var GetPoints = __webpack_require__2(15258);
var GEOM_CONST = __webpack_require__2(23777);
var Random = __webpack_require__2(65822);
var Vector2 = __webpack_require__2(26099);
var Line = new Class({
initialize: function Line2(x1, y1, x2, y2) {
if (x1 === void 0) {
x1 = 0;
}
if (y1 === void 0) {
y1 = 0;
}
if (x2 === void 0) {
x2 = 0;
}
if (y2 === void 0) {
y2 = 0;
}
this.type = GEOM_CONST.LINE;
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
},
/**
* Get a point on a line that's a given percentage along its length.
*
* @method Phaser.Geom.Line#getPoint
* @since 3.0.0
*
* @generic {Phaser.Geom.Point} O - [output,$return]
*
* @param {number} position - A value between 0 and 1, where 0 is the start, 0.5 is the middle and 1 is the end of the line.
* @param {(Phaser.Geom.Point|object)} [output] - An optional point, or point-like object, to store the coordinates of the point on the line.
*
* @return {(Phaser.Geom.Point|object)} A Point, or point-like object, containing the coordinates of the point on the line.
*/
getPoint: function(position, output) {
return GetPoint(this, position, output);
},
/**
* Get a number of points along a line's length.
*
* Provide a `quantity` to get an exact number of points along the line.
*
* Provide a `stepRate` to ensure a specific distance between each point on the line. Set `quantity` to `0` when
* providing a `stepRate`.
*
* @method Phaser.Geom.Line#getPoints
* @since 3.0.0
*
* @generic {Phaser.Geom.Point[]} O - [output,$return]
*
* @param {number} quantity - The number of points to place on the line. Set to `0` to use `stepRate` instead.
* @param {number} [stepRate] - The distance between each point on the line. When set, `quantity` is implied and should be set to `0`.
* @param {(array|Phaser.Geom.Point[])} [output] - An optional array of Points, or point-like objects, to store the coordinates of the points on the line.
*
* @return {(array|Phaser.Geom.Point[])} An array of Points, or point-like objects, containing the coordinates of the points on the line.
*/
getPoints: function(quantity, stepRate, output) {
return GetPoints(this, quantity, stepRate, output);
},
/**
* Get a random Point on the Line.
*
* @method Phaser.Geom.Line#getRandomPoint
* @since 3.0.0
*
* @generic {Phaser.Geom.Point} O - [point,$return]
*
* @param {(Phaser.Geom.Point|object)} [point] - An instance of a Point to be modified.
*
* @return {Phaser.Geom.Point} A random Point on the Line.
*/
getRandomPoint: function(point) {
return Random(this, point);
},
/**
* Set new coordinates for the line endpoints.
*
* @method Phaser.Geom.Line#setTo
* @since 3.0.0
*
* @param {number} [x1=0] - The x coordinate of the lines starting point.
* @param {number} [y1=0] - The y coordinate of the lines starting point.
* @param {number} [x2=0] - The x coordinate of the lines ending point.
* @param {number} [y2=0] - The y coordinate of the lines ending point.
*
* @return {this} This Line object.
*/
setTo: function(x1, y1, x2, y2) {
if (x1 === void 0) {
x1 = 0;
}
if (y1 === void 0) {
y1 = 0;
}
if (x2 === void 0) {
x2 = 0;
}
if (y2 === void 0) {
y2 = 0;
}
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
return this;
},
/**
* Sets this Line to match the x/y coordinates of the two given Vector2Like objects.
*
* @method Phaser.Geom.Line#setFromObjects
* @since 3.70.0
*
* @param {Phaser.Types.Math.Vector2Like} start - Any object with public `x` and `y` properties, whose values will be assigned to the x1/y1 components of this Line.
* @param {Phaser.Types.Math.Vector2Like} end - Any object with public `x` and `y` properties, whose values will be assigned to the x2/y2 components of this Line.
*
* @return {this} This Line object.
*/
setFromObjects: function(start, end) {
this.x1 = start.x;
this.y1 = start.y;
this.x2 = end.x;
this.y2 = end.y;
return this;
},
/**
* Returns a Vector2 object that corresponds to the start of this Line.
*
* @method Phaser.Geom.Line#getPointA
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2} O - [vec2,$return]
*
* @param {Phaser.Math.Vector2} [vec2] - A Vector2 object to set the results in. If `undefined` a new Vector2 will be created.
*
* @return {Phaser.Math.Vector2} A Vector2 object that corresponds to the start of this Line.
*/
getPointA: function(vec2) {
if (vec2 === void 0) {
vec2 = new Vector2();
}
vec2.set(this.x1, this.y1);
return vec2;
},
/**
* Returns a Vector2 object that corresponds to the end of this Line.
*
* @method Phaser.Geom.Line#getPointB
* @since 3.0.0
*
* @generic {Phaser.Math.Vector2} O - [vec2,$return]
*
* @param {Phaser.Math.Vector2} [vec2] - A Vector2 object to set the results in. If `undefined` a new Vector2 will be created.
*
* @return {Phaser.Math.Vector2} A Vector2 object that corresponds to the end of this Line.
*/
getPointB: function(vec2) {
if (vec2 === void 0) {
vec2 = new Vector2();
}
vec2.set(this.x2, this.y2);
return vec2;
},
/**
* The left position of the Line.
*
* @name Phaser.Geom.Line#left
* @type {number}
* @since 3.0.0
*/
left: {
get: function() {
return Math.min(this.x1, this.x2);
},
set: function(value) {
if (this.x1 <= this.x2) {
this.x1 = value;
} else {
this.x2 = value;
}
}
},
/**
* The right position of the Line.
*
* @name Phaser.Geom.Line#right
* @type {number}
* @since 3.0.0
*/
right: {
get: function() {
return Math.max(this.x1, this.x2);
},
set: function(value) {
if (this.x1 > this.x2) {
this.x1 = value;
} else {
this.x2 = value;
}
}
},
/**
* The top position of the Line.
*
* @name Phaser.Geom.Line#top
* @type {number}
* @since 3.0.0
*/
top: {
get: function() {
return Math.min(this.y1, this.y2);
},
set: function(value) {
if (this.y1 <= this.y2) {
this.y1 = value;
} else {
this.y2 = value;
}
}
},
/**
* The bottom position of the Line.
*
* @name Phaser.Geom.Line#bottom
* @type {number}
* @since 3.0.0
*/
bottom: {
get: function() {
return Math.max(this.y1, this.y2);
},
set: function(value) {
if (this.y1 > this.y2) {
this.y1 = value;
} else {
this.y2 = value;
}
}
}
});
module2.exports = Line;
}
),
/***/
64795: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var MATH_CONST = __webpack_require__2(36383);
var Wrap = __webpack_require__2(15994);
var Angle = __webpack_require__2(91938);
var NormalAngle = function(line) {
var angle = Angle(line) - MATH_CONST.TAU;
return Wrap(angle, -Math.PI, Math.PI);
};
module2.exports = NormalAngle;
}
),
/***/
52616: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var MATH_CONST = __webpack_require__2(36383);
var Angle = __webpack_require__2(91938);
var NormalX = function(line) {
return Math.cos(Angle(line) - MATH_CONST.TAU);
};
module2.exports = NormalX;
}
),
/***/
87231: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var MATH_CONST = __webpack_require__2(36383);
var Angle = __webpack_require__2(91938);
var NormalY = function(line) {
return Math.sin(Angle(line) - MATH_CONST.TAU);
};
module2.exports = NormalY;
}
),
/***/
89662: (
/***/
(module2) => {
var Offset = function(line, x, y) {
line.x1 += x;
line.y1 += y;
line.x2 += x;
line.y2 += y;
return line;
};
module2.exports = Offset;
}
),
/***/
71165: (
/***/
(module2) => {
var PerpSlope = function(line) {
return -((line.x2 - line.x1) / (line.y2 - line.y1));
};
module2.exports = PerpSlope;
}
),
/***/
65822: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
var Random = function(line, out) {
if (out === void 0) {
out = new Point();
}
var t = Math.random();
out.x = line.x1 + t * (line.x2 - line.x1);
out.y = line.y1 + t * (line.y2 - line.y1);
return out;
};
module2.exports = Random;
}
),
/***/
69777: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Angle = __webpack_require__2(91938);
var NormalAngle = __webpack_require__2(64795);
var ReflectAngle = function(lineA, lineB) {
return 2 * NormalAngle(lineB) - Math.PI - Angle(lineA);
};
module2.exports = ReflectAngle;
}
),
/***/
39706: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var RotateAroundXY = __webpack_require__2(64400);
var Rotate = function(line, angle) {
var x = (line.x1 + line.x2) / 2;
var y = (line.y1 + line.y2) / 2;
return RotateAroundXY(line, x, y, angle);
};
module2.exports = Rotate;
}
),
/***/
82585: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var RotateAroundXY = __webpack_require__2(64400);
var RotateAroundPoint = function(line, point, angle) {
return RotateAroundXY(line, point.x, point.y, angle);
};
module2.exports = RotateAroundPoint;
}
),
/***/
64400: (
/***/
(module2) => {
var RotateAroundXY = function(line, x, y, angle) {
var c = Math.cos(angle);
var s = Math.sin(angle);
var tx = line.x1 - x;
var ty = line.y1 - y;
line.x1 = tx * c - ty * s + x;
line.y1 = tx * s + ty * c + y;
tx = line.x2 - x;
ty = line.y2 - y;
line.x2 = tx * c - ty * s + x;
line.y2 = tx * s + ty * c + y;
return line;
};
module2.exports = RotateAroundXY;
}
),
/***/
62377: (
/***/
(module2) => {
var SetToAngle = function(line, x, y, angle, length) {
line.x1 = x;
line.y1 = y;
line.x2 = x + Math.cos(angle) * length;
line.y2 = y + Math.sin(angle) * length;
return line;
};
module2.exports = SetToAngle;
}
),
/***/
71366: (
/***/
(module2) => {
var Slope = function(line) {
return (line.y2 - line.y1) / (line.x2 - line.x1);
};
module2.exports = Slope;
}
),
/***/
10809: (
/***/
(module2) => {
var Width = function(line) {
return Math.abs(line.x1 - line.x2);
};
module2.exports = Width;
}
),
/***/
2529: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Line = __webpack_require__2(23031);
Line.Angle = __webpack_require__2(91938);
Line.BresenhamPoints = __webpack_require__2(84993);
Line.CenterOn = __webpack_require__2(36469);
Line.Clone = __webpack_require__2(31116);
Line.CopyFrom = __webpack_require__2(59944);
Line.Equals = __webpack_require__2(59220);
Line.Extend = __webpack_require__2(78177);
Line.GetEasedPoints = __webpack_require__2(26708);
Line.GetMidPoint = __webpack_require__2(32125);
Line.GetNearestPoint = __webpack_require__2(99569);
Line.GetNormal = __webpack_require__2(34638);
Line.GetPoint = __webpack_require__2(13151);
Line.GetPoints = __webpack_require__2(15258);
Line.GetShortestDistance = __webpack_require__2(26408);
Line.Height = __webpack_require__2(98770);
Line.Length = __webpack_require__2(35001);
Line.NormalAngle = __webpack_require__2(64795);
Line.NormalX = __webpack_require__2(52616);
Line.NormalY = __webpack_require__2(87231);
Line.Offset = __webpack_require__2(89662);
Line.PerpSlope = __webpack_require__2(71165);
Line.Random = __webpack_require__2(65822);
Line.ReflectAngle = __webpack_require__2(69777);
Line.Rotate = __webpack_require__2(39706);
Line.RotateAroundPoint = __webpack_require__2(82585);
Line.RotateAroundXY = __webpack_require__2(64400);
Line.SetToAngle = __webpack_require__2(62377);
Line.Slope = __webpack_require__2(71366);
Line.Width = __webpack_require__2(10809);
module2.exports = Line;
}
),
/***/
83997: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Rectangle = __webpack_require__2(87841);
var Vector2 = __webpack_require__2(26099);
function GetLength(x1, y1, x2, y2) {
var x = x1 - x2;
var y = y1 - y2;
var magnitude = x * x + y * y;
return Math.sqrt(magnitude);
}
var Face = new Class({
initialize: function Face2(vertex1, vertex2, vertex3) {
this.vertex1 = vertex1;
this.vertex2 = vertex2;
this.vertex3 = vertex3;
this.bounds = new Rectangle();
this._inCenter = new Vector2();
},
/**
* Calculates and returns the in-center position of this Face.
*
* @method Phaser.Geom.Mesh.Face#getInCenter
* @since 3.50.0
*
* @param {boolean} [local=true] Return the in center from the un-transformed vertex positions (`true`), or transformed? (`false`)
*
* @return {Phaser.Math.Vector2} A Vector2 containing the in center position of this Face.
*/
getInCenter: function(local) {
if (local === void 0) {
local = true;
}
var v1 = this.vertex1;
var v2 = this.vertex2;
var v3 = this.vertex3;
var v1x;
var v1y;
var v2x;
var v2y;
var v3x;
var v3y;
if (local) {
v1x = v1.x;
v1y = v1.y;
v2x = v2.x;
v2y = v2.y;
v3x = v3.x;
v3y = v3.y;
} else {
v1x = v1.vx;
v1y = v1.vy;
v2x = v2.vx;
v2y = v2.vy;
v3x = v3.vx;
v3y = v3.vy;
}
var d1 = GetLength(v3x, v3y, v2x, v2y);
var d2 = GetLength(v1x, v1y, v3x, v3y);
var d3 = GetLength(v2x, v2y, v1x, v1y);
var p = d1 + d2 + d3;
return this._inCenter.set(
(v1x * d1 + v2x * d2 + v3x * d3) / p,
(v1y * d1 + v2y * d2 + v3y * d3) / p
);
},
/**
* Checks if the given coordinates are within this Face.
*
* You can optionally provide a transform matrix. If given, the Face vertices
* will be transformed first, before being checked against the coordinates.
*
* @method Phaser.Geom.Mesh.Face#contains
* @since 3.50.0
*
* @param {number} x - The horizontal position to check.
* @param {number} y - The vertical position to check.
* @param {Phaser.GameObjects.Components.TransformMatrix} [calcMatrix] - Optional transform matrix to apply to the vertices before comparison.
*
* @return {boolean} `true` if the coordinates lay within this Face, otherwise `false`.
*/
contains: function(x, y, calcMatrix) {
var vertex1 = this.vertex1;
var vertex2 = this.vertex2;
var vertex3 = this.vertex3;
var v1x = vertex1.vx;
var v1y = vertex1.vy;
var v2x = vertex2.vx;
var v2y = vertex2.vy;
var v3x = vertex3.vx;
var v3y = vertex3.vy;
if (calcMatrix) {
var a = calcMatrix.a;
var b = calcMatrix.b;
var c = calcMatrix.c;
var d = calcMatrix.d;
var e = calcMatrix.e;
var f = calcMatrix.f;
v1x = vertex1.vx * a + vertex1.vy * c + e;
v1y = vertex1.vx * b + vertex1.vy * d + f;
v2x = vertex2.vx * a + vertex2.vy * c + e;
v2y = vertex2.vx * b + vertex2.vy * d + f;
v3x = vertex3.vx * a + vertex3.vy * c + e;
v3y = vertex3.vx * b + vertex3.vy * d + f;
}
var t0x = v3x - v1x;
var t0y = v3y - v1y;
var t1x = v2x - v1x;
var t1y = v2y - v1y;
var t2x = x - v1x;
var t2y = y - v1y;
var dot00 = t0x * t0x + t0y * t0y;
var dot01 = t0x * t1x + t0y * t1y;
var dot02 = t0x * t2x + t0y * t2y;
var dot11 = t1x * t1x + t1y * t1y;
var dot12 = t1x * t2x + t1y * t2y;
var bc = dot00 * dot11 - dot01 * dot01;
var inv = bc === 0 ? 0 : 1 / bc;
var u = (dot11 * dot02 - dot01 * dot12) * inv;
var v = (dot00 * dot12 - dot01 * dot02) * inv;
return u >= 0 && v >= 0 && u + v < 1;
},
/**
* Checks if the vertices in this Face are orientated counter-clockwise, or not.
*
* It checks the transformed position of the vertices, not the local one.
*
* @method Phaser.Geom.Mesh.Face#isCounterClockwise
* @since 3.50.0
*
* @param {number} z - The z-axis value to test against. Typically the `Mesh.modelPosition.z`.
*
* @return {boolean} `true` if the vertices in this Face run counter-clockwise, otherwise `false`.
*/
isCounterClockwise: function(z) {
var v1 = this.vertex1;
var v2 = this.vertex2;
var v3 = this.vertex3;
var d = (v2.vx - v1.vx) * (v3.vy - v1.vy) - (v2.vy - v1.vy) * (v3.vx - v1.vx);
return z <= 0 ? d >= 0 : d < 0;
},
/**
* Loads the data from this Vertex into the given Typed Arrays.
*
* @method Phaser.Geom.Mesh.Face#load
* @since 3.50.0
*
* @param {Float32Array} F32 - A Float32 Array to insert the position, UV and unit data in to.
* @param {Uint32Array} U32 - A Uint32 Array to insert the color and alpha data in to.
* @param {number} offset - The index of the array to insert this Vertex to.
* @param {number} textureUnit - The texture unit currently in use.
* @param {number} tintEffect - The tint effect to use.
*
* @return {number} The new vertex index array offset.
*/
load: function(F32, U32, offset, textureUnit, tintEffect) {
offset = this.vertex1.load(F32, U32, offset, textureUnit, tintEffect);
offset = this.vertex2.load(F32, U32, offset, textureUnit, tintEffect);
offset = this.vertex3.load(F32, U32, offset, textureUnit, tintEffect);
return offset;
},
/**
* Transforms all Face vertices by the given matrix, storing the results in their `vx`, `vy` and `vz` properties.
*
* @method Phaser.Geom.Mesh.Face#transformCoordinatesLocal
* @since 3.50.0
*
* @param {Phaser.Math.Matrix4} transformMatrix - The transform matrix to apply to this vertex.
* @param {number} width - The width of the parent Mesh.
* @param {number} height - The height of the parent Mesh.
* @param {number} cameraZ - The z position of the MeshCamera.
*
* @return {this} This Face instance.
*/
transformCoordinatesLocal: function(transformMatrix, width, height, cameraZ) {
this.vertex1.transformCoordinatesLocal(transformMatrix, width, height, cameraZ);
this.vertex2.transformCoordinatesLocal(transformMatrix, width, height, cameraZ);
this.vertex3.transformCoordinatesLocal(transformMatrix, width, height, cameraZ);
return this;
},
/**
* Updates the bounds of this Face, based on the translated values of the vertices.
*
* Call this method prior to accessing the `Face.bounds` property.
*
* @method Phaser.Geom.Mesh.Face#updateBounds
* @since 3.50.0
*
* @return {this} This Face instance.
*/
updateBounds: function() {
var v1 = this.vertex1;
var v2 = this.vertex2;
var v3 = this.vertex3;
var bounds = this.bounds;
bounds.x = Math.min(v1.vx, v2.vx, v3.vx);
bounds.y = Math.min(v1.vy, v2.vy, v3.vy);
bounds.width = Math.max(v1.vx, v2.vx, v3.vx) - bounds.x;
bounds.height = Math.max(v1.vy, v2.vy, v3.vy) - bounds.y;
return this;
},
/**
* Checks if this Face is within the view of the given Camera.
*
* This method is called in the `MeshWebGLRenderer` function. It performs the following tasks:
*
* First, the `Vertex.update` method is called on each of the vertices. This populates them
* with the new translated values, updating their `tx`, `ty` and `ta` properties.
*
* Then it tests to see if this face is visible due to the alpha values, if not, it returns.
*
* After this, if `hideCCW` is set, it calls `isCounterClockwise` and returns if not.
*
* Finally, it will update the `Face.bounds` based on the newly translated vertex values
* and return the results of an intersection test between the bounds and the camera world view
* rectangle.
*
* @method Phaser.Geom.Mesh.Face#isInView
* @since 3.50.0
*
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to check against.
* @param {boolean} hideCCW - Test the counter-clockwise orientation of the verts?
* @param {number} z - The Cameras z position, used in the CCW test.
* @param {number} alpha - The alpha of the parent object.
* @param {number} a - The parent transform matrix data a component.
* @param {number} b - The parent transform matrix data b component.
* @param {number} c - The parent transform matrix data c component.
* @param {number} d - The parent transform matrix data d component.
* @param {number} e - The parent transform matrix data e component.
* @param {number} f - The parent transform matrix data f component.
* @param {boolean} roundPixels - Round the vertex position or not?
*
* @return {boolean} `true` if this Face can be seen by the Camera.
*/
isInView: function(camera, hideCCW, z, alpha, a, b, c, d, e, f, roundPixels) {
this.update(alpha, a, b, c, d, e, f, roundPixels);
var v1 = this.vertex1;
var v2 = this.vertex2;
var v3 = this.vertex3;
if (v1.ta <= 0 && v2.ta <= 0 && v3.ta <= 0) {
return false;
}
if (hideCCW && !this.isCounterClockwise(z)) {
return false;
}
var bounds = this.bounds;
bounds.x = Math.min(v1.tx, v2.tx, v3.tx);
bounds.y = Math.min(v1.ty, v2.ty, v3.ty);
bounds.width = Math.max(v1.tx, v2.tx, v3.tx) - bounds.x;
bounds.height = Math.max(v1.ty, v2.ty, v3.ty) - bounds.y;
var cr = camera.x + camera.width;
var cb = camera.y + camera.height;
if (bounds.width <= 0 || bounds.height <= 0 || camera.width <= 0 || camera.height <= 0) {
return false;
}
return !(bounds.right < camera.x || bounds.bottom < camera.y || bounds.x > cr || bounds.y > cb);
},
/**
* Translates the original UV positions of each vertex by the given amounts.
*
* The original properties `Vertex.u` and `Vertex.v`
* remain unchanged, only the translated properties
* `Vertex.tu` and `Vertex.tv`, as used in rendering,
* are updated.
*
* @method Phaser.Geom.Mesh.Face#scrollUV
* @since 3.60.0
*
* @param {number} x - The amount to scroll the UV u coordinate by.
* @param {number} y - The amount to scroll the UV v coordinate by.
*
* @return {this} This Face instance.
*/
scrollUV: function(x, y) {
this.vertex1.scrollUV(x, y);
this.vertex2.scrollUV(x, y);
this.vertex3.scrollUV(x, y);
return this;
},
/**
* Scales the original UV values of each vertex by the given amounts.
*
* The original properties `Vertex.u` and `Vertex.v`
* remain unchanged, only the translated properties
* `Vertex.tu` and `Vertex.tv`, as used in rendering,
* are updated.
*
* @method Phaser.Geom.Mesh.Face#scaleUV
* @since 3.60.0
*
* @param {number} x - The amount to scale the UV u coordinate by.
* @param {number} y - The amount to scale the UV v coordinate by.
*
* @return {this} This Face instance.
*/
scaleUV: function(x, y) {
this.vertex1.scaleUV(x, y);
this.vertex2.scaleUV(x, y);
this.vertex3.scaleUV(x, y);
return this;
},
/**
* Sets the color value for each Vertex in this Face.
*
* @method Phaser.Geom.Mesh.Face#setColor
* @since 3.60.0
*
* @param {number} color - The color value for each vertex.
*
* @return {this} This Face instance.
*/
setColor: function(color) {
this.vertex1.color = color;
this.vertex2.color = color;
this.vertex3.color = color;
return this;
},
/**
* Calls the `Vertex.update` method on each of the vertices. This populates them
* with the new translated values, updating their `tx`, `ty` and `ta` properties.
*
* @method Phaser.Geom.Mesh.Face#update
* @since 3.60.0
*
* @param {number} alpha - The alpha of the parent object.
* @param {number} a - The parent transform matrix data a component.
* @param {number} b - The parent transform matrix data b component.
* @param {number} c - The parent transform matrix data c component.
* @param {number} d - The parent transform matrix data d component.
* @param {number} e - The parent transform matrix data e component.
* @param {number} f - The parent transform matrix data f component.
* @param {boolean} roundPixels - Round the vertex position or not?
*
* @return {this} This Face instance.
*/
update: function(alpha, a, b, c, d, e, f, roundPixels) {
this.vertex1.update(a, b, c, d, e, f, roundPixels, alpha);
this.vertex2.update(a, b, c, d, e, f, roundPixels, alpha);
this.vertex3.update(a, b, c, d, e, f, roundPixels, alpha);
return this;
},
/**
* Translates the vertices of this Face by the given amounts.
*
* The actual vertex positions are adjusted, not their transformed position.
*
* Therefore, this updates the vertex data directly.
*
* @method Phaser.Geom.Mesh.Face#translate
* @since 3.50.0
*
* @param {number} x - The amount to horizontally translate by.
* @param {number} [y=0] - The amount to vertically translate by.
*
* @return {this} This Face instance.
*/
translate: function(x, y) {
if (y === void 0) {
y = 0;
}
var v1 = this.vertex1;
var v2 = this.vertex2;
var v3 = this.vertex3;
v1.x += x;
v1.y += y;
v2.x += x;
v2.y += y;
v3.x += x;
v3.y += y;
return this;
},
/**
* The x coordinate of this Face, based on the in center position of the Face.
*
* @name Phaser.Geom.Mesh.Face#x
* @type {number}
* @since 3.50.0
*/
x: {
get: function() {
return this.getInCenter().x;
},
set: function(value) {
var current = this.getInCenter();
this.translate(value - current.x, 0);
}
},
/**
* The y coordinate of this Face, based on the in center position of the Face.
*
* @name Phaser.Geom.Mesh.Face#y
* @type {number}
* @since 3.50.0
*/
y: {
get: function() {
return this.getInCenter().y;
},
set: function(value) {
var current = this.getInCenter();
this.translate(0, value - current.y);
}
},
/**
* Set the alpha value of this Face.
*
* Each vertex is given the same value. If you need to adjust the alpha on a per-vertex basis
* then use the `Vertex.alpha` property instead.
*
* When getting the alpha of this Face, it will return an average of the alpha
* component of all three vertices.
*
* @name Phaser.Geom.Mesh.Face#alpha
* @type {number}
* @since 3.50.0
*/
alpha: {
get: function() {
var v1 = this.vertex1;
var v2 = this.vertex2;
var v3 = this.vertex3;
return (v1.alpha + v2.alpha + v3.alpha) / 3;
},
set: function(value) {
this.vertex1.alpha = value;
this.vertex2.alpha = value;
this.vertex3.alpha = value;
}
},
/**
* The depth of this Face, which is an average of the z component of all three vertices.
*
* The depth is calculated based on the transformed z value, not the local one.
*
* @name Phaser.Geom.Mesh.Face#depth
* @type {number}
* @readonly
* @since 3.50.0
*/
depth: {
get: function() {
var v1 = this.vertex1;
var v2 = this.vertex2;
var v3 = this.vertex3;
return (v1.vz + v2.vz + v3.vz) / 3;
}
},
/**
* Destroys this Face and nulls the references to the vertices.
*
* @method Phaser.Geom.Mesh.Face#destroy
* @since 3.50.0
*/
destroy: function() {
this.vertex1 = null;
this.vertex2 = null;
this.vertex3 = null;
}
});
module2.exports = Face;
}
),
/***/
48803: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Face = __webpack_require__2(83997);
var GetFastValue = __webpack_require__2(95540);
var Matrix4 = __webpack_require__2(37867);
var Vector3 = __webpack_require__2(25836);
var Vertex = __webpack_require__2(39318);
var tempPosition = new Vector3();
var tempRotation = new Vector3();
var tempMatrix = new Matrix4();
var GenerateGridVerts = function(config) {
var mesh = GetFastValue(config, "mesh");
var texture = GetFastValue(config, "texture", null);
var frame = GetFastValue(config, "frame");
var width = GetFastValue(config, "width", 1);
var height = GetFastValue(config, "height", width);
var widthSegments = GetFastValue(config, "widthSegments", 1);
var heightSegments = GetFastValue(config, "heightSegments", widthSegments);
var posX = GetFastValue(config, "x", 0);
var posY = GetFastValue(config, "y", 0);
var posZ = GetFastValue(config, "z", 0);
var rotateX = GetFastValue(config, "rotateX", 0);
var rotateY = GetFastValue(config, "rotateY", 0);
var rotateZ = GetFastValue(config, "rotateZ", 0);
var zIsUp = GetFastValue(config, "zIsUp", true);
var isOrtho = GetFastValue(config, "isOrtho", mesh ? mesh.dirtyCache[11] : false);
var colors = GetFastValue(config, "colors", [16777215]);
var alphas = GetFastValue(config, "alphas", [1]);
var tile = GetFastValue(config, "tile", false);
var flipY = GetFastValue(config, "flipY", false);
var widthSet = GetFastValue(config, "width", null);
var result = {
faces: [],
verts: []
};
tempPosition.set(posX, posY, posZ);
tempRotation.set(rotateX, rotateY, rotateZ);
tempMatrix.fromRotationXYTranslation(tempRotation, tempPosition, zIsUp);
var textureFrame;
if (!texture && mesh) {
texture = mesh.texture;
if (!frame) {
textureFrame = mesh.frame;
}
} else if (mesh && typeof texture === "string") {
texture = mesh.scene.sys.textures.get(texture);
} else if (!texture) {
return result;
}
if (!textureFrame) {
textureFrame = texture.get(frame);
}
if (!widthSet && isOrtho && texture && mesh) {
width = textureFrame.width / mesh.height;
height = textureFrame.height / mesh.height;
}
var halfWidth = width / 2;
var halfHeight = height / 2;
var gridX = Math.floor(widthSegments);
var gridY = Math.floor(heightSegments);
var gridX1 = gridX + 1;
var gridY1 = gridY + 1;
var segmentWidth = width / gridX;
var segmentHeight = height / gridY;
var uvs = [];
var vertices = [];
var ix;
var iy;
var frameU0 = 0;
var frameU1 = 1;
var frameV0 = 0;
var frameV1 = 1;
if (textureFrame) {
frameU0 = textureFrame.u0;
frameU1 = textureFrame.u1;
if (!flipY) {
frameV0 = textureFrame.v0;
frameV1 = textureFrame.v1;
} else {
frameV0 = textureFrame.v1;
frameV1 = textureFrame.v0;
}
}
var frameU = frameU1 - frameU0;
var frameV = frameV1 - frameV0;
for (iy = 0; iy < gridY1; iy++) {
var y = iy * segmentHeight - halfHeight;
for (ix = 0; ix < gridX1; ix++) {
var x = ix * segmentWidth - halfWidth;
vertices.push(x, -y);
var tu = frameU0 + frameU * (ix / gridX);
var tv = frameV0 + frameV * (iy / gridY);
uvs.push(tu, tv);
}
}
if (!Array.isArray(colors)) {
colors = [colors];
}
if (!Array.isArray(alphas)) {
alphas = [alphas];
}
var alphaIndex = 0;
var colorIndex = 0;
for (iy = 0; iy < gridY; iy++) {
for (ix = 0; ix < gridX; ix++) {
var a = (ix + gridX1 * iy) * 2;
var b = (ix + gridX1 * (iy + 1)) * 2;
var c = (ix + 1 + gridX1 * (iy + 1)) * 2;
var d = (ix + 1 + gridX1 * iy) * 2;
var color = colors[colorIndex];
var alpha = alphas[alphaIndex];
var vert1 = new Vertex(vertices[a], vertices[a + 1], 0, uvs[a], uvs[a + 1], color, alpha).transformMat4(tempMatrix);
var vert2 = new Vertex(vertices[b], vertices[b + 1], 0, uvs[b], uvs[b + 1], color, alpha).transformMat4(tempMatrix);
var vert3 = new Vertex(vertices[d], vertices[d + 1], 0, uvs[d], uvs[d + 1], color, alpha).transformMat4(tempMatrix);
var vert4 = new Vertex(vertices[b], vertices[b + 1], 0, uvs[b], uvs[b + 1], color, alpha).transformMat4(tempMatrix);
var vert5 = new Vertex(vertices[c], vertices[c + 1], 0, uvs[c], uvs[c + 1], color, alpha).transformMat4(tempMatrix);
var vert6 = new Vertex(vertices[d], vertices[d + 1], 0, uvs[d], uvs[d + 1], color, alpha).transformMat4(tempMatrix);
if (tile) {
vert1.setUVs(frameU0, frameV1);
vert2.setUVs(frameU0, frameV0);
vert3.setUVs(frameU1, frameV1);
vert4.setUVs(frameU0, frameV0);
vert5.setUVs(frameU1, frameV0);
vert6.setUVs(frameU1, frameV1);
}
colorIndex++;
if (colorIndex === colors.length) {
colorIndex = 0;
}
alphaIndex++;
if (alphaIndex === alphas.length) {
alphaIndex = 0;
}
result.verts.push(vert1, vert2, vert3, vert4, vert5, vert6);
result.faces.push(
new Face(vert1, vert2, vert3),
new Face(vert4, vert5, vert6)
);
}
}
if (mesh) {
mesh.faces = mesh.faces.concat(result.faces);
mesh.vertices = mesh.vertices.concat(result.verts);
}
return result;
};
module2.exports = GenerateGridVerts;
}
),
/***/
34684: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Face = __webpack_require__2(83997);
var Matrix4 = __webpack_require__2(37867);
var Vector3 = __webpack_require__2(25836);
var Vertex = __webpack_require__2(39318);
var tempPosition = new Vector3();
var tempRotation = new Vector3();
var tempMatrix = new Matrix4();
var GenerateObjVerts = function(data, mesh, scale, x, y, z, rotateX, rotateY, rotateZ, zIsUp) {
if (scale === void 0) {
scale = 1;
}
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (z === void 0) {
z = 0;
}
if (rotateX === void 0) {
rotateX = 0;
}
if (rotateY === void 0) {
rotateY = 0;
}
if (rotateZ === void 0) {
rotateZ = 0;
}
if (zIsUp === void 0) {
zIsUp = true;
}
var result = {
faces: [],
verts: []
};
var materials = data.materials;
tempPosition.set(x, y, z);
tempRotation.set(rotateX, rotateY, rotateZ);
tempMatrix.fromRotationXYTranslation(tempRotation, tempPosition, zIsUp);
for (var m = 0; m < data.models.length; m++) {
var model = data.models[m];
var vertices = model.vertices;
var textureCoords = model.textureCoords;
var faces = model.faces;
for (var i = 0; i < faces.length; i++) {
var face = faces[i];
var v1 = face.vertices[0];
var v2 = face.vertices[1];
var v3 = face.vertices[2];
var m1 = vertices[v1.vertexIndex];
var m2 = vertices[v2.vertexIndex];
var m3 = vertices[v3.vertexIndex];
var t1 = v1.textureCoordsIndex;
var t2 = v2.textureCoordsIndex;
var t3 = v3.textureCoordsIndex;
var uv1 = t1 === -1 ? { u: 0, v: 1 } : textureCoords[t1];
var uv2 = t2 === -1 ? { u: 0, v: 0 } : textureCoords[t2];
var uv3 = t3 === -1 ? { u: 1, v: 1 } : textureCoords[t3];
var color = 16777215;
if (face.material !== "" && materials[face.material]) {
color = materials[face.material];
}
var vert1 = new Vertex(m1.x * scale, m1.y * scale, m1.z * scale, uv1.u, uv1.v, color).transformMat4(tempMatrix);
var vert2 = new Vertex(m2.x * scale, m2.y * scale, m2.z * scale, uv2.u, uv2.v, color).transformMat4(tempMatrix);
var vert3 = new Vertex(m3.x * scale, m3.y * scale, m3.z * scale, uv3.u, uv3.v, color).transformMat4(tempMatrix);
result.verts.push(vert1, vert2, vert3);
result.faces.push(new Face(vert1, vert2, vert3));
}
}
if (mesh) {
mesh.faces = mesh.faces.concat(result.faces);
mesh.vertices = mesh.vertices.concat(result.verts);
}
return result;
};
module2.exports = GenerateObjVerts;
}
),
/***/
92515: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Face = __webpack_require__2(83997);
var Vertex = __webpack_require__2(39318);
var GenerateVerts = function(vertices, uvs, indicies, containsZ, normals, colors, alphas, flipUV) {
if (containsZ === void 0) {
containsZ = false;
}
if (colors === void 0) {
colors = 16777215;
}
if (alphas === void 0) {
alphas = 1;
}
if (flipUV === void 0) {
flipUV = false;
}
if (vertices.length !== uvs.length && !containsZ) {
console.warn("GenerateVerts: vertices and uvs count not equal");
return;
}
var result = {
faces: [],
vertices: []
};
var i;
var x;
var y;
var z;
var u;
var v;
var color;
var alpha;
var normalX;
var normalY;
var normalZ;
var iInc = containsZ ? 3 : 2;
var isColorArray = Array.isArray(colors);
var isAlphaArray = Array.isArray(alphas);
if (Array.isArray(indicies) && indicies.length > 0) {
for (i = 0; i < indicies.length; i++) {
var index1 = indicies[i];
var index2 = indicies[i] * 2;
var index3 = indicies[i] * iInc;
x = vertices[index3];
y = vertices[index3 + 1];
z = containsZ ? vertices[index3 + 2] : 0;
u = uvs[index2];
v = uvs[index2 + 1];
if (flipUV) {
v = 1 - v;
}
color = isColorArray ? colors[index1] : colors;
alpha = isAlphaArray ? alphas[index1] : alphas;
normalX = 0;
normalY = 0;
normalZ = 0;
if (normals) {
normalX = normals[index3];
normalY = normals[index3 + 1];
normalZ = containsZ ? normals[index3 + 2] : 0;
}
result.vertices.push(new Vertex(x, y, z, u, v, color, alpha, normalX, normalY, normalZ));
}
} else {
var uvIndex = 0;
var colorIndex = 0;
for (i = 0; i < vertices.length; i += iInc) {
x = vertices[i];
y = vertices[i + 1];
z = containsZ ? vertices[i + 2] : 0;
u = uvs[uvIndex];
v = uvs[uvIndex + 1];
color = isColorArray ? colors[colorIndex] : colors;
alpha = isAlphaArray ? alphas[colorIndex] : alphas;
normalX = 0;
normalY = 0;
normalZ = 0;
if (normals) {
normalX = normals[i];
normalY = normals[i + 1];
normalZ = containsZ ? normals[i + 2] : 0;
}
result.vertices.push(new Vertex(x, y, z, u, v, color, alpha, normalX, normalY, normalZ));
uvIndex += 2;
colorIndex++;
}
}
for (i = 0; i < result.vertices.length; i += 3) {
var vert1 = result.vertices[i];
var vert2 = result.vertices[i + 1];
var vert3 = result.vertices[i + 2];
result.faces.push(new Face(vert1, vert2, vert3));
}
return result;
};
module2.exports = GenerateVerts;
}
),
/***/
85048: (
/***/
(module2) => {
var flip = true;
var defaultModelName = "untitled";
var currentGroup = "";
var currentMaterial = "";
function stripComments(line) {
var idx = line.indexOf("#");
return idx > -1 ? line.substring(0, idx) : line;
}
function currentModel(result) {
if (result.models.length === 0) {
result.models.push({
faces: [],
name: defaultModelName,
textureCoords: [],
vertexNormals: [],
vertices: []
});
}
currentGroup = "";
return result.models[result.models.length - 1];
}
function parseObject(lineItems, result) {
var modelName = lineItems.length >= 2 ? lineItems[1] : defaultModelName;
result.models.push({
faces: [],
name: modelName,
textureCoords: [],
vertexNormals: [],
vertices: []
});
currentGroup = "";
}
function parseGroup(lineItems) {
if (lineItems.length === 2) {
currentGroup = lineItems[1];
}
}
function parseVertexCoords(lineItems, result) {
var len = lineItems.length;
var x = len >= 2 ? parseFloat(lineItems[1]) : 0;
var y = len >= 3 ? parseFloat(lineItems[2]) : 0;
var z = len >= 4 ? parseFloat(lineItems[3]) : 0;
currentModel(result).vertices.push({ x, y, z });
}
function parseTextureCoords(lineItems, result) {
var len = lineItems.length;
var u = len >= 2 ? parseFloat(lineItems[1]) : 0;
var v = len >= 3 ? parseFloat(lineItems[2]) : 0;
var w = len >= 4 ? parseFloat(lineItems[3]) : 0;
if (isNaN(u)) {
u = 0;
}
if (isNaN(v)) {
v = 0;
}
if (isNaN(w)) {
w = 0;
}
if (flip) {
v = 1 - v;
}
currentModel(result).textureCoords.push({ u, v, w });
}
function parseVertexNormal(lineItems, result) {
var len = lineItems.length;
var x = len >= 2 ? parseFloat(lineItems[1]) : 0;
var y = len >= 3 ? parseFloat(lineItems[2]) : 0;
var z = len >= 4 ? parseFloat(lineItems[3]) : 0;
currentModel(result).vertexNormals.push({ x, y, z });
}
function parsePolygon(lineItems, result) {
var totalVertices = lineItems.length - 1;
if (totalVertices < 3) {
return;
}
var face = {
group: currentGroup,
material: currentMaterial,
vertices: []
};
for (var i = 0; i < totalVertices; i++) {
var vertexString = lineItems[i + 1];
var vertexValues = vertexString.split("/");
var vvLen = vertexValues.length;
if (vvLen < 1 || vvLen > 3) {
continue;
}
var vertexIndex = 0;
var textureCoordsIndex = 0;
var vertexNormalIndex = 0;
vertexIndex = parseInt(vertexValues[0], 10);
if (vvLen > 1 && vertexValues[1] !== "") {
textureCoordsIndex = parseInt(vertexValues[1], 10);
}
if (vvLen > 2) {
vertexNormalIndex = parseInt(vertexValues[2], 10);
}
if (vertexIndex !== 0) {
if (vertexIndex < 0) {
vertexIndex = currentModel(result).vertices.length + 1 + vertexIndex;
}
textureCoordsIndex -= 1;
vertexIndex -= 1;
vertexNormalIndex -= 1;
face.vertices.push({
textureCoordsIndex,
vertexIndex,
vertexNormalIndex
});
}
}
currentModel(result).faces.push(face);
}
function parseMtlLib(lineItems, result) {
if (lineItems.length >= 2) {
result.materialLibraries.push(lineItems[1]);
}
}
function parseUseMtl(lineItems) {
if (lineItems.length >= 2) {
currentMaterial = lineItems[1];
}
}
var ParseObj = function(data, flipUV) {
if (flipUV === void 0) {
flipUV = true;
}
flip = flipUV;
var result = {
materials: {},
materialLibraries: [],
models: []
};
currentGroup = "";
currentMaterial = "";
var lines = data.split("\n");
for (var i = 0; i < lines.length; i++) {
var line = stripComments(lines[i]);
var lineItems = line.replace(/\s\s+/g, " ").trim().split(" ");
switch (lineItems[0].toLowerCase()) {
case "o":
parseObject(lineItems, result);
break;
case "g":
parseGroup(lineItems);
break;
case "v":
parseVertexCoords(lineItems, result);
break;
case "vt":
parseTextureCoords(lineItems, result);
break;
case "vn":
parseVertexNormal(lineItems, result);
break;
case "f":
parsePolygon(lineItems, result);
break;
case "mtllib":
parseMtlLib(lineItems, result);
break;
case "usemtl":
parseUseMtl(lineItems);
break;
}
}
return result;
};
module2.exports = ParseObj;
}
),
/***/
61485: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetColor = __webpack_require__2(37589);
var ParseObjMaterial = function(mtl) {
var output = {};
var lines = mtl.split("\n");
var currentMaterial = "";
for (var i = 0; i < lines.length; i++) {
var line = lines[i].trim();
if (line.indexOf("#") === 0 || line === "") {
continue;
}
var lineItems = line.replace(/\s\s+/g, " ").trim().split(" ");
switch (lineItems[0].toLowerCase()) {
case "newmtl": {
currentMaterial = lineItems[1];
break;
}
case "kd": {
var r = Math.floor(lineItems[1] * 255);
var g = lineItems.length >= 2 ? Math.floor(lineItems[2] * 255) : r;
var b = lineItems.length >= 3 ? Math.floor(lineItems[3] * 255) : r;
output[currentMaterial] = GetColor(r, g, b);
break;
}
}
}
return output;
};
module2.exports = ParseObjMaterial;
}
),
/***/
92570: (
/***/
(module2) => {
var RotateFace = function(face, angle, cx, cy) {
var x;
var y;
if (cx === void 0 && cy === void 0) {
var inCenter = face.getInCenter();
x = inCenter.x;
y = inCenter.y;
}
var c = Math.cos(angle);
var s = Math.sin(angle);
var v1 = face.vertex1;
var v2 = face.vertex2;
var v3 = face.vertex3;
var tx = v1.x - x;
var ty = v1.y - y;
v1.set(tx * c - ty * s + x, tx * s + ty * c + y);
tx = v2.x - x;
ty = v2.y - y;
v2.set(tx * c - ty * s + x, tx * s + ty * c + y);
tx = v3.x - x;
ty = v3.y - y;
v3.set(tx * c - ty * s + x, tx * s + ty * c + y);
};
module2.exports = RotateFace;
}
),
/***/
39318: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Utils = __webpack_require__2(70554);
var Vector3 = __webpack_require__2(25836);
var Vertex = new Class({
Extends: Vector3,
initialize: function Vertex2(x, y, z, u, v, color, alpha, nx, ny, nz) {
if (color === void 0) {
color = 16777215;
}
if (alpha === void 0) {
alpha = 1;
}
if (nx === void 0) {
nx = 0;
}
if (ny === void 0) {
ny = 0;
}
if (nz === void 0) {
nz = 0;
}
Vector3.call(this, x, y, z);
this.vx = 0;
this.vy = 0;
this.vz = 0;
this.nx = nx;
this.ny = ny;
this.nz = nz;
this.u = u;
this.v = v;
this.color = color;
this.alpha = alpha;
this.tx = 0;
this.ty = 0;
this.ta = 0;
this.tu = u;
this.tv = v;
},
/**
* Sets the U and V properties.
*
* Also resets the translated uv properties, undoing any scale
* or shift they may have had.
*
* @method Phaser.Geom.Mesh.Vertex#setUVs
* @since 3.50.0
*
* @param {number} u - The UV u coordinate of the vertex.
* @param {number} v - The UV v coordinate of the vertex.
*
* @return {this} This Vertex.
*/
setUVs: function(u, v) {
this.u = u;
this.v = v;
this.tu = u;
this.tv = v;
return this;
},
/**
* Translates the original UV positions by the given amounts.
*
* The original properties `Vertex.u` and `Vertex.v`
* remain unchanged, only the translated properties
* `Vertex.tu` and `Vertex.tv`, as used in rendering,
* are updated.
*
* @method Phaser.Geom.Mesh.Vertex#scrollUV
* @since 3.60.0
*
* @param {number} x - The amount to scroll the UV u coordinate by.
* @param {number} y - The amount to scroll the UV v coordinate by.
*
* @return {this} This Vertex.
*/
scrollUV: function(x, y) {
this.tu += x;
this.tv += y;
return this;
},
/**
* Scales the original UV values by the given amounts.
*
* The original properties `Vertex.u` and `Vertex.v`
* remain unchanged, only the translated properties
* `Vertex.tu` and `Vertex.tv`, as used in rendering,
* are updated.
*
* @method Phaser.Geom.Mesh.Vertex#scaleUV
* @since 3.60.0
*
* @param {number} x - The amount to scale the UV u coordinate by.
* @param {number} y - The amount to scale the UV v coordinate by.
*
* @return {this} This Vertex.
*/
scaleUV: function(x, y) {
this.tu = this.u * x;
this.tv = this.v * y;
return this;
},
/**
* Transforms this vertex by the given matrix, storing the results in `vx`, `vy` and `vz`.
*
* @method Phaser.Geom.Mesh.Vertex#transformCoordinatesLocal
* @since 3.50.0
*
* @param {Phaser.Math.Matrix4} transformMatrix - The transform matrix to apply to this vertex.
* @param {number} width - The width of the parent Mesh.
* @param {number} height - The height of the parent Mesh.
* @param {number} cameraZ - The z position of the MeshCamera.
*/
transformCoordinatesLocal: function(transformMatrix, width, height, cameraZ) {
var x = this.x;
var y = this.y;
var z = this.z;
var m = transformMatrix.val;
var tx = x * m[0] + y * m[4] + z * m[8] + m[12];
var ty = x * m[1] + y * m[5] + z * m[9] + m[13];
var tz = x * m[2] + y * m[6] + z * m[10] + m[14];
var tw = x * m[3] + y * m[7] + z * m[11] + m[15];
this.vx = tx / tw * width;
this.vy = -(ty / tw) * height;
if (cameraZ <= 0) {
this.vz = tz / tw;
} else {
this.vz = -(tz / tw);
}
},
/**
* Resizes this Vertex by setting the x and y coordinates, then transforms this vertex
* by an identity matrix and dimensions, storing the results in `vx`, `vy` and `vz`.
*
* @method Phaser.Geom.Mesh.Vertex#resize
* @since 3.60.0
*
* @param {number} x - The x position of the vertex.
* @param {number} y - The y position of the vertex.
* @param {number} width - The width of the parent Mesh.
* @param {number} height - The height of the parent Mesh.
* @param {number} originX - The originX of the parent Mesh.
* @param {number} originY - The originY of the parent Mesh.
*
* @return {this} This Vertex.
*/
resize: function(x, y, width, height, originX, originY) {
this.x = x;
this.y = y;
this.vx = this.x * width;
this.vy = -this.y * height;
this.vz = 0;
if (originX < 0.5) {
this.vx += width * (0.5 - originX);
} else if (originX > 0.5) {
this.vx -= width * (originX - 0.5);
}
if (originY < 0.5) {
this.vy += height * (0.5 - originY);
} else if (originY > 0.5) {
this.vy -= height * (originY - 0.5);
}
return this;
},
/**
* Updates this Vertex based on the given transform.
*
* @method Phaser.Geom.Mesh.Vertex#update
* @since 3.50.0
*
* @param {number} a - The parent transform matrix data a component.
* @param {number} b - The parent transform matrix data b component.
* @param {number} c - The parent transform matrix data c component.
* @param {number} d - The parent transform matrix data d component.
* @param {number} e - The parent transform matrix data e component.
* @param {number} f - The parent transform matrix data f component.
* @param {boolean} roundPixels - Round the vertex position or not?
* @param {number} alpha - The alpha of the parent object.
*
* @return {this} This Vertex.
*/
update: function(a, b, c, d, e, f, roundPixels, alpha) {
var tx = this.vx * a + this.vy * c + e;
var ty = this.vx * b + this.vy * d + f;
if (roundPixels) {
tx = Math.round(tx);
ty = Math.round(ty);
}
this.tx = tx;
this.ty = ty;
this.ta = this.alpha * alpha;
return this;
},
/**
* Loads the data from this Vertex into the given Typed Arrays.
*
* @method Phaser.Geom.Mesh.Vertex#load
* @since 3.50.0
*
* @param {Float32Array} F32 - A Float32 Array to insert the position, UV and unit data in to.
* @param {Uint32Array} U32 - A Uint32 Array to insert the color and alpha data in to.
* @param {number} offset - The index of the array to insert this Vertex to.
* @param {number} textureUnit - The texture unit currently in use.
* @param {number} tintEffect - The tint effect to use.
*
* @return {number} The new array offset.
*/
load: function(F32, U32, offset, textureUnit, tintEffect) {
F32[++offset] = this.tx;
F32[++offset] = this.ty;
F32[++offset] = this.tu;
F32[++offset] = this.tv;
F32[++offset] = textureUnit;
F32[++offset] = tintEffect;
U32[++offset] = Utils.getTintAppendFloatAlpha(this.color, this.ta);
return offset;
}
});
module2.exports = Vertex;
}
),
/***/
73090: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Mesh = {
Face: __webpack_require__2(83997),
GenerateGridVerts: __webpack_require__2(48803),
GenerateObjVerts: __webpack_require__2(34684),
GenerateVerts: __webpack_require__2(92515),
ParseObj: __webpack_require__2(85048),
ParseObjMaterial: __webpack_require__2(61485),
RotateFace: __webpack_require__2(92570),
Vertex: __webpack_require__2(39318)
};
module2.exports = Mesh;
}
),
/***/
96550: (
/***/
(module2) => {
var Ceil = function(point) {
return point.setTo(Math.ceil(point.x), Math.ceil(point.y));
};
module2.exports = Ceil;
}
),
/***/
99706: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
var Clone = function(source) {
return new Point(source.x, source.y);
};
module2.exports = Clone;
}
),
/***/
68010: (
/***/
(module2) => {
var CopyFrom = function(source, dest) {
return dest.setTo(source.x, source.y);
};
module2.exports = CopyFrom;
}
),
/***/
27814: (
/***/
(module2) => {
var Equals = function(point, toCompare) {
return point.x === toCompare.x && point.y === toCompare.y;
};
module2.exports = Equals;
}
),
/***/
73565: (
/***/
(module2) => {
var Floor = function(point) {
return point.setTo(Math.floor(point.x), Math.floor(point.y));
};
module2.exports = Floor;
}
),
/***/
87555: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
var GetCentroid = function(points, out) {
if (out === void 0) {
out = new Point();
}
if (!Array.isArray(points)) {
throw new Error("GetCentroid points argument must be an array");
}
var len = points.length;
if (len < 1) {
throw new Error("GetCentroid points array must not be empty");
} else if (len === 1) {
out.x = points[0].x;
out.y = points[0].y;
} else {
for (var i = 0; i < len; i++) {
out.x += points[i].x;
out.y += points[i].y;
}
out.x /= len;
out.y /= len;
}
return out;
};
module2.exports = GetCentroid;
}
),
/***/
28793: (
/***/
(module2) => {
var GetMagnitude = function(point) {
return Math.sqrt(point.x * point.x + point.y * point.y);
};
module2.exports = GetMagnitude;
}
),
/***/
44405: (
/***/
(module2) => {
var GetMagnitudeSq = function(point) {
return point.x * point.x + point.y * point.y;
};
module2.exports = GetMagnitudeSq;
}
),
/***/
20873: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Rectangle = __webpack_require__2(87841);
var GetRectangleFromPoints = function(points, out) {
if (out === void 0) {
out = new Rectangle();
}
var xMax = Number.NEGATIVE_INFINITY;
var xMin = Number.POSITIVE_INFINITY;
var yMax = Number.NEGATIVE_INFINITY;
var yMin = Number.POSITIVE_INFINITY;
for (var i = 0; i < points.length; i++) {
var point = points[i];
if (point.x > xMax) {
xMax = point.x;
}
if (point.x < xMin) {
xMin = point.x;
}
if (point.y > yMax) {
yMax = point.y;
}
if (point.y < yMin) {
yMin = point.y;
}
}
out.x = xMin;
out.y = yMin;
out.width = xMax - xMin;
out.height = yMax - yMin;
return out;
};
module2.exports = GetRectangleFromPoints;
}
),
/***/
26152: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
var Interpolate = function(pointA, pointB, t, out) {
if (t === void 0) {
t = 0;
}
if (out === void 0) {
out = new Point();
}
out.x = pointA.x + (pointB.x - pointA.x) * t;
out.y = pointA.y + (pointB.y - pointA.y) * t;
return out;
};
module2.exports = Interpolate;
}
),
/***/
55767: (
/***/
(module2) => {
var Invert = function(point) {
return point.setTo(point.y, point.x);
};
module2.exports = Invert;
}
),
/***/
79432: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
var Negative = function(point, out) {
if (out === void 0) {
out = new Point();
}
return out.setTo(-point.x, -point.y);
};
module2.exports = Negative;
}
),
/***/
2141: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var GEOM_CONST = __webpack_require__2(23777);
var Point = new Class({
initialize: function Point2(x, y) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = x;
}
this.type = GEOM_CONST.POINT;
this.x = x;
this.y = y;
},
/**
* Set the x and y coordinates of the point to the given values.
*
* @method Phaser.Geom.Point#setTo
* @since 3.0.0
*
* @param {number} [x=0] - The x coordinate of this Point.
* @param {number} [y=x] - The y coordinate of this Point.
*
* @return {this} This Point object.
*/
setTo: function(x, y) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = x;
}
this.x = x;
this.y = y;
return this;
}
});
module2.exports = Point;
}
),
/***/
72930: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
var GetMagnitudeSq = __webpack_require__2(44405);
var Project = function(pointA, pointB, out) {
if (out === void 0) {
out = new Point();
}
var dot = pointA.x * pointB.x + pointA.y * pointB.y;
var amt = dot / GetMagnitudeSq(pointB);
if (amt !== 0) {
out.x = amt * pointB.x;
out.y = amt * pointB.y;
}
return out;
};
module2.exports = Project;
}
),
/***/
62880: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
var ProjectUnit = function(pointA, pointB, out) {
if (out === void 0) {
out = new Point();
}
var amt = pointA.x * pointB.x + pointA.y * pointB.y;
if (amt !== 0) {
out.x = amt * pointB.x;
out.y = amt * pointB.y;
}
return out;
};
module2.exports = ProjectUnit;
}
),
/***/
15093: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetMagnitude = __webpack_require__2(28793);
var SetMagnitude = function(point, magnitude) {
if (point.x !== 0 || point.y !== 0) {
var m = GetMagnitude(point);
point.x /= m;
point.y /= m;
}
point.x *= magnitude;
point.y *= magnitude;
return point;
};
module2.exports = SetMagnitude;
}
),
/***/
43711: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
Point.Ceil = __webpack_require__2(96550);
Point.Clone = __webpack_require__2(99706);
Point.CopyFrom = __webpack_require__2(68010);
Point.Equals = __webpack_require__2(27814);
Point.Floor = __webpack_require__2(73565);
Point.GetCentroid = __webpack_require__2(87555);
Point.GetMagnitude = __webpack_require__2(28793);
Point.GetMagnitudeSq = __webpack_require__2(44405);
Point.GetRectangleFromPoints = __webpack_require__2(20873);
Point.Interpolate = __webpack_require__2(26152);
Point.Invert = __webpack_require__2(55767);
Point.Negative = __webpack_require__2(79432);
Point.Project = __webpack_require__2(72930);
Point.ProjectUnit = __webpack_require__2(62880);
Point.SetMagnitude = __webpack_require__2(15093);
module2.exports = Point;
}
),
/***/
12306: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Polygon = __webpack_require__2(25717);
var Clone = function(polygon) {
return new Polygon(polygon.points);
};
module2.exports = Clone;
}
),
/***/
63814: (
/***/
(module2) => {
var Contains = function(polygon, x, y) {
var inside = false;
for (var i = -1, j = polygon.points.length - 1; ++i < polygon.points.length; j = i) {
var ix = polygon.points[i].x;
var iy = polygon.points[i].y;
var jx = polygon.points[j].x;
var jy = polygon.points[j].y;
if ((iy <= y && y < jy || jy <= y && y < iy) && x < (jx - ix) * (y - iy) / (jy - iy) + ix) {
inside = !inside;
}
}
return inside;
};
module2.exports = Contains;
}
),
/***/
99338: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Contains = __webpack_require__2(63814);
var ContainsPoint = function(polygon, point) {
return Contains(polygon, point.x, point.y);
};
module2.exports = ContainsPoint;
}
),
/***/
94811: (
/***/
(module2) => {
"use strict";
function earcut(data, holeIndices, dim) {
dim = dim || 2;
var hasHoles = holeIndices && holeIndices.length, outerLen = hasHoles ? holeIndices[0] * dim : data.length, outerNode = linkedList(data, 0, outerLen, dim, true), triangles = [];
if (!outerNode || outerNode.next === outerNode.prev) return triangles;
var minX, minY, maxX, maxY, x, y, invSize;
if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);
if (data.length > 80 * dim) {
minX = maxX = data[0];
minY = maxY = data[1];
for (var i = dim; i < outerLen; i += dim) {
x = data[i];
y = data[i + 1];
if (x < minX) minX = x;
if (y < minY) minY = y;
if (x > maxX) maxX = x;
if (y > maxY) maxY = y;
}
invSize = Math.max(maxX - minX, maxY - minY);
invSize = invSize !== 0 ? 32767 / invSize : 0;
}
earcutLinked(outerNode, triangles, dim, minX, minY, invSize, 0);
return triangles;
}
function linkedList(data, start, end, dim, clockwise) {
var i, last;
if (clockwise === signedArea(data, start, end, dim) > 0) {
for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);
} else {
for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last);
}
if (last && equals(last, last.next)) {
removeNode(last);
last = last.next;
}
return last;
}
function filterPoints(start, end) {
if (!start) return start;
if (!end) end = start;
var p = start, again;
do {
again = false;
if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {
removeNode(p);
p = end = p.prev;
if (p === p.next) break;
again = true;
} else {
p = p.next;
}
} while (again || p !== end);
return end;
}
function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {
if (!ear) return;
if (!pass && invSize) indexCurve(ear, minX, minY, invSize);
var stop = ear, prev, next;
while (ear.prev !== ear.next) {
prev = ear.prev;
next = ear.next;
if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) {
triangles.push(prev.i / dim | 0);
triangles.push(ear.i / dim | 0);
triangles.push(next.i / dim | 0);
removeNode(ear);
ear = next.next;
stop = next.next;
continue;
}
ear = next;
if (ear === stop) {
if (!pass) {
earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1);
} else if (pass === 1) {
ear = cureLocalIntersections(filterPoints(ear), triangles, dim);
earcutLinked(ear, triangles, dim, minX, minY, invSize, 2);
} else if (pass === 2) {
splitEarcut(ear, triangles, dim, minX, minY, invSize);
}
break;
}
}
}
function isEar(ear) {
var a = ear.prev, b = ear, c = ear.next;
if (area(a, b, c) >= 0) return false;
var ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;
var x0 = ax < bx ? ax < cx ? ax : cx : bx < cx ? bx : cx, y0 = ay < by ? ay < cy ? ay : cy : by < cy ? by : cy, x1 = ax > bx ? ax > cx ? ax : cx : bx > cx ? bx : cx, y1 = ay > by ? ay > cy ? ay : cy : by > cy ? by : cy;
var p = c.next;
while (p !== a) {
if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
p = p.next;
}
return true;
}
function isEarHashed(ear, minX, minY, invSize) {
var a = ear.prev, b = ear, c = ear.next;
if (area(a, b, c) >= 0) return false;
var ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;
var x0 = ax < bx ? ax < cx ? ax : cx : bx < cx ? bx : cx, y0 = ay < by ? ay < cy ? ay : cy : by < cy ? by : cy, x1 = ax > bx ? ax > cx ? ax : cx : bx > cx ? bx : cx, y1 = ay > by ? ay > cy ? ay : cy : by > cy ? by : cy;
var minZ = zOrder(x0, y0, minX, minY, invSize), maxZ = zOrder(x1, y1, minX, minY, invSize);
var p = ear.prevZ, n = ear.nextZ;
while (p && p.z >= minZ && n && n.z <= maxZ) {
if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
p = p.prevZ;
if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;
n = n.nextZ;
}
while (p && p.z >= minZ) {
if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
p = p.prevZ;
}
while (n && n.z <= maxZ) {
if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;
n = n.nextZ;
}
return true;
}
function cureLocalIntersections(start, triangles, dim) {
var p = start;
do {
var a = p.prev, b = p.next.next;
if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {
triangles.push(a.i / dim | 0);
triangles.push(p.i / dim | 0);
triangles.push(b.i / dim | 0);
removeNode(p);
removeNode(p.next);
p = start = b;
}
p = p.next;
} while (p !== start);
return filterPoints(p);
}
function splitEarcut(start, triangles, dim, minX, minY, invSize) {
var a = start;
do {
var b = a.next.next;
while (b !== a.prev) {
if (a.i !== b.i && isValidDiagonal(a, b)) {
var c = splitPolygon(a, b);
a = filterPoints(a, a.next);
c = filterPoints(c, c.next);
earcutLinked(a, triangles, dim, minX, minY, invSize, 0);
earcutLinked(c, triangles, dim, minX, minY, invSize, 0);
return;
}
b = b.next;
}
a = a.next;
} while (a !== start);
}
function eliminateHoles(data, holeIndices, outerNode, dim) {
var queue = [], i, len, start, end, list;
for (i = 0, len = holeIndices.length; i < len; i++) {
start = holeIndices[i] * dim;
end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
list = linkedList(data, start, end, dim, false);
if (list === list.next) list.steiner = true;
queue.push(getLeftmost(list));
}
queue.sort(compareX);
for (i = 0; i < queue.length; i++) {
outerNode = eliminateHole(queue[i], outerNode);
}
return outerNode;
}
function compareX(a, b) {
return a.x - b.x;
}
function eliminateHole(hole, outerNode) {
var bridge = findHoleBridge(hole, outerNode);
if (!bridge) {
return outerNode;
}
var bridgeReverse = splitPolygon(bridge, hole);
filterPoints(bridgeReverse, bridgeReverse.next);
return filterPoints(bridge, bridge.next);
}
function findHoleBridge(hole, outerNode) {
var p = outerNode, hx = hole.x, hy = hole.y, qx = -Infinity, m;
do {
if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {
var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
if (x <= hx && x > qx) {
qx = x;
m = p.x < p.next.x ? p : p.next;
if (x === hx) return m;
}
}
p = p.next;
} while (p !== outerNode);
if (!m) return null;
var stop = m, mx = m.x, my = m.y, tanMin = Infinity, tan;
p = m;
do {
if (hx >= p.x && p.x >= mx && hx !== p.x && pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {
tan = Math.abs(hy - p.y) / (hx - p.x);
if (locallyInside(p, hole) && (tan < tanMin || tan === tanMin && (p.x > m.x || p.x === m.x && sectorContainsSector(m, p)))) {
m = p;
tanMin = tan;
}
}
p = p.next;
} while (p !== stop);
return m;
}
function sectorContainsSector(m, p) {
return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0;
}
function indexCurve(start, minX, minY, invSize) {
var p = start;
do {
if (p.z === 0) p.z = zOrder(p.x, p.y, minX, minY, invSize);
p.prevZ = p.prev;
p.nextZ = p.next;
p = p.next;
} while (p !== start);
p.prevZ.nextZ = null;
p.prevZ = null;
sortLinked(p);
}
function sortLinked(list) {
var i, p, q, e, tail, numMerges, pSize, qSize, inSize = 1;
do {
p = list;
list = null;
tail = null;
numMerges = 0;
while (p) {
numMerges++;
q = p;
pSize = 0;
for (i = 0; i < inSize; i++) {
pSize++;
q = q.nextZ;
if (!q) break;
}
qSize = inSize;
while (pSize > 0 || qSize > 0 && q) {
if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) {
e = p;
p = p.nextZ;
pSize--;
} else {
e = q;
q = q.nextZ;
qSize--;
}
if (tail) tail.nextZ = e;
else list = e;
e.prevZ = tail;
tail = e;
}
p = q;
}
tail.nextZ = null;
inSize *= 2;
} while (numMerges > 1);
return list;
}
function zOrder(x, y, minX, minY, invSize) {
x = (x - minX) * invSize | 0;
y = (y - minY) * invSize | 0;
x = (x | x << 8) & 16711935;
x = (x | x << 4) & 252645135;
x = (x | x << 2) & 858993459;
x = (x | x << 1) & 1431655765;
y = (y | y << 8) & 16711935;
y = (y | y << 4) & 252645135;
y = (y | y << 2) & 858993459;
y = (y | y << 1) & 1431655765;
return x | y << 1;
}
function getLeftmost(start) {
var p = start, leftmost = start;
do {
if (p.x < leftmost.x || p.x === leftmost.x && p.y < leftmost.y) leftmost = p;
p = p.next;
} while (p !== start);
return leftmost;
}
function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
return (cx - px) * (ay - py) >= (ax - px) * (cy - py) && (ax - px) * (by - py) >= (bx - px) * (ay - py) && (bx - px) * (cy - py) >= (cx - px) * (by - py);
}
function isValidDiagonal(a, b) {
return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && // dones't intersect other edges
(locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && // locally visible
(area(a.prev, a, b.prev) || area(a, b.prev, b)) || // does not create opposite-facing sectors
equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0);
}
function area(p, q, r) {
return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
}
function equals(p1, p2) {
return p1.x === p2.x && p1.y === p2.y;
}
function intersects(p1, q1, p2, q2) {
var o1 = sign(area(p1, q1, p2));
var o2 = sign(area(p1, q1, q2));
var o3 = sign(area(p2, q2, p1));
var o4 = sign(area(p2, q2, q1));
if (o1 !== o2 && o3 !== o4) return true;
if (o1 === 0 && onSegment(p1, p2, q1)) return true;
if (o2 === 0 && onSegment(p1, q2, q1)) return true;
if (o3 === 0 && onSegment(p2, p1, q2)) return true;
if (o4 === 0 && onSegment(p2, q1, q2)) return true;
return false;
}
function onSegment(p, q, r) {
return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);
}
function sign(num) {
return num > 0 ? 1 : num < 0 ? -1 : 0;
}
function intersectsPolygon(a, b) {
var p = a;
do {
if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && intersects(p, p.next, a, b)) return true;
p = p.next;
} while (p !== a);
return false;
}
function locallyInside(a, b) {
return area(a.prev, a, a.next) < 0 ? area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;
}
function middleInside(a, b) {
var p = a, inside = false, px = (a.x + b.x) / 2, py = (a.y + b.y) / 2;
do {
if (p.y > py !== p.next.y > py && p.next.y !== p.y && px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x)
inside = !inside;
p = p.next;
} while (p !== a);
return inside;
}
function splitPolygon(a, b) {
var a2 = new Node(a.i, a.x, a.y), b2 = new Node(b.i, b.x, b.y), an = a.next, bp = b.prev;
a.next = b;
b.prev = a;
a2.next = an;
an.prev = a2;
b2.next = a2;
a2.prev = b2;
bp.next = b2;
b2.prev = bp;
return b2;
}
function insertNode(i, x, y, last) {
var p = new Node(i, x, y);
if (!last) {
p.prev = p;
p.next = p;
} else {
p.next = last.next;
p.prev = last;
last.next.prev = p;
last.next = p;
}
return p;
}
function removeNode(p) {
p.next.prev = p.prev;
p.prev.next = p.next;
if (p.prevZ) p.prevZ.nextZ = p.nextZ;
if (p.nextZ) p.nextZ.prevZ = p.prevZ;
}
function Node(i, x, y) {
this.i = i;
this.x = x;
this.y = y;
this.prev = null;
this.next = null;
this.z = 0;
this.prevZ = null;
this.nextZ = null;
this.steiner = false;
}
earcut.deviation = function(data, holeIndices, dim, triangles) {
var hasHoles = holeIndices && holeIndices.length;
var outerLen = hasHoles ? holeIndices[0] * dim : data.length;
var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim));
if (hasHoles) {
for (var i = 0, len = holeIndices.length; i < len; i++) {
var start = holeIndices[i] * dim;
var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
polygonArea -= Math.abs(signedArea(data, start, end, dim));
}
}
var trianglesArea = 0;
for (i = 0; i < triangles.length; i += 3) {
var a = triangles[i] * dim;
var b = triangles[i + 1] * dim;
var c = triangles[i + 2] * dim;
trianglesArea += Math.abs(
(data[a] - data[c]) * (data[b + 1] - data[a + 1]) - (data[a] - data[b]) * (data[c + 1] - data[a + 1])
);
}
return polygonArea === 0 && trianglesArea === 0 ? 0 : Math.abs((trianglesArea - polygonArea) / polygonArea);
};
function signedArea(data, start, end, dim) {
var sum = 0;
for (var i = start, j = end - dim; i < end; i += dim) {
sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);
j = i;
}
return sum;
}
earcut.flatten = function(data) {
var dim = data[0][0].length, result = { vertices: [], holes: [], dimensions: dim }, holeIndex = 0;
for (var i = 0; i < data.length; i++) {
for (var j = 0; j < data[i].length; j++) {
for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]);
}
if (i > 0) {
holeIndex += data[i - 1].length;
result.holes.push(holeIndex);
}
}
return result;
};
module2.exports = earcut;
}
),
/***/
13829: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Rectangle = __webpack_require__2(87841);
var GetAABB = function(polygon, out) {
if (out === void 0) {
out = new Rectangle();
}
var minX = Infinity;
var minY = Infinity;
var maxX = -minX;
var maxY = -minY;
var p;
for (var i = 0; i < polygon.points.length; i++) {
p = polygon.points[i];
minX = Math.min(minX, p.x);
minY = Math.min(minY, p.y);
maxX = Math.max(maxX, p.x);
maxY = Math.max(maxY, p.y);
}
out.x = minX;
out.y = minY;
out.width = maxX - minX;
out.height = maxY - minY;
return out;
};
module2.exports = GetAABB;
}
),
/***/
26173: (
/***/
(module2) => {
var GetNumberArray = function(polygon, output) {
if (output === void 0) {
output = [];
}
for (var i = 0; i < polygon.points.length; i++) {
output.push(polygon.points[i].x);
output.push(polygon.points[i].y);
}
return output;
};
module2.exports = GetNumberArray;
}
),
/***/
9564: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Length = __webpack_require__2(35001);
var Line = __webpack_require__2(23031);
var Perimeter = __webpack_require__2(30052);
var GetPoints = function(polygon, quantity, stepRate, out) {
if (out === void 0) {
out = [];
}
var points = polygon.points;
var perimeter = Perimeter(polygon);
if (!quantity && stepRate > 0) {
quantity = perimeter / stepRate;
}
for (var i = 0; i < quantity; i++) {
var position = perimeter * (i / quantity);
var accumulatedPerimeter = 0;
for (var j = 0; j < points.length; j++) {
var pointA = points[j];
var pointB = points[(j + 1) % points.length];
var line = new Line(
pointA.x,
pointA.y,
pointB.x,
pointB.y
);
var length = Length(line);
if (position < accumulatedPerimeter || position > accumulatedPerimeter + length) {
accumulatedPerimeter += length;
continue;
}
var point = line.getPoint((position - accumulatedPerimeter) / length);
out.push(point);
break;
}
}
return out;
};
module2.exports = GetPoints;
}
),
/***/
30052: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Length = __webpack_require__2(35001);
var Line = __webpack_require__2(23031);
var Perimeter = function(polygon) {
var points = polygon.points;
var perimeter = 0;
for (var i = 0; i < points.length; i++) {
var pointA = points[i];
var pointB = points[(i + 1) % points.length];
var line = new Line(
pointA.x,
pointA.y,
pointB.x,
pointB.y
);
perimeter += Length(line);
}
return perimeter;
};
module2.exports = Perimeter;
}
),
/***/
25717: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Contains = __webpack_require__2(63814);
var GetPoints = __webpack_require__2(9564);
var GEOM_CONST = __webpack_require__2(23777);
var Polygon = new Class({
initialize: function Polygon2(points) {
this.type = GEOM_CONST.POLYGON;
this.area = 0;
this.points = [];
if (points) {
this.setTo(points);
}
},
/**
* Check to see if the Polygon contains the given x / y coordinates.
*
* @method Phaser.Geom.Polygon#contains
* @since 3.0.0
*
* @param {number} x - The x coordinate to check within the polygon.
* @param {number} y - The y coordinate to check within the polygon.
*
* @return {boolean} `true` if the coordinates are within the polygon, otherwise `false`.
*/
contains: function(x, y) {
return Contains(this, x, y);
},
/**
* Sets this Polygon to the given points.
*
* The points can be set from a variety of formats:
*
* - A string containing paired values separated by a single space: `'40 0 40 20 100 20 100 80 40 80 40 100 0 50'`
* - An array of Point objects: `[new Phaser.Point(x1, y1), ...]`
* - An array of objects with public x/y properties: `[obj1, obj2, ...]`
* - An array of paired numbers that represent point coordinates: `[x1,y1, x2,y2, ...]`
* - An array of arrays with two elements representing x/y coordinates: `[[x1, y1], [x2, y2], ...]`
*
* `setTo` may also be called without any arguments to remove all points.
*
* @method Phaser.Geom.Polygon#setTo
* @since 3.0.0
*
* @param {(string|number[]|Phaser.Types.Math.Vector2Like[])} [points] - Points defining the perimeter of this polygon. Please check function description above for the different supported formats.
*
* @return {this} This Polygon object.
*/
setTo: function(points) {
this.area = 0;
this.points = [];
if (typeof points === "string") {
points = points.split(" ");
}
if (!Array.isArray(points)) {
return this;
}
var p;
for (var i = 0; i < points.length; i++) {
p = { x: 0, y: 0 };
if (typeof points[i] === "number" || typeof points[i] === "string") {
p.x = parseFloat(points[i]);
p.y = parseFloat(points[i + 1]);
i++;
} else if (Array.isArray(points[i])) {
p.x = points[i][0];
p.y = points[i][1];
} else {
p.x = points[i].x;
p.y = points[i].y;
}
this.points.push(p);
}
this.calculateArea();
return this;
},
/**
* Calculates the area of the Polygon. This is available in the property Polygon.area
*
* @method Phaser.Geom.Polygon#calculateArea
* @since 3.0.0
*
* @return {number} The area of the polygon.
*/
calculateArea: function() {
if (this.points.length < 3) {
this.area = 0;
return this.area;
}
var sum = 0;
var p1;
var p2;
for (var i = 0; i < this.points.length - 1; i++) {
p1 = this.points[i];
p2 = this.points[i + 1];
sum += (p2.x - p1.x) * (p1.y + p2.y);
}
p1 = this.points[0];
p2 = this.points[this.points.length - 1];
sum += (p1.x - p2.x) * (p2.y + p1.y);
this.area = -sum * 0.5;
return this.area;
},
/**
* Returns an array of Point objects containing the coordinates of the points around the perimeter of the Polygon,
* based on the given quantity or stepRate values.
*
* @method Phaser.Geom.Polygon#getPoints
* @since 3.12.0
*
* @generic {Phaser.Geom.Point[]} O - [output,$return]
*
* @param {number} quantity - The amount of points to return. If a falsey value the quantity will be derived from the `stepRate` instead.
* @param {number} [stepRate] - Sets the quantity by getting the perimeter of the Polygon and dividing it by the stepRate.
* @param {(array|Phaser.Geom.Point[])} [output] - An array to insert the points in to. If not provided a new array will be created.
*
* @return {(array|Phaser.Geom.Point[])} An array of Point objects pertaining to the points around the perimeter of the Polygon.
*/
getPoints: function(quantity, step, output) {
return GetPoints(this, quantity, step, output);
}
});
module2.exports = Polygon;
}
),
/***/
8133: (
/***/
(module2) => {
var Reverse = function(polygon) {
polygon.points.reverse();
return polygon;
};
module2.exports = Reverse;
}
),
/***/
29524: (
/***/
(module2) => {
function getSqDist(p1, p2) {
var dx = p1.x - p2.x, dy = p1.y - p2.y;
return dx * dx + dy * dy;
}
function getSqSegDist(p, p1, p2) {
var x = p1.x, y = p1.y, dx = p2.x - x, dy = p2.y - y;
if (dx !== 0 || dy !== 0) {
var t = ((p.x - x) * dx + (p.y - y) * dy) / (dx * dx + dy * dy);
if (t > 1) {
x = p2.x;
y = p2.y;
} else if (t > 0) {
x += dx * t;
y += dy * t;
}
}
dx = p.x - x;
dy = p.y - y;
return dx * dx + dy * dy;
}
function simplifyRadialDist(points, sqTolerance) {
var prevPoint = points[0], newPoints = [prevPoint], point;
for (var i = 1, len = points.length; i < len; i++) {
point = points[i];
if (getSqDist(point, prevPoint) > sqTolerance) {
newPoints.push(point);
prevPoint = point;
}
}
if (prevPoint !== point) {
newPoints.push(point);
}
return newPoints;
}
function simplifyDPStep(points, first, last, sqTolerance, simplified) {
var maxSqDist = sqTolerance, index;
for (var i = first + 1; i < last; i++) {
var sqDist = getSqSegDist(points[i], points[first], points[last]);
if (sqDist > maxSqDist) {
index = i;
maxSqDist = sqDist;
}
}
if (maxSqDist > sqTolerance) {
if (index - first > 1) {
simplifyDPStep(points, first, index, sqTolerance, simplified);
}
simplified.push(points[index]);
if (last - index > 1) {
simplifyDPStep(points, index, last, sqTolerance, simplified);
}
}
}
function simplifyDouglasPeucker(points, sqTolerance) {
var last = points.length - 1;
var simplified = [points[0]];
simplifyDPStep(points, 0, last, sqTolerance, simplified);
simplified.push(points[last]);
return simplified;
}
var Simplify = function(polygon, tolerance, highestQuality) {
if (tolerance === void 0) {
tolerance = 1;
}
if (highestQuality === void 0) {
highestQuality = false;
}
var points = polygon.points;
if (points.length > 2) {
var sqTolerance = tolerance * tolerance;
if (!highestQuality) {
points = simplifyRadialDist(points, sqTolerance);
}
polygon.setTo(simplifyDouglasPeucker(points, sqTolerance));
}
return polygon;
};
module2.exports = Simplify;
}
),
/***/
5469: (
/***/
(module2) => {
var copy = function(out, a) {
out[0] = a[0];
out[1] = a[1];
return out;
};
var Smooth = function(polygon) {
var i;
var points = [];
var data = polygon.points;
for (i = 0; i < data.length; i++) {
points.push([data[i].x, data[i].y]);
}
var output = [];
if (points.length > 0) {
output.push(copy([0, 0], points[0]));
}
for (i = 0; i < points.length - 1; i++) {
var p0 = points[i];
var p1 = points[i + 1];
var p0x = p0[0];
var p0y = p0[1];
var p1x = p1[0];
var p1y = p1[1];
output.push([0.85 * p0x + 0.15 * p1x, 0.85 * p0y + 0.15 * p1y]);
output.push([0.15 * p0x + 0.85 * p1x, 0.15 * p0y + 0.85 * p1y]);
}
if (points.length > 1) {
output.push(copy([0, 0], points[points.length - 1]));
}
return polygon.setTo(output);
};
module2.exports = Smooth;
}
),
/***/
24709: (
/***/
(module2) => {
var Translate = function(polygon, x, y) {
var points = polygon.points;
for (var i = 0; i < points.length; i++) {
points[i].x += x;
points[i].y += y;
}
return polygon;
};
module2.exports = Translate;
}
),
/***/
58423: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Polygon = __webpack_require__2(25717);
Polygon.Clone = __webpack_require__2(12306);
Polygon.Contains = __webpack_require__2(63814);
Polygon.ContainsPoint = __webpack_require__2(99338);
Polygon.Earcut = __webpack_require__2(94811);
Polygon.GetAABB = __webpack_require__2(13829);
Polygon.GetNumberArray = __webpack_require__2(26173);
Polygon.GetPoints = __webpack_require__2(9564);
Polygon.Perimeter = __webpack_require__2(30052);
Polygon.Reverse = __webpack_require__2(8133);
Polygon.Simplify = __webpack_require__2(29524);
Polygon.Smooth = __webpack_require__2(5469);
Polygon.Translate = __webpack_require__2(24709);
module2.exports = Polygon;
}
),
/***/
62224: (
/***/
(module2) => {
var Area = function(rect) {
return rect.width * rect.height;
};
module2.exports = Area;
}
),
/***/
98615: (
/***/
(module2) => {
var Ceil = function(rect) {
rect.x = Math.ceil(rect.x);
rect.y = Math.ceil(rect.y);
return rect;
};
module2.exports = Ceil;
}
),
/***/
31688: (
/***/
(module2) => {
var CeilAll = function(rect) {
rect.x = Math.ceil(rect.x);
rect.y = Math.ceil(rect.y);
rect.width = Math.ceil(rect.width);
rect.height = Math.ceil(rect.height);
return rect;
};
module2.exports = CeilAll;
}
),
/***/
67502: (
/***/
(module2) => {
var CenterOn = function(rect, x, y) {
rect.x = x - rect.width / 2;
rect.y = y - rect.height / 2;
return rect;
};
module2.exports = CenterOn;
}
),
/***/
65085: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Rectangle = __webpack_require__2(87841);
var Clone = function(source) {
return new Rectangle(source.x, source.y, source.width, source.height);
};
module2.exports = Clone;
}
),
/***/
37303: (
/***/
(module2) => {
var Contains = function(rect, x, y) {
if (rect.width <= 0 || rect.height <= 0) {
return false;
}
return rect.x <= x && rect.x + rect.width >= x && rect.y <= y && rect.y + rect.height >= y;
};
module2.exports = Contains;
}
),
/***/
96553: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Contains = __webpack_require__2(37303);
var ContainsPoint = function(rect, point) {
return Contains(rect, point.x, point.y);
};
module2.exports = ContainsPoint;
}
),
/***/
70273: (
/***/
(module2) => {
var ContainsRect = function(rectA, rectB) {
if (rectB.width * rectB.height > rectA.width * rectA.height) {
return false;
}
return rectB.x > rectA.x && rectB.x < rectA.right && (rectB.right > rectA.x && rectB.right < rectA.right) && (rectB.y > rectA.y && rectB.y < rectA.bottom) && (rectB.bottom > rectA.y && rectB.bottom < rectA.bottom);
};
module2.exports = ContainsRect;
}
),
/***/
43459: (
/***/
(module2) => {
var CopyFrom = function(source, dest) {
return dest.setTo(source.x, source.y, source.width, source.height);
};
module2.exports = CopyFrom;
}
),
/***/
77493: (
/***/
(module2) => {
var Decompose = function(rect, out) {
if (out === void 0) {
out = [];
}
out.push({ x: rect.x, y: rect.y });
out.push({ x: rect.right, y: rect.y });
out.push({ x: rect.right, y: rect.bottom });
out.push({ x: rect.x, y: rect.bottom });
return out;
};
module2.exports = Decompose;
}
),
/***/
9219: (
/***/
(module2) => {
var Equals = function(rect, toCompare) {
return rect.x === toCompare.x && rect.y === toCompare.y && rect.width === toCompare.width && rect.height === toCompare.height;
};
module2.exports = Equals;
}
),
/***/
53751: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetAspectRatio = __webpack_require__2(8249);
var FitInside = function(target, source) {
var ratio = GetAspectRatio(target);
if (ratio < GetAspectRatio(source)) {
target.setSize(source.height * ratio, source.height);
} else {
target.setSize(source.width, source.width / ratio);
}
return target.setPosition(
source.centerX - target.width / 2,
source.centerY - target.height / 2
);
};
module2.exports = FitInside;
}
),
/***/
16088: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetAspectRatio = __webpack_require__2(8249);
var FitOutside = function(target, source) {
var ratio = GetAspectRatio(target);
if (ratio > GetAspectRatio(source)) {
target.setSize(source.height * ratio, source.height);
} else {
target.setSize(source.width, source.width / ratio);
}
return target.setPosition(
source.centerX - target.width / 2,
source.centerY - target.height / 2
);
};
module2.exports = FitOutside;
}
),
/***/
80774: (
/***/
(module2) => {
var Floor = function(rect) {
rect.x = Math.floor(rect.x);
rect.y = Math.floor(rect.y);
return rect;
};
module2.exports = Floor;
}
),
/***/
83859: (
/***/
(module2) => {
var FloorAll = function(rect) {
rect.x = Math.floor(rect.x);
rect.y = Math.floor(rect.y);
rect.width = Math.floor(rect.width);
rect.height = Math.floor(rect.height);
return rect;
};
module2.exports = FloorAll;
}
),
/***/
19217: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Rectangle = __webpack_require__2(87841);
var MATH_CONST = __webpack_require__2(36383);
var FromPoints = function(points, out) {
if (out === void 0) {
out = new Rectangle();
}
if (points.length === 0) {
return out;
}
var minX = Number.MAX_VALUE;
var minY = Number.MAX_VALUE;
var maxX = MATH_CONST.MIN_SAFE_INTEGER;
var maxY = MATH_CONST.MIN_SAFE_INTEGER;
var p;
var px;
var py;
for (var i = 0; i < points.length; i++) {
p = points[i];
if (Array.isArray(p)) {
px = p[0];
py = p[1];
} else {
px = p.x;
py = p.y;
}
minX = Math.min(minX, px);
minY = Math.min(minY, py);
maxX = Math.max(maxX, px);
maxY = Math.max(maxY, py);
}
out.x = minX;
out.y = minY;
out.width = maxX - minX;
out.height = maxY - minY;
return out;
};
module2.exports = FromPoints;
}
),
/***/
9477: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Rectangle = __webpack_require__2(87841);
var FromXY = function(x1, y1, x2, y2, out) {
if (out === void 0) {
out = new Rectangle();
}
return out.setTo(
Math.min(x1, x2),
Math.min(y1, y2),
Math.abs(x1 - x2),
Math.abs(y1 - y2)
);
};
module2.exports = FromXY;
}
),
/***/
8249: (
/***/
(module2) => {
var GetAspectRatio = function(rect) {
return rect.height === 0 ? NaN : rect.width / rect.height;
};
module2.exports = GetAspectRatio;
}
),
/***/
27165: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
var GetCenter = function(rect, out) {
if (out === void 0) {
out = new Point();
}
out.x = rect.centerX;
out.y = rect.centerY;
return out;
};
module2.exports = GetCenter;
}
),
/***/
20812: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Perimeter = __webpack_require__2(13019);
var Point = __webpack_require__2(2141);
var GetPoint = function(rectangle, position, out) {
if (out === void 0) {
out = new Point();
}
if (position <= 0 || position >= 1) {
out.x = rectangle.x;
out.y = rectangle.y;
return out;
}
var p = Perimeter(rectangle) * position;
if (position > 0.5) {
p -= rectangle.width + rectangle.height;
if (p <= rectangle.width) {
out.x = rectangle.right - p;
out.y = rectangle.bottom;
} else {
out.x = rectangle.x;
out.y = rectangle.bottom - (p - rectangle.width);
}
} else if (p <= rectangle.width) {
out.x = rectangle.x + p;
out.y = rectangle.y;
} else {
out.x = rectangle.right;
out.y = rectangle.y + (p - rectangle.width);
}
return out;
};
module2.exports = GetPoint;
}
),
/***/
34819: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetPoint = __webpack_require__2(20812);
var Perimeter = __webpack_require__2(13019);
var GetPoints = function(rectangle, quantity, stepRate, out) {
if (out === void 0) {
out = [];
}
if (!quantity && stepRate > 0) {
quantity = Perimeter(rectangle) / stepRate;
}
for (var i = 0; i < quantity; i++) {
var position = i / quantity;
out.push(GetPoint(rectangle, position));
}
return out;
};
module2.exports = GetPoints;
}
),
/***/
51313: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
var GetSize = function(rect, out) {
if (out === void 0) {
out = new Point();
}
out.x = rect.width;
out.y = rect.height;
return out;
};
module2.exports = GetSize;
}
),
/***/
86091: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CenterOn = __webpack_require__2(67502);
var Inflate = function(rect, x, y) {
var cx = rect.centerX;
var cy = rect.centerY;
rect.setSize(rect.width + x * 2, rect.height + y * 2);
return CenterOn(rect, cx, cy);
};
module2.exports = Inflate;
}
),
/***/
53951: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Rectangle = __webpack_require__2(87841);
var Intersects = __webpack_require__2(59996);
var Intersection = function(rectA, rectB, out) {
if (out === void 0) {
out = new Rectangle();
}
if (Intersects(rectA, rectB)) {
out.x = Math.max(rectA.x, rectB.x);
out.y = Math.max(rectA.y, rectB.y);
out.width = Math.min(rectA.right, rectB.right) - out.x;
out.height = Math.min(rectA.bottom, rectB.bottom) - out.y;
} else {
out.setEmpty();
}
return out;
};
module2.exports = Intersection;
}
),
/***/
14649: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Perimeter = __webpack_require__2(13019);
var Point = __webpack_require__2(2141);
var MarchingAnts = function(rect, step, quantity, out) {
if (out === void 0) {
out = [];
}
if (!step && !quantity) {
return out;
}
if (!step) {
step = Perimeter(rect) / quantity;
} else {
quantity = Math.round(Perimeter(rect) / step);
}
var x = rect.x;
var y = rect.y;
var face = 0;
for (var i = 0; i < quantity; i++) {
out.push(new Point(x, y));
switch (face) {
case 0:
x += step;
if (x >= rect.right) {
face = 1;
y += x - rect.right;
x = rect.right;
}
break;
case 1:
y += step;
if (y >= rect.bottom) {
face = 2;
x -= y - rect.bottom;
y = rect.bottom;
}
break;
case 2:
x -= step;
if (x <= rect.left) {
face = 3;
y -= rect.left - x;
x = rect.left;
}
break;
case 3:
y -= step;
if (y <= rect.top) {
face = 0;
y = rect.top;
}
break;
}
}
return out;
};
module2.exports = MarchingAnts;
}
),
/***/
33595: (
/***/
(module2) => {
var MergePoints = function(target, points) {
var minX = target.x;
var maxX = target.right;
var minY = target.y;
var maxY = target.bottom;
for (var i = 0; i < points.length; i++) {
minX = Math.min(minX, points[i].x);
maxX = Math.max(maxX, points[i].x);
minY = Math.min(minY, points[i].y);
maxY = Math.max(maxY, points[i].y);
}
target.x = minX;
target.y = minY;
target.width = maxX - minX;
target.height = maxY - minY;
return target;
};
module2.exports = MergePoints;
}
),
/***/
20074: (
/***/
(module2) => {
var MergeRect = function(target, source) {
var minX = Math.min(target.x, source.x);
var maxX = Math.max(target.right, source.right);
target.x = minX;
target.width = maxX - minX;
var minY = Math.min(target.y, source.y);
var maxY = Math.max(target.bottom, source.bottom);
target.y = minY;
target.height = maxY - minY;
return target;
};
module2.exports = MergeRect;
}
),
/***/
92171: (
/***/
(module2) => {
var MergeXY = function(target, x, y) {
var minX = Math.min(target.x, x);
var maxX = Math.max(target.right, x);
target.x = minX;
target.width = maxX - minX;
var minY = Math.min(target.y, y);
var maxY = Math.max(target.bottom, y);
target.y = minY;
target.height = maxY - minY;
return target;
};
module2.exports = MergeXY;
}
),
/***/
42981: (
/***/
(module2) => {
var Offset = function(rect, x, y) {
rect.x += x;
rect.y += y;
return rect;
};
module2.exports = Offset;
}
),
/***/
46907: (
/***/
(module2) => {
var OffsetPoint = function(rect, point) {
rect.x += point.x;
rect.y += point.y;
return rect;
};
module2.exports = OffsetPoint;
}
),
/***/
60170: (
/***/
(module2) => {
var Overlaps = function(rectA, rectB) {
return rectA.x < rectB.right && rectA.right > rectB.x && rectA.y < rectB.bottom && rectA.bottom > rectB.y;
};
module2.exports = Overlaps;
}
),
/***/
13019: (
/***/
(module2) => {
var Perimeter = function(rect) {
return 2 * (rect.width + rect.height);
};
module2.exports = Perimeter;
}
),
/***/
85133: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
var DegToRad = __webpack_require__2(39506);
var PerimeterPoint = function(rectangle, angle, out) {
if (out === void 0) {
out = new Point();
}
angle = DegToRad(angle);
var s = Math.sin(angle);
var c = Math.cos(angle);
var dx = c > 0 ? rectangle.width / 2 : rectangle.width / -2;
var dy = s > 0 ? rectangle.height / 2 : rectangle.height / -2;
if (Math.abs(dx * s) < Math.abs(dy * c)) {
dy = dx * s / c;
} else {
dx = dy * c / s;
}
out.x = dx + rectangle.centerX;
out.y = dy + rectangle.centerY;
return out;
};
module2.exports = PerimeterPoint;
}
),
/***/
26597: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
var Random = function(rect, out) {
if (out === void 0) {
out = new Point();
}
out.x = rect.x + Math.random() * rect.width;
out.y = rect.y + Math.random() * rect.height;
return out;
};
module2.exports = Random;
}
),
/***/
86470: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Between = __webpack_require__2(30976);
var ContainsRect = __webpack_require__2(70273);
var Point = __webpack_require__2(2141);
var RandomOutside = function(outer, inner, out) {
if (out === void 0) {
out = new Point();
}
if (ContainsRect(outer, inner)) {
switch (Between(0, 3)) {
case 0:
out.x = outer.x + Math.random() * (inner.right - outer.x);
out.y = outer.y + Math.random() * (inner.top - outer.y);
break;
case 1:
out.x = inner.x + Math.random() * (outer.right - inner.x);
out.y = inner.bottom + Math.random() * (outer.bottom - inner.bottom);
break;
case 2:
out.x = outer.x + Math.random() * (inner.x - outer.x);
out.y = inner.y + Math.random() * (outer.bottom - inner.y);
break;
case 3:
out.x = inner.right + Math.random() * (outer.right - inner.right);
out.y = outer.y + Math.random() * (inner.bottom - outer.y);
break;
}
}
return out;
};
module2.exports = RandomOutside;
}
),
/***/
87841: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Contains = __webpack_require__2(37303);
var GetPoint = __webpack_require__2(20812);
var GetPoints = __webpack_require__2(34819);
var GEOM_CONST = __webpack_require__2(23777);
var Line = __webpack_require__2(23031);
var Random = __webpack_require__2(26597);
var Rectangle = new Class({
initialize: function Rectangle2(x, y, width, height) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (width === void 0) {
width = 0;
}
if (height === void 0) {
height = 0;
}
this.type = GEOM_CONST.RECTANGLE;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
},
/**
* Checks if the given point is inside the Rectangle's bounds.
*
* @method Phaser.Geom.Rectangle#contains
* @since 3.0.0
*
* @param {number} x - The X coordinate of the point to check.
* @param {number} y - The Y coordinate of the point to check.
*
* @return {boolean} `true` if the point is within the Rectangle's bounds, otherwise `false`.
*/
contains: function(x, y) {
return Contains(this, x, y);
},
/**
* Calculates the coordinates of a point at a certain `position` on the Rectangle's perimeter.
*
* The `position` is a fraction between 0 and 1 which defines how far into the perimeter the point is.
*
* A value of 0 or 1 returns the point at the top left corner of the rectangle, while a value of 0.5 returns the point at the bottom right corner of the rectangle. Values between 0 and 0.5 are on the top or the right side and values between 0.5 and 1 are on the bottom or the left side.
*
* @method Phaser.Geom.Rectangle#getPoint
* @since 3.0.0
*
* @generic {Phaser.Geom.Point} O - [output,$return]
*
* @param {number} position - The normalized distance into the Rectangle's perimeter to return.
* @param {(Phaser.Geom.Point|object)} [output] - An object to update with the `x` and `y` coordinates of the point.
*
* @return {(Phaser.Geom.Point|object)} The updated `output` object, or a new Point if no `output` object was given.
*/
getPoint: function(position, output) {
return GetPoint(this, position, output);
},
/**
* Returns an array of points from the perimeter of the Rectangle, each spaced out based on the quantity or step required.
*
* @method Phaser.Geom.Rectangle#getPoints
* @since 3.0.0
*
* @generic {Phaser.Geom.Point[]} O - [output,$return]
*
* @param {number} quantity - The number of points to return. Set to `false` or 0 to return an arbitrary number of points (`perimeter / stepRate`) evenly spaced around the Rectangle based on the `stepRate`.
* @param {number} [stepRate] - If `quantity` is 0, determines the normalized distance between each returned point.
* @param {(array|Phaser.Geom.Point[])} [output] - An array to which to append the points.
*
* @return {(array|Phaser.Geom.Point[])} The modified `output` array, or a new array if none was provided.
*/
getPoints: function(quantity, stepRate, output) {
return GetPoints(this, quantity, stepRate, output);
},
/**
* Returns a random point within the Rectangle's bounds.
*
* @method Phaser.Geom.Rectangle#getRandomPoint
* @since 3.0.0
*
* @generic {Phaser.Geom.Point} O - [point,$return]
*
* @param {Phaser.Geom.Point} [point] - The object in which to store the `x` and `y` coordinates of the point.
*
* @return {Phaser.Geom.Point} The updated `point`, or a new Point if none was provided.
*/
getRandomPoint: function(point) {
return Random(this, point);
},
/**
* Sets the position, width, and height of the Rectangle.
*
* @method Phaser.Geom.Rectangle#setTo
* @since 3.0.0
*
* @param {number} x - The X coordinate of the top left corner of the Rectangle.
* @param {number} y - The Y coordinate of the top left corner of the Rectangle.
* @param {number} width - The width of the Rectangle.
* @param {number} height - The height of the Rectangle.
*
* @return {this} This Rectangle object.
*/
setTo: function(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
return this;
},
/**
* Resets the position, width, and height of the Rectangle to 0.
*
* @method Phaser.Geom.Rectangle#setEmpty
* @since 3.0.0
*
* @return {this} This Rectangle object.
*/
setEmpty: function() {
return this.setTo(0, 0, 0, 0);
},
/**
* Sets the position of the Rectangle.
*
* @method Phaser.Geom.Rectangle#setPosition
* @since 3.0.0
*
* @param {number} x - The X coordinate of the top left corner of the Rectangle.
* @param {number} [y=x] - The Y coordinate of the top left corner of the Rectangle.
*
* @return {this} This Rectangle object.
*/
setPosition: function(x, y) {
if (y === void 0) {
y = x;
}
this.x = x;
this.y = y;
return this;
},
/**
* Sets the width and height of the Rectangle.
*
* @method Phaser.Geom.Rectangle#setSize
* @since 3.0.0
*
* @param {number} width - The width to set the Rectangle to.
* @param {number} [height=width] - The height to set the Rectangle to.
*
* @return {this} This Rectangle object.
*/
setSize: function(width, height) {
if (height === void 0) {
height = width;
}
this.width = width;
this.height = height;
return this;
},
/**
* Determines if the Rectangle is empty. A Rectangle is empty if its width or height is less than or equal to 0.
*
* @method Phaser.Geom.Rectangle#isEmpty
* @since 3.0.0
*
* @return {boolean} `true` if the Rectangle is empty. A Rectangle object is empty if its width or height is less than or equal to 0.
*/
isEmpty: function() {
return this.width <= 0 || this.height <= 0;
},
/**
* Returns a Line object that corresponds to the top of this Rectangle.
*
* @method Phaser.Geom.Rectangle#getLineA
* @since 3.0.0
*
* @generic {Phaser.Geom.Line} O - [line,$return]
*
* @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created.
*
* @return {Phaser.Geom.Line} A Line object that corresponds to the top of this Rectangle.
*/
getLineA: function(line) {
if (line === void 0) {
line = new Line();
}
line.setTo(this.x, this.y, this.right, this.y);
return line;
},
/**
* Returns a Line object that corresponds to the right of this Rectangle.
*
* @method Phaser.Geom.Rectangle#getLineB
* @since 3.0.0
*
* @generic {Phaser.Geom.Line} O - [line,$return]
*
* @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created.
*
* @return {Phaser.Geom.Line} A Line object that corresponds to the right of this Rectangle.
*/
getLineB: function(line) {
if (line === void 0) {
line = new Line();
}
line.setTo(this.right, this.y, this.right, this.bottom);
return line;
},
/**
* Returns a Line object that corresponds to the bottom of this Rectangle.
*
* @method Phaser.Geom.Rectangle#getLineC
* @since 3.0.0
*
* @generic {Phaser.Geom.Line} O - [line,$return]
*
* @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created.
*
* @return {Phaser.Geom.Line} A Line object that corresponds to the bottom of this Rectangle.
*/
getLineC: function(line) {
if (line === void 0) {
line = new Line();
}
line.setTo(this.right, this.bottom, this.x, this.bottom);
return line;
},
/**
* Returns a Line object that corresponds to the left of this Rectangle.
*
* @method Phaser.Geom.Rectangle#getLineD
* @since 3.0.0
*
* @generic {Phaser.Geom.Line} O - [line,$return]
*
* @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created.
*
* @return {Phaser.Geom.Line} A Line object that corresponds to the left of this Rectangle.
*/
getLineD: function(line) {
if (line === void 0) {
line = new Line();
}
line.setTo(this.x, this.bottom, this.x, this.y);
return line;
},
/**
* The x coordinate of the left of the Rectangle.
* Changing the left property of a Rectangle object has no effect on the y and height properties. However it does affect the width property, whereas changing the x value does not affect the width property.
*
* @name Phaser.Geom.Rectangle#left
* @type {number}
* @since 3.0.0
*/
left: {
get: function() {
return this.x;
},
set: function(value) {
if (value >= this.right) {
this.width = 0;
} else {
this.width = this.right - value;
}
this.x = value;
}
},
/**
* The sum of the x and width properties.
* Changing the right property of a Rectangle object has no effect on the x, y and height properties, however it does affect the width property.
*
* @name Phaser.Geom.Rectangle#right
* @type {number}
* @since 3.0.0
*/
right: {
get: function() {
return this.x + this.width;
},
set: function(value) {
if (value <= this.x) {
this.width = 0;
} else {
this.width = value - this.x;
}
}
},
/**
* The y coordinate of the top of the Rectangle. Changing the top property of a Rectangle object has no effect on the x and width properties.
* However it does affect the height property, whereas changing the y value does not affect the height property.
*
* @name Phaser.Geom.Rectangle#top
* @type {number}
* @since 3.0.0
*/
top: {
get: function() {
return this.y;
},
set: function(value) {
if (value >= this.bottom) {
this.height = 0;
} else {
this.height = this.bottom - value;
}
this.y = value;
}
},
/**
* The sum of the y and height properties.
* Changing the bottom property of a Rectangle object has no effect on the x, y and width properties, but does change the height property.
*
* @name Phaser.Geom.Rectangle#bottom
* @type {number}
* @since 3.0.0
*/
bottom: {
get: function() {
return this.y + this.height;
},
set: function(value) {
if (value <= this.y) {
this.height = 0;
} else {
this.height = value - this.y;
}
}
},
/**
* The x coordinate of the center of the Rectangle.
*
* @name Phaser.Geom.Rectangle#centerX
* @type {number}
* @since 3.0.0
*/
centerX: {
get: function() {
return this.x + this.width / 2;
},
set: function(value) {
this.x = value - this.width / 2;
}
},
/**
* The y coordinate of the center of the Rectangle.
*
* @name Phaser.Geom.Rectangle#centerY
* @type {number}
* @since 3.0.0
*/
centerY: {
get: function() {
return this.y + this.height / 2;
},
set: function(value) {
this.y = value - this.height / 2;
}
}
});
module2.exports = Rectangle;
}
),
/***/
94845: (
/***/
(module2) => {
var SameDimensions = function(rect, toCompare) {
return rect.width === toCompare.width && rect.height === toCompare.height;
};
module2.exports = SameDimensions;
}
),
/***/
31730: (
/***/
(module2) => {
var Scale = function(rect, x, y) {
if (y === void 0) {
y = x;
}
rect.width *= x;
rect.height *= y;
return rect;
};
module2.exports = Scale;
}
),
/***/
36899: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Rectangle = __webpack_require__2(87841);
var Union = function(rectA, rectB, out) {
if (out === void 0) {
out = new Rectangle();
}
var x = Math.min(rectA.x, rectB.x);
var y = Math.min(rectA.y, rectB.y);
var w = Math.max(rectA.right, rectB.right) - x;
var h = Math.max(rectA.bottom, rectB.bottom) - y;
return out.setTo(x, y, w, h);
};
module2.exports = Union;
}
),
/***/
93232: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Rectangle = __webpack_require__2(87841);
Rectangle.Area = __webpack_require__2(62224);
Rectangle.Ceil = __webpack_require__2(98615);
Rectangle.CeilAll = __webpack_require__2(31688);
Rectangle.CenterOn = __webpack_require__2(67502);
Rectangle.Clone = __webpack_require__2(65085);
Rectangle.Contains = __webpack_require__2(37303);
Rectangle.ContainsPoint = __webpack_require__2(96553);
Rectangle.ContainsRect = __webpack_require__2(70273);
Rectangle.CopyFrom = __webpack_require__2(43459);
Rectangle.Decompose = __webpack_require__2(77493);
Rectangle.Equals = __webpack_require__2(9219);
Rectangle.FitInside = __webpack_require__2(53751);
Rectangle.FitOutside = __webpack_require__2(16088);
Rectangle.Floor = __webpack_require__2(80774);
Rectangle.FloorAll = __webpack_require__2(83859);
Rectangle.FromPoints = __webpack_require__2(19217);
Rectangle.FromXY = __webpack_require__2(9477);
Rectangle.GetAspectRatio = __webpack_require__2(8249);
Rectangle.GetCenter = __webpack_require__2(27165);
Rectangle.GetPoint = __webpack_require__2(20812);
Rectangle.GetPoints = __webpack_require__2(34819);
Rectangle.GetSize = __webpack_require__2(51313);
Rectangle.Inflate = __webpack_require__2(86091);
Rectangle.Intersection = __webpack_require__2(53951);
Rectangle.MarchingAnts = __webpack_require__2(14649);
Rectangle.MergePoints = __webpack_require__2(33595);
Rectangle.MergeRect = __webpack_require__2(20074);
Rectangle.MergeXY = __webpack_require__2(92171);
Rectangle.Offset = __webpack_require__2(42981);
Rectangle.OffsetPoint = __webpack_require__2(46907);
Rectangle.Overlaps = __webpack_require__2(60170);
Rectangle.Perimeter = __webpack_require__2(13019);
Rectangle.PerimeterPoint = __webpack_require__2(85133);
Rectangle.Random = __webpack_require__2(26597);
Rectangle.RandomOutside = __webpack_require__2(86470);
Rectangle.SameDimensions = __webpack_require__2(94845);
Rectangle.Scale = __webpack_require__2(31730);
Rectangle.Union = __webpack_require__2(36899);
module2.exports = Rectangle;
}
),
/***/
41658: (
/***/
(module2) => {
var Area = function(triangle) {
var x1 = triangle.x1;
var y1 = triangle.y1;
var x2 = triangle.x2;
var y2 = triangle.y2;
var x3 = triangle.x3;
var y3 = triangle.y3;
return Math.abs(((x3 - x1) * (y2 - y1) - (x2 - x1) * (y3 - y1)) / 2);
};
module2.exports = Area;
}
),
/***/
39208: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Triangle = __webpack_require__2(16483);
var BuildEquilateral = function(x, y, length) {
var height = length * (Math.sqrt(3) / 2);
var x1 = x;
var y1 = y;
var x2 = x + length / 2;
var y2 = y + height;
var x3 = x - length / 2;
var y3 = y + height;
return new Triangle(x1, y1, x2, y2, x3, y3);
};
module2.exports = BuildEquilateral;
}
),
/***/
39545: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var EarCut = __webpack_require__2(94811);
var Triangle = __webpack_require__2(16483);
var BuildFromPolygon = function(data, holes, scaleX, scaleY, out) {
if (holes === void 0) {
holes = null;
}
if (scaleX === void 0) {
scaleX = 1;
}
if (scaleY === void 0) {
scaleY = 1;
}
if (out === void 0) {
out = [];
}
var tris = EarCut(data, holes);
var a;
var b;
var c;
var x1;
var y1;
var x2;
var y2;
var x3;
var y3;
for (var i = 0; i < tris.length; i += 3) {
a = tris[i];
b = tris[i + 1];
c = tris[i + 2];
x1 = data[a * 2] * scaleX;
y1 = data[a * 2 + 1] * scaleY;
x2 = data[b * 2] * scaleX;
y2 = data[b * 2 + 1] * scaleY;
x3 = data[c * 2] * scaleX;
y3 = data[c * 2 + 1] * scaleY;
out.push(new Triangle(x1, y1, x2, y2, x3, y3));
}
return out;
};
module2.exports = BuildFromPolygon;
}
),
/***/
90301: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Triangle = __webpack_require__2(16483);
var BuildRight = function(x, y, width, height) {
if (height === void 0) {
height = width;
}
var x1 = x;
var y1 = y;
var x2 = x;
var y2 = y - height;
var x3 = x + width;
var y3 = y;
return new Triangle(x1, y1, x2, y2, x3, y3);
};
module2.exports = BuildRight;
}
),
/***/
23707: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Centroid = __webpack_require__2(97523);
var Offset = __webpack_require__2(13584);
var CenterOn = function(triangle, x, y, centerFunc) {
if (centerFunc === void 0) {
centerFunc = Centroid;
}
var center = centerFunc(triangle);
var diffX = x - center.x;
var diffY = y - center.y;
return Offset(triangle, diffX, diffY);
};
module2.exports = CenterOn;
}
),
/***/
97523: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
var Centroid = function(triangle, out) {
if (out === void 0) {
out = new Point();
}
out.x = (triangle.x1 + triangle.x2 + triangle.x3) / 3;
out.y = (triangle.y1 + triangle.y2 + triangle.y3) / 3;
return out;
};
module2.exports = Centroid;
}
),
/***/
24951: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Vector2 = __webpack_require__2(26099);
function det(m00, m01, m10, m11) {
return m00 * m11 - m01 * m10;
}
var CircumCenter = function(triangle, out) {
if (out === void 0) {
out = new Vector2();
}
var cx = triangle.x3;
var cy = triangle.y3;
var ax = triangle.x1 - cx;
var ay = triangle.y1 - cy;
var bx = triangle.x2 - cx;
var by = triangle.y2 - cy;
var denom = 2 * det(ax, ay, bx, by);
var numx = det(ay, ax * ax + ay * ay, by, bx * bx + by * by);
var numy = det(ax, ax * ax + ay * ay, bx, bx * bx + by * by);
out.x = cx - numx / denom;
out.y = cy + numy / denom;
return out;
};
module2.exports = CircumCenter;
}
),
/***/
85614: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Circle = __webpack_require__2(96503);
var CircumCircle = function(triangle, out) {
if (out === void 0) {
out = new Circle();
}
var x1 = triangle.x1;
var y1 = triangle.y1;
var x2 = triangle.x2;
var y2 = triangle.y2;
var x3 = triangle.x3;
var y3 = triangle.y3;
var A = x2 - x1;
var B = y2 - y1;
var C = x3 - x1;
var D = y3 - y1;
var E = A * (x1 + x2) + B * (y1 + y2);
var F = C * (x1 + x3) + D * (y1 + y3);
var G = 2 * (A * (y3 - y2) - B * (x3 - x2));
var dx;
var dy;
if (Math.abs(G) < 1e-6) {
var minX = Math.min(x1, x2, x3);
var minY = Math.min(y1, y2, y3);
dx = (Math.max(x1, x2, x3) - minX) * 0.5;
dy = (Math.max(y1, y2, y3) - minY) * 0.5;
out.x = minX + dx;
out.y = minY + dy;
out.radius = Math.sqrt(dx * dx + dy * dy);
} else {
out.x = (D * E - B * F) / G;
out.y = (A * F - C * E) / G;
dx = out.x - x1;
dy = out.y - y1;
out.radius = Math.sqrt(dx * dx + dy * dy);
}
return out;
};
module2.exports = CircumCircle;
}
),
/***/
74422: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Triangle = __webpack_require__2(16483);
var Clone = function(source) {
return new Triangle(source.x1, source.y1, source.x2, source.y2, source.x3, source.y3);
};
module2.exports = Clone;
}
),
/***/
10690: (
/***/
(module2) => {
var Contains = function(triangle, x, y) {
var v0x = triangle.x3 - triangle.x1;
var v0y = triangle.y3 - triangle.y1;
var v1x = triangle.x2 - triangle.x1;
var v1y = triangle.y2 - triangle.y1;
var v2x = x - triangle.x1;
var v2y = y - triangle.y1;
var dot00 = v0x * v0x + v0y * v0y;
var dot01 = v0x * v1x + v0y * v1y;
var dot02 = v0x * v2x + v0y * v2y;
var dot11 = v1x * v1x + v1y * v1y;
var dot12 = v1x * v2x + v1y * v2y;
var b = dot00 * dot11 - dot01 * dot01;
var inv = b === 0 ? 0 : 1 / b;
var u = (dot11 * dot02 - dot01 * dot12) * inv;
var v = (dot00 * dot12 - dot01 * dot02) * inv;
return u >= 0 && v >= 0 && u + v < 1;
};
module2.exports = Contains;
}
),
/***/
48653: (
/***/
(module2) => {
var ContainsArray = function(triangle, points, returnFirst, out) {
if (returnFirst === void 0) {
returnFirst = false;
}
if (out === void 0) {
out = [];
}
var v0x = triangle.x3 - triangle.x1;
var v0y = triangle.y3 - triangle.y1;
var v1x = triangle.x2 - triangle.x1;
var v1y = triangle.y2 - triangle.y1;
var dot00 = v0x * v0x + v0y * v0y;
var dot01 = v0x * v1x + v0y * v1y;
var dot11 = v1x * v1x + v1y * v1y;
var b = dot00 * dot11 - dot01 * dot01;
var inv = b === 0 ? 0 : 1 / b;
var u;
var v;
var v2x;
var v2y;
var dot02;
var dot12;
var x1 = triangle.x1;
var y1 = triangle.y1;
for (var i = 0; i < points.length; i++) {
v2x = points[i].x - x1;
v2y = points[i].y - y1;
dot02 = v0x * v2x + v0y * v2y;
dot12 = v1x * v2x + v1y * v2y;
u = (dot11 * dot02 - dot01 * dot12) * inv;
v = (dot00 * dot12 - dot01 * dot02) * inv;
if (u >= 0 && v >= 0 && u + v < 1) {
out.push({ x: points[i].x, y: points[i].y });
if (returnFirst) {
break;
}
}
}
return out;
};
module2.exports = ContainsArray;
}
),
/***/
96006: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Contains = __webpack_require__2(10690);
var ContainsPoint = function(triangle, point) {
return Contains(triangle, point.x, point.y);
};
module2.exports = ContainsPoint;
}
),
/***/
71326: (
/***/
(module2) => {
var CopyFrom = function(source, dest) {
return dest.setTo(source.x1, source.y1, source.x2, source.y2, source.x3, source.y3);
};
module2.exports = CopyFrom;
}
),
/***/
71694: (
/***/
(module2) => {
var Decompose = function(triangle, out) {
if (out === void 0) {
out = [];
}
out.push({ x: triangle.x1, y: triangle.y1 });
out.push({ x: triangle.x2, y: triangle.y2 });
out.push({ x: triangle.x3, y: triangle.y3 });
return out;
};
module2.exports = Decompose;
}
),
/***/
33522: (
/***/
(module2) => {
var Equals = function(triangle, toCompare) {
return triangle.x1 === toCompare.x1 && triangle.y1 === toCompare.y1 && triangle.x2 === toCompare.x2 && triangle.y2 === toCompare.y2 && triangle.x3 === toCompare.x3 && triangle.y3 === toCompare.y3;
};
module2.exports = Equals;
}
),
/***/
20437: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
var Length = __webpack_require__2(35001);
var GetPoint = function(triangle, position, out) {
if (out === void 0) {
out = new Point();
}
var line1 = triangle.getLineA();
var line2 = triangle.getLineB();
var line3 = triangle.getLineC();
if (position <= 0 || position >= 1) {
out.x = line1.x1;
out.y = line1.y1;
return out;
}
var length1 = Length(line1);
var length2 = Length(line2);
var length3 = Length(line3);
var perimeter = length1 + length2 + length3;
var p = perimeter * position;
var localPosition = 0;
if (p < length1) {
localPosition = p / length1;
out.x = line1.x1 + (line1.x2 - line1.x1) * localPosition;
out.y = line1.y1 + (line1.y2 - line1.y1) * localPosition;
} else if (p > length1 + length2) {
p -= length1 + length2;
localPosition = p / length3;
out.x = line3.x1 + (line3.x2 - line3.x1) * localPosition;
out.y = line3.y1 + (line3.y2 - line3.y1) * localPosition;
} else {
p -= length1;
localPosition = p / length2;
out.x = line2.x1 + (line2.x2 - line2.x1) * localPosition;
out.y = line2.y1 + (line2.y2 - line2.y1) * localPosition;
}
return out;
};
module2.exports = GetPoint;
}
),
/***/
80672: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Length = __webpack_require__2(35001);
var Point = __webpack_require__2(2141);
var GetPoints = function(triangle, quantity, stepRate, out) {
if (out === void 0) {
out = [];
}
var line1 = triangle.getLineA();
var line2 = triangle.getLineB();
var line3 = triangle.getLineC();
var length1 = Length(line1);
var length2 = Length(line2);
var length3 = Length(line3);
var perimeter = length1 + length2 + length3;
if (!quantity && stepRate > 0) {
quantity = perimeter / stepRate;
}
for (var i = 0; i < quantity; i++) {
var p = perimeter * (i / quantity);
var localPosition = 0;
var point = new Point();
if (p < length1) {
localPosition = p / length1;
point.x = line1.x1 + (line1.x2 - line1.x1) * localPosition;
point.y = line1.y1 + (line1.y2 - line1.y1) * localPosition;
} else if (p > length1 + length2) {
p -= length1 + length2;
localPosition = p / length3;
point.x = line3.x1 + (line3.x2 - line3.x1) * localPosition;
point.y = line3.y1 + (line3.y2 - line3.y1) * localPosition;
} else {
p -= length1;
localPosition = p / length2;
point.x = line2.x1 + (line2.x2 - line2.x1) * localPosition;
point.y = line2.y1 + (line2.y2 - line2.y1) * localPosition;
}
out.push(point);
}
return out;
};
module2.exports = GetPoints;
}
),
/***/
39757: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
function getLength(x1, y1, x2, y2) {
var x = x1 - x2;
var y = y1 - y2;
var magnitude = x * x + y * y;
return Math.sqrt(magnitude);
}
var InCenter = function(triangle, out) {
if (out === void 0) {
out = new Point();
}
var x1 = triangle.x1;
var y1 = triangle.y1;
var x2 = triangle.x2;
var y2 = triangle.y2;
var x3 = triangle.x3;
var y3 = triangle.y3;
var d1 = getLength(x3, y3, x2, y2);
var d2 = getLength(x1, y1, x3, y3);
var d3 = getLength(x2, y2, x1, y1);
var p = d1 + d2 + d3;
out.x = (x1 * d1 + x2 * d2 + x3 * d3) / p;
out.y = (y1 * d1 + y2 * d2 + y3 * d3) / p;
return out;
};
module2.exports = InCenter;
}
),
/***/
13584: (
/***/
(module2) => {
var Offset = function(triangle, x, y) {
triangle.x1 += x;
triangle.y1 += y;
triangle.x2 += x;
triangle.y2 += y;
triangle.x3 += x;
triangle.y3 += y;
return triangle;
};
module2.exports = Offset;
}
),
/***/
1376: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Length = __webpack_require__2(35001);
var Perimeter = function(triangle) {
var line1 = triangle.getLineA();
var line2 = triangle.getLineB();
var line3 = triangle.getLineC();
return Length(line1) + Length(line2) + Length(line3);
};
module2.exports = Perimeter;
}
),
/***/
90260: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Point = __webpack_require__2(2141);
var Random = function(triangle, out) {
if (out === void 0) {
out = new Point();
}
var ux = triangle.x2 - triangle.x1;
var uy = triangle.y2 - triangle.y1;
var vx = triangle.x3 - triangle.x1;
var vy = triangle.y3 - triangle.y1;
var r = Math.random();
var s = Math.random();
if (r + s >= 1) {
r = 1 - r;
s = 1 - s;
}
out.x = triangle.x1 + (ux * r + vx * s);
out.y = triangle.y1 + (uy * r + vy * s);
return out;
};
module2.exports = Random;
}
),
/***/
52172: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var RotateAroundXY = __webpack_require__2(99614);
var InCenter = __webpack_require__2(39757);
var Rotate = function(triangle, angle) {
var point = InCenter(triangle);
return RotateAroundXY(triangle, point.x, point.y, angle);
};
module2.exports = Rotate;
}
),
/***/
49907: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var RotateAroundXY = __webpack_require__2(99614);
var RotateAroundPoint = function(triangle, point, angle) {
return RotateAroundXY(triangle, point.x, point.y, angle);
};
module2.exports = RotateAroundPoint;
}
),
/***/
99614: (
/***/
(module2) => {
var RotateAroundXY = function(triangle, x, y, angle) {
var c = Math.cos(angle);
var s = Math.sin(angle);
var tx = triangle.x1 - x;
var ty = triangle.y1 - y;
triangle.x1 = tx * c - ty * s + x;
triangle.y1 = tx * s + ty * c + y;
tx = triangle.x2 - x;
ty = triangle.y2 - y;
triangle.x2 = tx * c - ty * s + x;
triangle.y2 = tx * s + ty * c + y;
tx = triangle.x3 - x;
ty = triangle.y3 - y;
triangle.x3 = tx * c - ty * s + x;
triangle.y3 = tx * s + ty * c + y;
return triangle;
};
module2.exports = RotateAroundXY;
}
),
/***/
16483: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Contains = __webpack_require__2(10690);
var GetPoint = __webpack_require__2(20437);
var GetPoints = __webpack_require__2(80672);
var GEOM_CONST = __webpack_require__2(23777);
var Line = __webpack_require__2(23031);
var Random = __webpack_require__2(90260);
var Triangle = new Class({
initialize: function Triangle2(x1, y1, x2, y2, x3, y3) {
if (x1 === void 0) {
x1 = 0;
}
if (y1 === void 0) {
y1 = 0;
}
if (x2 === void 0) {
x2 = 0;
}
if (y2 === void 0) {
y2 = 0;
}
if (x3 === void 0) {
x3 = 0;
}
if (y3 === void 0) {
y3 = 0;
}
this.type = GEOM_CONST.TRIANGLE;
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.x3 = x3;
this.y3 = y3;
},
/**
* Checks whether a given points lies within the triangle.
*
* @method Phaser.Geom.Triangle#contains
* @since 3.0.0
*
* @param {number} x - The x coordinate of the point to check.
* @param {number} y - The y coordinate of the point to check.
*
* @return {boolean} `true` if the coordinate pair is within the triangle, otherwise `false`.
*/
contains: function(x, y) {
return Contains(this, x, y);
},
/**
* Returns a specific point on the triangle.
*
* @method Phaser.Geom.Triangle#getPoint
* @since 3.0.0
*
* @generic {Phaser.Geom.Point} O - [output,$return]
*
* @param {number} position - Position as float within `0` and `1`. `0` equals the first point.
* @param {(Phaser.Geom.Point|object)} [output] - Optional Point, or point-like object, that the calculated point will be written to.
*
* @return {(Phaser.Geom.Point|object)} Calculated `Point` that represents the requested position. It is the same as `output` when this parameter has been given.
*/
getPoint: function(position, output) {
return GetPoint(this, position, output);
},
/**
* Calculates a list of evenly distributed points on the triangle. It is either possible to pass an amount of points to be generated (`quantity`) or the distance between two points (`stepRate`).
*
* @method Phaser.Geom.Triangle#getPoints
* @since 3.0.0
*
* @generic {Phaser.Geom.Point[]} O - [output,$return]
*
* @param {number} quantity - Number of points to be generated. Can be falsey when `stepRate` should be used. All points have the same distance along the triangle.
* @param {number} [stepRate] - Distance between two points. Will only be used when `quantity` is falsey.
* @param {(array|Phaser.Geom.Point[])} [output] - Optional Array for writing the calculated points into. Otherwise a new array will be created.
*
* @return {(array|Phaser.Geom.Point[])} Returns a list of calculated `Point` instances or the filled array passed as parameter `output`.
*/
getPoints: function(quantity, stepRate, output) {
return GetPoints(this, quantity, stepRate, output);
},
/**
* Returns a random point along the triangle.
*
* @method Phaser.Geom.Triangle#getRandomPoint
* @since 3.0.0
*
* @generic {Phaser.Geom.Point} O - [point,$return]
*
* @param {Phaser.Geom.Point} [point] - Optional `Point` that should be modified. Otherwise a new one will be created.
*
* @return {Phaser.Geom.Point} Random `Point`. When parameter `point` has been provided it will be returned.
*/
getRandomPoint: function(point) {
return Random(this, point);
},
/**
* Sets all three points of the triangle. Leaving out any coordinate sets it to be `0`.
*
* @method Phaser.Geom.Triangle#setTo
* @since 3.0.0
*
* @param {number} [x1=0] - `x` coordinate of the first point.
* @param {number} [y1=0] - `y` coordinate of the first point.
* @param {number} [x2=0] - `x` coordinate of the second point.
* @param {number} [y2=0] - `y` coordinate of the second point.
* @param {number} [x3=0] - `x` coordinate of the third point.
* @param {number} [y3=0] - `y` coordinate of the third point.
*
* @return {this} This Triangle object.
*/
setTo: function(x1, y1, x2, y2, x3, y3) {
if (x1 === void 0) {
x1 = 0;
}
if (y1 === void 0) {
y1 = 0;
}
if (x2 === void 0) {
x2 = 0;
}
if (y2 === void 0) {
y2 = 0;
}
if (x3 === void 0) {
x3 = 0;
}
if (y3 === void 0) {
y3 = 0;
}
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.x3 = x3;
this.y3 = y3;
return this;
},
/**
* Returns a Line object that corresponds to Line A of this Triangle.
*
* @method Phaser.Geom.Triangle#getLineA
* @since 3.0.0
*
* @generic {Phaser.Geom.Line} O - [line,$return]
*
* @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created.
*
* @return {Phaser.Geom.Line} A Line object that corresponds to line A of this Triangle.
*/
getLineA: function(line) {
if (line === void 0) {
line = new Line();
}
line.setTo(this.x1, this.y1, this.x2, this.y2);
return line;
},
/**
* Returns a Line object that corresponds to Line B of this Triangle.
*
* @method Phaser.Geom.Triangle#getLineB
* @since 3.0.0
*
* @generic {Phaser.Geom.Line} O - [line,$return]
*
* @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created.
*
* @return {Phaser.Geom.Line} A Line object that corresponds to line B of this Triangle.
*/
getLineB: function(line) {
if (line === void 0) {
line = new Line();
}
line.setTo(this.x2, this.y2, this.x3, this.y3);
return line;
},
/**
* Returns a Line object that corresponds to Line C of this Triangle.
*
* @method Phaser.Geom.Triangle#getLineC
* @since 3.0.0
*
* @generic {Phaser.Geom.Line} O - [line,$return]
*
* @param {Phaser.Geom.Line} [line] - A Line object to set the results in. If `undefined` a new Line will be created.
*
* @return {Phaser.Geom.Line} A Line object that corresponds to line C of this Triangle.
*/
getLineC: function(line) {
if (line === void 0) {
line = new Line();
}
line.setTo(this.x3, this.y3, this.x1, this.y1);
return line;
},
/**
* Left most X coordinate of the triangle. Setting it moves the triangle on the X axis accordingly.
*
* @name Phaser.Geom.Triangle#left
* @type {number}
* @since 3.0.0
*/
left: {
get: function() {
return Math.min(this.x1, this.x2, this.x3);
},
set: function(value) {
var diff = 0;
if (this.x1 <= this.x2 && this.x1 <= this.x3) {
diff = this.x1 - value;
} else if (this.x2 <= this.x1 && this.x2 <= this.x3) {
diff = this.x2 - value;
} else {
diff = this.x3 - value;
}
this.x1 -= diff;
this.x2 -= diff;
this.x3 -= diff;
}
},
/**
* Right most X coordinate of the triangle. Setting it moves the triangle on the X axis accordingly.
*
* @name Phaser.Geom.Triangle#right
* @type {number}
* @since 3.0.0
*/
right: {
get: function() {
return Math.max(this.x1, this.x2, this.x3);
},
set: function(value) {
var diff = 0;
if (this.x1 >= this.x2 && this.x1 >= this.x3) {
diff = this.x1 - value;
} else if (this.x2 >= this.x1 && this.x2 >= this.x3) {
diff = this.x2 - value;
} else {
diff = this.x3 - value;
}
this.x1 -= diff;
this.x2 -= diff;
this.x3 -= diff;
}
},
/**
* Top most Y coordinate of the triangle. Setting it moves the triangle on the Y axis accordingly.
*
* @name Phaser.Geom.Triangle#top
* @type {number}
* @since 3.0.0
*/
top: {
get: function() {
return Math.min(this.y1, this.y2, this.y3);
},
set: function(value) {
var diff = 0;
if (this.y1 <= this.y2 && this.y1 <= this.y3) {
diff = this.y1 - value;
} else if (this.y2 <= this.y1 && this.y2 <= this.y3) {
diff = this.y2 - value;
} else {
diff = this.y3 - value;
}
this.y1 -= diff;
this.y2 -= diff;
this.y3 -= diff;
}
},
/**
* Bottom most Y coordinate of the triangle. Setting it moves the triangle on the Y axis accordingly.
*
* @name Phaser.Geom.Triangle#bottom
* @type {number}
* @since 3.0.0
*/
bottom: {
get: function() {
return Math.max(this.y1, this.y2, this.y3);
},
set: function(value) {
var diff = 0;
if (this.y1 >= this.y2 && this.y1 >= this.y3) {
diff = this.y1 - value;
} else if (this.y2 >= this.y1 && this.y2 >= this.y3) {
diff = this.y2 - value;
} else {
diff = this.y3 - value;
}
this.y1 -= diff;
this.y2 -= diff;
this.y3 -= diff;
}
}
});
module2.exports = Triangle;
}
),
/***/
84435: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Triangle = __webpack_require__2(16483);
Triangle.Area = __webpack_require__2(41658);
Triangle.BuildEquilateral = __webpack_require__2(39208);
Triangle.BuildFromPolygon = __webpack_require__2(39545);
Triangle.BuildRight = __webpack_require__2(90301);
Triangle.CenterOn = __webpack_require__2(23707);
Triangle.Centroid = __webpack_require__2(97523);
Triangle.CircumCenter = __webpack_require__2(24951);
Triangle.CircumCircle = __webpack_require__2(85614);
Triangle.Clone = __webpack_require__2(74422);
Triangle.Contains = __webpack_require__2(10690);
Triangle.ContainsArray = __webpack_require__2(48653);
Triangle.ContainsPoint = __webpack_require__2(96006);
Triangle.CopyFrom = __webpack_require__2(71326);
Triangle.Decompose = __webpack_require__2(71694);
Triangle.Equals = __webpack_require__2(33522);
Triangle.GetPoint = __webpack_require__2(20437);
Triangle.GetPoints = __webpack_require__2(80672);
Triangle.InCenter = __webpack_require__2(39757);
Triangle.Perimeter = __webpack_require__2(1376);
Triangle.Offset = __webpack_require__2(13584);
Triangle.Random = __webpack_require__2(90260);
Triangle.Rotate = __webpack_require__2(52172);
Triangle.RotateAroundPoint = __webpack_require__2(49907);
Triangle.RotateAroundXY = __webpack_require__2(99614);
module2.exports = Triangle;
}
),
/***/
74457: (
/***/
(module2) => {
var CreateInteractiveObject = function(gameObject, hitArea, hitAreaCallback) {
return {
gameObject,
enabled: true,
draggable: false,
dropZone: false,
cursor: false,
target: null,
camera: null,
hitArea,
hitAreaCallback,
hitAreaDebug: null,
// Has the dev specified their own shape, or is this bound to the texture size?
customHitArea: false,
localX: 0,
localY: 0,
// 0 = Not being dragged
// 1 = Being checked for dragging
// 2 = Being dragged
dragState: 0,
dragStartX: 0,
dragStartY: 0,
dragStartXGlobal: 0,
dragStartYGlobal: 0,
dragStartCamera: null,
dragX: 0,
dragY: 0
};
};
module2.exports = CreateInteractiveObject;
}
),
/***/
84409: (
/***/
(module2) => {
var CreatePixelPerfectHandler = function(textureManager, alphaTolerance) {
return function(hitArea, x, y, gameObject) {
var alpha = textureManager.getPixelAlpha(x, y, gameObject.texture.key, gameObject.frame.name);
return alpha && alpha >= alphaTolerance;
};
};
module2.exports = CreatePixelPerfectHandler;
}
),
/***/
7003: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(93301);
var EventEmitter = __webpack_require__2(50792);
var Events = __webpack_require__2(8214);
var GameEvents = __webpack_require__2(8443);
var Keyboard = __webpack_require__2(78970);
var Mouse = __webpack_require__2(85098);
var Pointer = __webpack_require__2(42515);
var Touch = __webpack_require__2(36210);
var TransformMatrix = __webpack_require__2(61340);
var TransformXY = __webpack_require__2(85955);
var InputManager = new Class({
initialize: function InputManager2(game, config) {
this.game = game;
this.scaleManager;
this.canvas;
this.config = config;
this.enabled = true;
this.events = new EventEmitter();
this.isOver = true;
this.defaultCursor = "";
this.keyboard = config.inputKeyboard ? new Keyboard(this) : null;
this.mouse = config.inputMouse ? new Mouse(this) : null;
this.touch = config.inputTouch ? new Touch(this) : null;
this.pointers = [];
this.pointersTotal = config.inputActivePointers;
for (var i = 0; i <= this.pointersTotal; i++) {
var pointer = new Pointer(this, i);
pointer.smoothFactor = config.inputSmoothFactor;
this.pointers.push(pointer);
}
this.mousePointer = config.inputMouse ? this.pointers[0] : null;
this.activePointer = this.pointers[0];
this.globalTopOnly = true;
this.time = 0;
this._tempPoint = { x: 0, y: 0 };
this._tempHitTest = [];
this._tempMatrix = new TransformMatrix();
this._tempMatrix2 = new TransformMatrix();
this._tempSkip = false;
this.mousePointerContainer = [this.mousePointer];
game.events.once(GameEvents.BOOT, this.boot, this);
},
/**
* The Boot handler is called by Phaser.Game when it first starts up.
* The renderer is available by now.
*
* @method Phaser.Input.InputManager#boot
* @protected
* @fires Phaser.Input.Events#MANAGER_BOOT
* @since 3.0.0
*/
boot: function() {
var game = this.game;
var events = game.events;
this.canvas = game.canvas;
this.scaleManager = game.scale;
this.events.emit(Events.MANAGER_BOOT);
events.on(GameEvents.PRE_RENDER, this.preRender, this);
events.once(GameEvents.DESTROY, this.destroy, this);
},
/**
* Internal canvas state change, called automatically by the Mouse Manager.
*
* @method Phaser.Input.InputManager#setCanvasOver
* @fires Phaser.Input.Events#GAME_OVER
* @private
* @since 3.16.0
*
* @param {(MouseEvent|TouchEvent)} event - The DOM Event.
*/
setCanvasOver: function(event) {
this.isOver = true;
this.events.emit(Events.GAME_OVER, event);
},
/**
* Internal canvas state change, called automatically by the Mouse Manager.
*
* @method Phaser.Input.InputManager#setCanvasOut
* @fires Phaser.Input.Events#GAME_OUT
* @private
* @since 3.16.0
*
* @param {(MouseEvent|TouchEvent)} event - The DOM Event.
*/
setCanvasOut: function(event) {
this.isOver = false;
this.events.emit(Events.GAME_OUT, event);
},
/**
* Internal update, called automatically by the Game Step right at the start.
*
* @method Phaser.Input.InputManager#preRender
* @private
* @since 3.18.0
*/
preRender: function() {
var time = this.game.loop.now;
var delta = this.game.loop.delta;
var scenes = this.game.scene.getScenes(true, true);
this.time = time;
this.events.emit(Events.MANAGER_UPDATE);
for (var i = 0; i < scenes.length; i++) {
var scene = scenes[i];
if (scene.sys.input && scene.sys.input.updatePoll(time, delta) && this.globalTopOnly) {
return;
}
}
},
/**
* Tells the Input system to set a custom cursor.
*
* This cursor will be the default cursor used when interacting with the game canvas.
*
* If an Interactive Object also sets a custom cursor, this is the cursor that is reset after its use.
*
* Any valid CSS cursor value is allowed, including paths to image files, i.e.:
*
* ```javascript
* this.input.setDefaultCursor('url(assets/cursors/sword.cur), pointer');
* ```
*
* Please read about the differences between browsers when it comes to the file formats and sizes they support:
*
* https://developer.mozilla.org/en-US/docs/Web/CSS/cursor
* https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_User_Interface/Using_URL_values_for_the_cursor_property
*
* It's up to you to pick a suitable cursor format that works across the range of browsers you need to support.
*
* @method Phaser.Input.InputManager#setDefaultCursor
* @since 3.10.0
*
* @param {string} cursor - The CSS to be used when setting the default cursor.
*/
setDefaultCursor: function(cursor) {
this.defaultCursor = cursor;
if (this.canvas.style.cursor !== cursor) {
this.canvas.style.cursor = cursor;
}
},
/**
* Called by the InputPlugin when processing over and out events.
*
* Tells the Input Manager to set a custom cursor during its postUpdate step.
*
* https://developer.mozilla.org/en-US/docs/Web/CSS/cursor
*
* @method Phaser.Input.InputManager#setCursor
* @private
* @since 3.10.0
*
* @param {Phaser.Types.Input.InteractiveObject} interactiveObject - The Interactive Object that called this method.
*/
setCursor: function(interactiveObject) {
if (interactiveObject.cursor) {
this.canvas.style.cursor = interactiveObject.cursor;
}
},
/**
* Called by the InputPlugin when processing over and out events.
*
* Tells the Input Manager to clear the hand cursor, if set, during its postUpdate step.
*
* @method Phaser.Input.InputManager#resetCursor
* @private
* @since 3.10.0
*
* @param {Phaser.Types.Input.InteractiveObject} interactiveObject - The Interactive Object that called this method. Pass `null` if you just want to set the force value.
* @param {boolean} [forceReset=false] - Should the reset happen regardless of the object's cursor state? Default false.
*/
resetCursor: function(interactiveObject, forceReset) {
if ((forceReset || interactiveObject && interactiveObject.cursor) && this.canvas) {
this.canvas.style.cursor = this.defaultCursor;
}
},
/**
* Adds new Pointer objects to the Input Manager.
*
* By default Phaser creates 2 pointer objects: `mousePointer` and `pointer1`.
*
* You can create more either by calling this method, or by setting the `input.activePointers` property
* in the Game Config, up to a maximum of 10 pointers.
*
* The first 10 pointers are available via the `InputPlugin.pointerX` properties, once they have been added
* via this method.
*
* @method Phaser.Input.InputManager#addPointer
* @since 3.10.0
*
* @param {number} [quantity=1] The number of new Pointers to create. A maximum of 10 is allowed in total.
*
* @return {Phaser.Input.Pointer[]} An array containing all of the new Pointer objects that were created.
*/
addPointer: function(quantity) {
if (quantity === void 0) {
quantity = 1;
}
var output = [];
if (this.pointersTotal + quantity > 10) {
quantity = 10 - this.pointersTotal;
}
for (var i = 0; i < quantity; i++) {
var id = this.pointers.length;
var pointer = new Pointer(this, id);
pointer.smoothFactor = this.config.inputSmoothFactor;
this.pointers.push(pointer);
this.pointersTotal++;
output.push(pointer);
}
return output;
},
/**
* Internal method that gets a list of all the active Input Plugins in the game
* and updates each of them in turn, in reverse order (top to bottom), to allow
* for DOM top-level event handling simulation.
*
* @method Phaser.Input.InputManager#updateInputPlugins
* @since 3.16.0
*
* @param {number} type - The type of event to process.
* @param {Phaser.Input.Pointer[]} pointers - An array of Pointers on which the event occurred.
*/
updateInputPlugins: function(type, pointers) {
var scenes = this.game.scene.getScenes(false, true);
this._tempSkip = false;
for (var i = 0; i < scenes.length; i++) {
var scene = scenes[i];
if (scene.sys.input) {
var capture = scene.sys.input.update(type, pointers);
if (capture && this.globalTopOnly || this._tempSkip) {
return;
}
}
}
},
// event.targetTouches = list of all touches on the TARGET ELEMENT (i.e. game dom element)
// event.touches = list of all touches on the ENTIRE DOCUMENT, not just the target element
// event.changedTouches = the touches that CHANGED in this event, not the total number of them
/**
* Processes a touch start event, as passed in by the TouchManager.
*
* @method Phaser.Input.InputManager#onTouchStart
* @private
* @since 3.18.0
*
* @param {TouchEvent} event - The native DOM Touch event.
*/
onTouchStart: function(event) {
var pointers = this.pointers;
var changed = [];
for (var c = 0; c < event.changedTouches.length; c++) {
var changedTouch = event.changedTouches[c];
for (var i = 1; i < pointers.length; i++) {
var pointer = pointers[i];
if (!pointer.active) {
pointer.touchstart(changedTouch, event);
this.activePointer = pointer;
changed.push(pointer);
break;
}
}
}
this.updateInputPlugins(CONST.TOUCH_START, changed);
},
/**
* Processes a touch move event, as passed in by the TouchManager.
*
* @method Phaser.Input.InputManager#onTouchMove
* @private
* @since 3.18.0
*
* @param {TouchEvent} event - The native DOM Touch event.
*/
onTouchMove: function(event) {
var pointers = this.pointers;
var changed = [];
for (var c = 0; c < event.changedTouches.length; c++) {
var changedTouch = event.changedTouches[c];
for (var i = 1; i < pointers.length; i++) {
var pointer = pointers[i];
if (pointer.active && pointer.identifier === changedTouch.identifier) {
var element = document.elementFromPoint(changedTouch.clientX, changedTouch.clientY);
var overCanvas = element === this.canvas;
if (!this.isOver && overCanvas) {
this.setCanvasOver(event);
} else if (this.isOver && !overCanvas) {
this.setCanvasOut(event);
}
if (this.isOver) {
pointer.touchmove(changedTouch, event);
this.activePointer = pointer;
changed.push(pointer);
}
break;
}
}
}
this.updateInputPlugins(CONST.TOUCH_MOVE, changed);
},
// For touch end its a list of the touch points that have been removed from the surface
// https://developer.mozilla.org/en-US/docs/DOM/TouchList
// event.changedTouches = the touches that CHANGED in this event, not the total number of them
/**
* Processes a touch end event, as passed in by the TouchManager.
*
* @method Phaser.Input.InputManager#onTouchEnd
* @private
* @since 3.18.0
*
* @param {TouchEvent} event - The native DOM Touch event.
*/
onTouchEnd: function(event) {
var pointers = this.pointers;
var changed = [];
for (var c = 0; c < event.changedTouches.length; c++) {
var changedTouch = event.changedTouches[c];
for (var i = 1; i < pointers.length; i++) {
var pointer = pointers[i];
if (pointer.active && pointer.identifier === changedTouch.identifier) {
pointer.touchend(changedTouch, event);
changed.push(pointer);
break;
}
}
}
this.updateInputPlugins(CONST.TOUCH_END, changed);
},
/**
* Processes a touch cancel event, as passed in by the TouchManager.
*
* @method Phaser.Input.InputManager#onTouchCancel
* @private
* @since 3.18.0
*
* @param {TouchEvent} event - The native DOM Touch event.
*/
onTouchCancel: function(event) {
var pointers = this.pointers;
var changed = [];
for (var c = 0; c < event.changedTouches.length; c++) {
var changedTouch = event.changedTouches[c];
for (var i = 1; i < pointers.length; i++) {
var pointer = pointers[i];
if (pointer.active && pointer.identifier === changedTouch.identifier) {
pointer.touchcancel(changedTouch, event);
changed.push(pointer);
break;
}
}
}
this.updateInputPlugins(CONST.TOUCH_CANCEL, changed);
},
/**
* Processes a mouse down event, as passed in by the MouseManager.
*
* @method Phaser.Input.InputManager#onMouseDown
* @private
* @since 3.18.0
*
* @param {MouseEvent} event - The native DOM Mouse event.
*/
onMouseDown: function(event) {
var mousePointer = this.mousePointer;
mousePointer.down(event);
mousePointer.updateMotion();
this.activePointer = mousePointer;
this.updateInputPlugins(CONST.MOUSE_DOWN, this.mousePointerContainer);
},
/**
* Processes a mouse move event, as passed in by the MouseManager.
*
* @method Phaser.Input.InputManager#onMouseMove
* @private
* @since 3.18.0
*
* @param {MouseEvent} event - The native DOM Mouse event.
*/
onMouseMove: function(event) {
var mousePointer = this.mousePointer;
mousePointer.move(event);
mousePointer.updateMotion();
this.activePointer = mousePointer;
this.updateInputPlugins(CONST.MOUSE_MOVE, this.mousePointerContainer);
},
/**
* Processes a mouse up event, as passed in by the MouseManager.
*
* @method Phaser.Input.InputManager#onMouseUp
* @private
* @since 3.18.0
*
* @param {MouseEvent} event - The native DOM Mouse event.
*/
onMouseUp: function(event) {
var mousePointer = this.mousePointer;
mousePointer.up(event);
mousePointer.updateMotion();
this.activePointer = mousePointer;
this.updateInputPlugins(CONST.MOUSE_UP, this.mousePointerContainer);
},
/**
* Processes a mouse wheel event, as passed in by the MouseManager.
*
* @method Phaser.Input.InputManager#onMouseWheel
* @private
* @since 3.18.0
*
* @param {WheelEvent} event - The native DOM Wheel event.
*/
onMouseWheel: function(event) {
var mousePointer = this.mousePointer;
mousePointer.wheel(event);
this.activePointer = mousePointer;
this.updateInputPlugins(CONST.MOUSE_WHEEL, this.mousePointerContainer);
},
/**
* Processes a pointer lock change event, as passed in by the MouseManager.
*
* @method Phaser.Input.InputManager#onPointerLockChange
* @fires Phaser.Input.Events#POINTERLOCK_CHANGE
* @private
* @since 3.19.0
*
* @param {MouseEvent} event - The native DOM Mouse event.
*/
onPointerLockChange: function(event) {
var isLocked = this.mouse.locked;
this.mousePointer.locked = isLocked;
this.events.emit(Events.POINTERLOCK_CHANGE, event, isLocked);
},
/**
* Checks if the given Game Object should be considered as a candidate for input or not.
*
* Checks if the Game Object has an input component that is enabled, that it will render,
* and finally, if it has a parent, that the parent parent, or any ancestor, is visible or not.
*
* @method Phaser.Input.InputManager#inputCandidate
* @private
* @since 3.10.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to test.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera which is being tested against.
*
* @return {boolean} `true` if the Game Object should be considered for input, otherwise `false`.
*/
inputCandidate: function(gameObject, camera) {
var input = gameObject.input;
if (!input || !input.enabled || !gameObject.willRender(camera)) {
return false;
}
var visible = true;
var parent = gameObject.parentContainer;
if (parent) {
do {
if (!parent.willRender(camera)) {
visible = false;
break;
}
parent = parent.parentContainer;
} while (parent);
}
return visible;
},
/**
* Performs a hit test using the given Pointer and camera, against an array of interactive Game Objects.
*
* The Game Objects are culled against the camera, and then the coordinates are translated into the local camera space
* and used to determine if they fall within the remaining Game Objects hit areas or not.
*
* If nothing is matched an empty array is returned.
*
* This method is called automatically by InputPlugin.hitTestPointer and doesn't usually need to be invoked directly.
*
* @method Phaser.Input.InputManager#hitTest
* @since 3.0.0
*
* @param {Phaser.Input.Pointer} pointer - The Pointer to test against.
* @param {array} gameObjects - An array of interactive Game Objects to check.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera which is being tested against.
* @param {array} [output] - An array to store the results in. If not given, a new empty array is created.
*
* @return {array} An array of the Game Objects that were hit during this hit test.
*/
hitTest: function(pointer, gameObjects, camera, output) {
if (output === void 0) {
output = this._tempHitTest;
}
var tempPoint = this._tempPoint;
var csx = camera.scrollX;
var csy = camera.scrollY;
output.length = 0;
var x = pointer.x;
var y = pointer.y;
camera.getWorldPoint(x, y, tempPoint);
pointer.worldX = tempPoint.x;
pointer.worldY = tempPoint.y;
var point = { x: 0, y: 0 };
var matrix = this._tempMatrix;
var parentMatrix = this._tempMatrix2;
for (var i = 0; i < gameObjects.length; i++) {
var gameObject = gameObjects[i];
if (!this.inputCandidate(gameObject, camera)) {
continue;
}
var px = tempPoint.x + csx * gameObject.scrollFactorX - csx;
var py = tempPoint.y + csy * gameObject.scrollFactorY - csy;
if (gameObject.parentContainer) {
gameObject.getWorldTransformMatrix(matrix, parentMatrix);
matrix.applyInverse(px, py, point);
} else {
TransformXY(px, py, gameObject.x, gameObject.y, gameObject.rotation, gameObject.scaleX, gameObject.scaleY, point);
}
if (this.pointWithinHitArea(gameObject, point.x, point.y)) {
output.push(gameObject);
}
}
return output;
},
/**
* Checks if the given x and y coordinate are within the hit area of the Game Object.
*
* This method assumes that the coordinate values have already been translated into the space of the Game Object.
*
* If the coordinates are within the hit area they are set into the Game Objects Input `localX` and `localY` properties.
*
* @method Phaser.Input.InputManager#pointWithinHitArea
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The interactive Game Object to check against.
* @param {number} x - The translated x coordinate for the hit test.
* @param {number} y - The translated y coordinate for the hit test.
*
* @return {boolean} `true` if the coordinates were inside the Game Objects hit area, otherwise `false`.
*/
pointWithinHitArea: function(gameObject, x, y) {
x += gameObject.displayOriginX;
y += gameObject.displayOriginY;
var input = gameObject.input;
if (input && input.hitAreaCallback(input.hitArea, x, y, gameObject)) {
input.localX = x;
input.localY = y;
return true;
} else {
return false;
}
},
/**
* Checks if the given x and y coordinate are within the hit area of the Interactive Object.
*
* This method assumes that the coordinate values have already been translated into the space of the Interactive Object.
*
* If the coordinates are within the hit area they are set into the Interactive Objects Input `localX` and `localY` properties.
*
* @method Phaser.Input.InputManager#pointWithinInteractiveObject
* @since 3.0.0
*
* @param {Phaser.Types.Input.InteractiveObject} object - The Interactive Object to check against.
* @param {number} x - The translated x coordinate for the hit test.
* @param {number} y - The translated y coordinate for the hit test.
*
* @return {boolean} `true` if the coordinates were inside the Game Objects hit area, otherwise `false`.
*/
pointWithinInteractiveObject: function(object, x, y) {
if (!object.hitArea) {
return false;
}
x += object.gameObject.displayOriginX;
y += object.gameObject.displayOriginY;
object.localX = x;
object.localY = y;
return object.hitAreaCallback(object.hitArea, x, y, object);
},
/**
* Transforms the pageX and pageY values of a Pointer into the scaled coordinate space of the Input Manager.
*
* @method Phaser.Input.InputManager#transformPointer
* @since 3.10.0
*
* @param {Phaser.Input.Pointer} pointer - The Pointer to transform the values for.
* @param {number} pageX - The Page X value.
* @param {number} pageY - The Page Y value.
* @param {boolean} wasMove - Are we transforming the Pointer from a move event, or an up / down event?
*/
transformPointer: function(pointer, pageX, pageY, wasMove) {
var p0 = pointer.position;
var p1 = pointer.prevPosition;
p1.x = p0.x;
p1.y = p0.y;
var x = this.scaleManager.transformX(pageX);
var y = this.scaleManager.transformY(pageY);
var a = pointer.smoothFactor;
if (!wasMove || a === 0) {
p0.x = x;
p0.y = y;
} else {
p0.x = x * a + p1.x * (1 - a);
p0.y = y * a + p1.y * (1 - a);
}
},
/**
* Destroys the Input Manager and all of its systems.
*
* There is no way to recover from doing this.
*
* @method Phaser.Input.InputManager#destroy
* @since 3.0.0
*/
destroy: function() {
this.events.removeAllListeners();
this.game.events.off(GameEvents.PRE_RENDER);
if (this.keyboard) {
this.keyboard.destroy();
}
if (this.mouse) {
this.mouse.destroy();
}
if (this.touch) {
this.touch.destroy();
}
for (var i = 0; i < this.pointers.length; i++) {
this.pointers[i].destroy();
}
this.pointers = [];
this._tempHitTest = [];
this._tempMatrix.destroy();
this.canvas = null;
this.game = null;
}
});
module2.exports = InputManager;
}
),
/***/
48205: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Circle = __webpack_require__2(96503);
var CircleContains = __webpack_require__2(87902);
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(93301);
var CreateInteractiveObject = __webpack_require__2(74457);
var CreatePixelPerfectHandler = __webpack_require__2(84409);
var DistanceBetween = __webpack_require__2(20339);
var Ellipse = __webpack_require__2(8497);
var EllipseContains = __webpack_require__2(81154);
var Events = __webpack_require__2(8214);
var EventEmitter = __webpack_require__2(50792);
var GetFastValue = __webpack_require__2(95540);
var GEOM_CONST = __webpack_require__2(23777);
var InputPluginCache = __webpack_require__2(89639);
var IsPlainObject = __webpack_require__2(41212);
var PluginCache = __webpack_require__2(37277);
var Rectangle = __webpack_require__2(87841);
var RectangleContains = __webpack_require__2(37303);
var SceneEvents = __webpack_require__2(44594);
var Triangle = __webpack_require__2(16483);
var TriangleContains = __webpack_require__2(10690);
var InputPlugin = new Class({
Extends: EventEmitter,
initialize: function InputPlugin2(scene) {
EventEmitter.call(this);
this.scene = scene;
this.systems = scene.sys;
this.settings = scene.sys.settings;
this.manager = scene.sys.game.input;
this.pluginEvents = new EventEmitter();
this.enabled = true;
this.displayList;
this.cameras;
InputPluginCache.install(this);
this.mouse = this.manager.mouse;
this.topOnly = true;
this.pollRate = -1;
this._pollTimer = 0;
var _eventData = { cancelled: false };
this._eventContainer = {
stopPropagation: function() {
_eventData.cancelled = true;
}
};
this._eventData = _eventData;
this.dragDistanceThreshold = 0;
this.dragTimeThreshold = 0;
this._temp = [];
this._tempZones = [];
this._list = [];
this._pendingInsertion = [];
this._pendingRemoval = [];
this._draggable = [];
this._drag = { 0: [], 1: [], 2: [], 3: [], 4: [], 5: [], 6: [], 7: [], 8: [], 9: [], 10: [] };
this._dragState = [];
this._over = { 0: [], 1: [], 2: [], 3: [], 4: [], 5: [], 6: [], 7: [], 8: [], 9: [], 10: [] };
this._validTypes = ["onDown", "onUp", "onOver", "onOut", "onMove", "onDragStart", "onDrag", "onDragEnd", "onDragEnter", "onDragLeave", "onDragOver", "onDrop"];
this._updatedThisFrame = false;
scene.sys.events.once(SceneEvents.BOOT, this.boot, this);
scene.sys.events.on(SceneEvents.START, this.start, this);
},
/**
* This method is called automatically, only once, when the Scene is first created.
* Do not invoke it directly.
*
* @method Phaser.Input.InputPlugin#boot
* @fires Phaser.Input.Events#BOOT
* @private
* @since 3.5.1
*/
boot: function() {
this.cameras = this.systems.cameras;
this.displayList = this.systems.displayList;
this.systems.events.once(SceneEvents.DESTROY, this.destroy, this);
this.pluginEvents.emit(Events.BOOT);
},
/**
* This method is called automatically by the Scene when it is starting up.
* It is responsible for creating local systems, properties and listening for Scene events.
* Do not invoke it directly.
*
* @method Phaser.Input.InputPlugin#start
* @fires Phaser.Input.Events#START
* @private
* @since 3.5.0
*/
start: function() {
var eventEmitter = this.systems.events;
eventEmitter.on(SceneEvents.TRANSITION_START, this.transitionIn, this);
eventEmitter.on(SceneEvents.TRANSITION_OUT, this.transitionOut, this);
eventEmitter.on(SceneEvents.TRANSITION_COMPLETE, this.transitionComplete, this);
eventEmitter.on(SceneEvents.PRE_UPDATE, this.preUpdate, this);
eventEmitter.once(SceneEvents.SHUTDOWN, this.shutdown, this);
this.manager.events.on(Events.GAME_OUT, this.onGameOut, this);
this.manager.events.on(Events.GAME_OVER, this.onGameOver, this);
this.enabled = true;
this._dragState = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
this.pluginEvents.emit(Events.START);
},
/**
* Game Over handler.
*
* @method Phaser.Input.InputPlugin#onGameOver
* @fires Phaser.Input.Events#GAME_OVER
* @private
* @since 3.16.2
*/
onGameOver: function(event) {
if (this.isActive()) {
this.emit(Events.GAME_OVER, event.timeStamp, event);
}
},
/**
* Game Out handler.
*
* @method Phaser.Input.InputPlugin#onGameOut
* @fires Phaser.Input.Events#GAME_OUT
* @private
* @since 3.16.2
*/
onGameOut: function(event) {
if (this.isActive()) {
this.emit(Events.GAME_OUT, event.timeStamp, event);
}
},
/**
* The pre-update handler is responsible for checking the pending removal and insertion lists and
* deleting old Game Objects.
*
* @method Phaser.Input.InputPlugin#preUpdate
* @private
* @fires Phaser.Input.Events#PRE_UPDATE
* @since 3.0.0
*/
preUpdate: function() {
this.pluginEvents.emit(Events.PRE_UPDATE);
var removeList = this._pendingRemoval;
var insertList = this._pendingInsertion;
var toRemove = removeList.length;
var toInsert = insertList.length;
if (toRemove === 0 && toInsert === 0) {
return;
}
var current = this._list;
for (var i = 0; i < toRemove; i++) {
var gameObject = removeList[i];
var index = current.indexOf(gameObject);
if (index > -1) {
current.splice(index, 1);
this.clear(gameObject, true);
}
}
this._pendingRemoval.length = 0;
this._list = current.concat(insertList.splice(0));
},
/**
* Checks to see if the Input Manager, this plugin and the Scene to which it belongs are all active and input enabled.
*
* @method Phaser.Input.InputPlugin#isActive
* @since 3.10.0
*
* @return {boolean} `true` if the plugin and the Scene it belongs to is active.
*/
isActive: function() {
return this.manager && this.manager.enabled && this.enabled && this.scene.sys.canInput();
},
/**
* Sets a custom cursor on the parent canvas element of the game, based on the `cursor`
* setting of the given Interactive Object (i.e. a Sprite).
*
* See the CSS property `cursor` for more information on MDN:
*
* https://developer.mozilla.org/en-US/docs/Web/CSS/cursor
*
* @method Phaser.Input.InputPlugin#setCursor
* @since 3.85.0
*
* @param {Phaser.Types.Input.InteractiveObject} interactiveObject - The Interactive Object that will set the cursor on the canvas.
*/
setCursor: function(interactiveObject) {
if (this.manager) {
this.manager.setCursor(interactiveObject);
}
},
/**
* Forces the Input Manager to clear the custom or hand cursor, regardless of the
* interactive state of any Game Objects.
*
* @method Phaser.Input.InputPlugin#resetCursor
* @since 3.85.0
*/
resetCursor: function() {
if (this.manager) {
this.manager.resetCursor(null, true);
}
},
/**
* This is called automatically by the Input Manager.
* It emits events for plugins to listen to and also handles polling updates, if enabled.
*
* @method Phaser.Input.InputPlugin#updatePoll
* @since 3.18.0
*
* @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout.
* @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
*
* @return {boolean} `true` if the plugin and the Scene it belongs to is active.
*/
updatePoll: function(time, delta) {
if (!this.isActive()) {
return false;
}
this.pluginEvents.emit(Events.UPDATE, time, delta);
if (this._updatedThisFrame) {
this._updatedThisFrame = false;
return false;
}
var i;
var manager = this.manager;
var pointers = manager.pointers;
for (i = 0; i < pointers.length; i++) {
pointers[i].updateMotion();
}
if (this._list.length === 0) {
return false;
}
var rate = this.pollRate;
if (rate === -1) {
return false;
} else if (rate > 0) {
this._pollTimer -= delta;
if (this._pollTimer < 0) {
this._pollTimer = this.pollRate;
} else {
return false;
}
}
var captured = false;
for (i = 0; i < pointers.length; i++) {
var total = 0;
var pointer = pointers[i];
this._tempZones = [];
this._temp = this.hitTestPointer(pointer);
this.sortGameObjects(this._temp, pointer);
this.sortDropZones(this._tempZones);
if (this.topOnly) {
if (this._temp.length) {
this._temp.splice(1);
}
if (this._tempZones.length) {
this._tempZones.splice(1);
}
}
total += this.processOverOutEvents(pointer);
if (this.getDragState(pointer) === 2) {
this.processDragThresholdEvent(pointer, time);
}
if (total > 0) {
captured = true;
}
}
return captured;
},
/**
* This method is called when a DOM Event is received by the Input Manager. It handles dispatching the events
* to relevant input enabled Game Objects in this scene.
*
* @method Phaser.Input.InputPlugin#update
* @private
* @fires Phaser.Input.Events#UPDATE
* @since 3.0.0
*
* @param {number} type - The type of event to process.
* @param {Phaser.Input.Pointer[]} pointers - An array of Pointers on which the event occurred.
*
* @return {boolean} `true` if this Scene has captured the input events from all other Scenes, otherwise `false`.
*/
update: function(type, pointers) {
if (!this.isActive()) {
return false;
}
var captured = false;
for (var i = 0; i < pointers.length; i++) {
var total = 0;
var pointer = pointers[i];
this._tempZones = [];
this._temp = this.hitTestPointer(pointer);
this.sortGameObjects(this._temp, pointer);
this.sortDropZones(this._tempZones);
if (this.topOnly) {
if (this._temp.length) {
this._temp.splice(1);
}
if (this._tempZones.length) {
this._tempZones.splice(1);
}
}
switch (type) {
case CONST.MOUSE_DOWN:
total += this.processDragDownEvent(pointer);
total += this.processDownEvents(pointer);
total += this.processOverOutEvents(pointer);
break;
case CONST.MOUSE_UP:
total += this.processDragUpEvent(pointer);
total += this.processUpEvents(pointer);
total += this.processOverOutEvents(pointer);
break;
case CONST.TOUCH_START:
total += this.processDragDownEvent(pointer);
total += this.processDownEvents(pointer);
total += this.processOverEvents(pointer);
break;
case CONST.TOUCH_END:
case CONST.TOUCH_CANCEL:
total += this.processDragUpEvent(pointer);
total += this.processUpEvents(pointer);
total += this.processOutEvents(pointer);
break;
case CONST.MOUSE_MOVE:
case CONST.TOUCH_MOVE:
total += this.processDragMoveEvent(pointer);
total += this.processMoveEvents(pointer);
total += this.processOverOutEvents(pointer);
break;
case CONST.MOUSE_WHEEL:
total += this.processWheelEvent(pointer);
break;
}
if (total > 0) {
captured = true;
}
}
this._updatedThisFrame = true;
return captured;
},
/**
* Clears a Game Object so it no longer has an Interactive Object associated with it.
* The Game Object is then queued for removal from the Input Plugin on the next update.
*
* @method Phaser.Input.InputPlugin#clear
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that will have its Interactive Object removed.
* @param {boolean} [skipQueue=false] - Skip adding this Game Object into the removal queue?
*
* @return {Phaser.GameObjects.GameObject} The Game Object that had its Interactive Object removed.
*/
clear: function(gameObject, skipQueue) {
if (skipQueue === void 0) {
skipQueue = false;
}
this.disable(gameObject);
var input = gameObject.input;
if (input) {
this.removeDebug(gameObject);
this.manager.resetCursor(input);
input.gameObject = void 0;
input.target = void 0;
input.hitArea = void 0;
input.hitAreaCallback = void 0;
input.callbackContext = void 0;
gameObject.input = null;
}
if (!skipQueue) {
this.queueForRemoval(gameObject);
}
var index = this._draggable.indexOf(gameObject);
if (index > -1) {
this._draggable.splice(index, 1);
}
return gameObject;
},
/**
* Disables Input on a single Game Object.
*
* An input disabled Game Object still retains its Interactive Object component and can be re-enabled
* at any time, by passing it to `InputPlugin.enable`.
*
* @method Phaser.Input.InputPlugin#disable
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to have its input system disabled.
* @param {boolean} [resetCursor=false] - Reset the cursor to the default?
*
* @return {this} This Input Plugin.
*/
disable: function(gameObject, resetCursor) {
if (resetCursor === void 0) {
resetCursor = false;
}
var input = gameObject.input;
if (input) {
input.enabled = false;
input.dragState = 0;
}
var drag = this._drag;
var over = this._over;
var manager = this.manager;
for (var i = 0, index; i < manager.pointers.length; i++) {
index = drag[i].indexOf(gameObject);
if (index > -1) {
drag[i].splice(index, 1);
}
index = over[i].indexOf(gameObject);
if (index > -1) {
over[i].splice(index, 1);
}
}
if (resetCursor) {
this.resetCursor();
}
return this;
},
/**
* Enable a Game Object for interaction.
*
* If the Game Object already has an Interactive Object component, it is enabled and returned.
*
* Otherwise, a new Interactive Object component is created and assigned to the Game Object's `input` property.
*
* Input works by using hit areas, these are nearly always geometric shapes, such as rectangles or circles, that act as the hit area
* for the Game Object. However, you can provide your own hit area shape and callback, should you wish to handle some more advanced
* input detection.
*
* If no arguments are provided it will try and create a rectangle hit area based on the texture frame the Game Object is using. If
* this isn't a texture-bound object, such as a Graphics or BitmapText object, this will fail, and you'll need to provide a specific
* shape for it to use.
*
* You can also provide an Input Configuration Object as the only argument to this method.
*
* @method Phaser.Input.InputPlugin#enable
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to be enabled for input.
* @param {(Phaser.Types.Input.InputConfiguration|any)} [hitArea] - Either an input configuration object, or a geometric shape that defines the hit area for the Game Object. If not specified a Rectangle will be used.
* @param {Phaser.Types.Input.HitAreaCallback} [hitAreaCallback] - The 'contains' function to invoke to check if the pointer is within the hit area.
* @param {boolean} [dropZone=false] - Is this Game Object a drop zone or not?
*
* @return {this} This Input Plugin.
*/
enable: function(gameObject, hitArea, hitAreaCallback, dropZone) {
if (dropZone === void 0) {
dropZone = false;
}
if (gameObject.input) {
gameObject.input.enabled = true;
} else {
this.setHitArea(gameObject, hitArea, hitAreaCallback);
}
if (gameObject.input && dropZone && !gameObject.input.dropZone) {
gameObject.input.dropZone = dropZone;
}
return this;
},
/**
* Takes the given Pointer and performs a hit test against it, to see which interactive Game Objects
* it is currently above.
*
* The hit test is performed against which-ever Camera the Pointer is over. If it is over multiple
* cameras, it starts checking the camera at the top of the camera list, and if nothing is found, iterates down the list.
*
* @method Phaser.Input.InputPlugin#hitTestPointer
* @since 3.0.0
*
* @param {Phaser.Input.Pointer} pointer - The Pointer to check against the Game Objects.
*
* @return {Phaser.GameObjects.GameObject[]} An array of all the interactive Game Objects the Pointer was above.
*/
hitTestPointer: function(pointer) {
var cameras = this.cameras.getCamerasBelowPointer(pointer);
for (var c = 0; c < cameras.length; c++) {
var camera = cameras[c];
var over = this.manager.hitTest(pointer, this._list, camera);
for (var i = 0; i < over.length; i++) {
var obj = over[i];
if (obj.input.dropZone) {
this._tempZones.push(obj);
}
}
if (over.length > 0) {
pointer.camera = camera;
return over;
}
}
pointer.camera = cameras[0];
return [];
},
/**
* An internal method that handles the Pointer down event.
*
* @method Phaser.Input.InputPlugin#processDownEvents
* @private
* @fires Phaser.Input.Events#GAMEOBJECT_POINTER_DOWN
* @fires Phaser.Input.Events#GAMEOBJECT_DOWN
* @fires Phaser.Input.Events#POINTER_DOWN
* @fires Phaser.Input.Events#POINTER_DOWN_OUTSIDE
* @since 3.0.0
*
* @param {Phaser.Input.Pointer} pointer - The Pointer being tested.
*
* @return {number} The total number of objects interacted with.
*/
processDownEvents: function(pointer) {
var total = 0;
var currentlyOver = this._temp;
var _eventData = this._eventData;
var _eventContainer = this._eventContainer;
_eventData.cancelled = false;
for (var i = 0; i < currentlyOver.length; i++) {
var gameObject = currentlyOver[i];
if (!gameObject.input || !gameObject.input.enabled) {
continue;
}
total++;
gameObject.emit(Events.GAMEOBJECT_POINTER_DOWN, pointer, gameObject.input.localX, gameObject.input.localY, _eventContainer);
if (_eventData.cancelled || !this.isActive()) {
break;
}
if (gameObject.input && gameObject.input.enabled) {
this.emit(Events.GAMEOBJECT_DOWN, pointer, gameObject, _eventContainer);
if (_eventData.cancelled || !this.isActive()) {
break;
}
}
}
if (!_eventData.cancelled && this.isActive()) {
if (pointer.downElement === this.manager.game.canvas) {
this.emit(Events.POINTER_DOWN, pointer, currentlyOver);
} else {
this.emit(Events.POINTER_DOWN_OUTSIDE, pointer);
}
}
return total;
},
/**
* Returns the drag state of the given Pointer for this Input Plugin.
*
* The state will be one of the following:
*
* 0 = Not dragging anything
* 1 = Primary button down and objects below, so collect a draglist
* 2 = Pointer being checked if meets drag criteria
* 3 = Pointer meets criteria, notify the draglist
* 4 = Pointer actively dragging the draglist and has moved
* 5 = Pointer actively dragging but has been released, notify draglist
*
* @method Phaser.Input.InputPlugin#getDragState
* @since 3.16.0
*
* @param {Phaser.Input.Pointer} pointer - The Pointer to get the drag state for.
*
* @return {number} The drag state of the given Pointer.
*/
getDragState: function(pointer) {
return this._dragState[pointer.id];
},
/**
* Sets the drag state of the given Pointer for this Input Plugin.
*
* The state must be one of the following values:
*
* 0 = Not dragging anything
* 1 = Primary button down and objects below, so collect a draglist
* 2 = Pointer being checked if meets drag criteria
* 3 = Pointer meets criteria, notify the draglist
* 4 = Pointer actively dragging the draglist and has moved
* 5 = Pointer actively dragging but has been released, notify draglist
*
* @method Phaser.Input.InputPlugin#setDragState
* @since 3.16.0
*
* @param {Phaser.Input.Pointer} pointer - The Pointer to set the drag state for.
* @param {number} state - The drag state value. An integer between 0 and 5.
*/
setDragState: function(pointer, state) {
this._dragState[pointer.id] = state;
},
/**
* Checks to see if a Pointer is ready to drag the objects below it, based on either a distance
* or time threshold.
*
* @method Phaser.Input.InputPlugin#processDragThresholdEvent
* @private
* @since 3.18.0
*
* @param {Phaser.Input.Pointer} pointer - The Pointer to check the drag thresholds on.
* @param {number} time - The current time.
*/
processDragThresholdEvent: function(pointer, time) {
var passed = false;
var timeThreshold = this.dragTimeThreshold;
var distanceThreshold = this.dragDistanceThreshold;
if (distanceThreshold > 0 && DistanceBetween(pointer.x, pointer.y, pointer.downX, pointer.downY) >= distanceThreshold) {
passed = true;
} else if (timeThreshold > 0 && time >= pointer.downTime + timeThreshold) {
passed = true;
}
if (passed) {
this.setDragState(pointer, 3);
return this.processDragStartList(pointer);
}
},
/**
* Processes the drag list for the given pointer and dispatches the start events for each object on it.
*
* @method Phaser.Input.InputPlugin#processDragStartList
* @private
* @fires Phaser.Input.Events#DRAG_START
* @fires Phaser.Input.Events#GAMEOBJECT_DRAG_START
* @since 3.18.0
*
* @param {Phaser.Input.Pointer} pointer - The Pointer to process the drag event on.
*
* @return {number} The number of items that DRAG_START was called on.
*/
processDragStartList: function(pointer) {
if (this.getDragState(pointer) !== 3) {
return 0;
}
var list = this._drag[pointer.id];
if (list.length > 1) {
list = list.slice(0);
}
for (var i = 0; i < list.length; i++) {
var gameObject = list[i];
var input = gameObject.input;
input.dragState = 2;
input.dragStartX = gameObject.x;
input.dragStartY = gameObject.y;
input.dragStartXGlobal = pointer.worldX;
input.dragStartYGlobal = pointer.worldY;
input.dragStartCamera = pointer.camera;
input.dragX = input.dragStartXGlobal - input.dragStartX;
input.dragY = input.dragStartYGlobal - input.dragStartY;
gameObject.emit(Events.GAMEOBJECT_DRAG_START, pointer, input.dragX, input.dragY);
this.emit(Events.DRAG_START, pointer, gameObject);
}
this.setDragState(pointer, 4);
return list.length;
},
/**
* Processes a 'drag down' event for the given pointer. Checks the pointer state, builds-up the drag list
* and prepares them all for interaction.
*
* @method Phaser.Input.InputPlugin#processDragDownEvent
* @private
* @since 3.18.0
*
* @param {Phaser.Input.Pointer} pointer - The Pointer to process the drag event on.
*
* @return {number} The number of items that were collected on the drag list.
*/
processDragDownEvent: function(pointer) {
var currentlyOver = this._temp;
if (this._draggable.length === 0 || currentlyOver.length === 0 || !pointer.primaryDown || this.getDragState(pointer) !== 0) {
return 0;
}
this.setDragState(pointer, 1);
var draglist = [];
for (var i = 0; i < currentlyOver.length; i++) {
var gameObject = currentlyOver[i];
if (gameObject.input.draggable && gameObject.input.dragState === 0) {
draglist.push(gameObject);
}
}
if (draglist.length === 0) {
this.setDragState(pointer, 0);
return 0;
} else if (draglist.length > 1) {
this.sortGameObjects(draglist, pointer);
if (this.topOnly) {
draglist.splice(1);
}
}
this._drag[pointer.id] = draglist;
if (this.dragDistanceThreshold === 0 && this.dragTimeThreshold === 0) {
this.setDragState(pointer, 3);
return this.processDragStartList(pointer);
} else {
this.setDragState(pointer, 2);
return 0;
}
},
/**
* Processes a 'drag move' event for the given pointer.
*
* @method Phaser.Input.InputPlugin#processDragMoveEvent
* @private
* @fires Phaser.Input.Events#DRAG_ENTER
* @fires Phaser.Input.Events#DRAG
* @fires Phaser.Input.Events#DRAG_LEAVE
* @fires Phaser.Input.Events#DRAG_OVER
* @fires Phaser.Input.Events#GAMEOBJECT_DRAG_ENTER
* @fires Phaser.Input.Events#GAMEOBJECT_DRAG
* @fires Phaser.Input.Events#GAMEOBJECT_DRAG_LEAVE
* @fires Phaser.Input.Events#GAMEOBJECT_DRAG_OVER
* @since 3.18.0
*
* @param {Phaser.Input.Pointer} pointer - The Pointer to process the drag event on.
*
* @return {number} The number of items that were updated by this drag event.
*/
processDragMoveEvent: function(pointer) {
if (this.getDragState(pointer) === 2) {
this.processDragThresholdEvent(pointer, this.manager.game.loop.now);
}
if (this.getDragState(pointer) !== 4) {
return 0;
}
var dropZones = this._tempZones;
var list = this._drag[pointer.id];
if (list.length > 1) {
list = list.slice(0);
}
for (var i = 0; i < list.length; i++) {
var gameObject = list[i];
var input = gameObject.input;
var target = input.target;
if (target) {
var index = dropZones.indexOf(target);
if (index === 0) {
gameObject.emit(Events.GAMEOBJECT_DRAG_OVER, pointer, target);
this.emit(Events.DRAG_OVER, pointer, gameObject, target);
} else if (index > 0) {
gameObject.emit(Events.GAMEOBJECT_DRAG_LEAVE, pointer, target);
this.emit(Events.DRAG_LEAVE, pointer, gameObject, target);
input.target = dropZones[0];
target = input.target;
gameObject.emit(Events.GAMEOBJECT_DRAG_ENTER, pointer, target);
this.emit(Events.DRAG_ENTER, pointer, gameObject, target);
} else {
gameObject.emit(Events.GAMEOBJECT_DRAG_LEAVE, pointer, target);
this.emit(Events.DRAG_LEAVE, pointer, gameObject, target);
if (dropZones[0]) {
input.target = dropZones[0];
target = input.target;
gameObject.emit(Events.GAMEOBJECT_DRAG_ENTER, pointer, target);
this.emit(Events.DRAG_ENTER, pointer, gameObject, target);
} else {
input.target = null;
}
}
} else if (!target && dropZones[0]) {
input.target = dropZones[0];
target = input.target;
gameObject.emit(Events.GAMEOBJECT_DRAG_ENTER, pointer, target);
this.emit(Events.DRAG_ENTER, pointer, gameObject, target);
}
var dragX;
var dragY;
var dragWorldXY = pointer.positionToCamera(input.dragStartCamera);
if (!gameObject.parentContainer) {
dragX = dragWorldXY.x - input.dragX;
dragY = dragWorldXY.y - input.dragY;
} else {
var dx = dragWorldXY.x - input.dragStartXGlobal;
var dy = dragWorldXY.y - input.dragStartYGlobal;
var rotation = gameObject.getParentRotation();
var dxRotated = dx * Math.cos(rotation) + dy * Math.sin(rotation);
var dyRotated = dy * Math.cos(rotation) - dx * Math.sin(rotation);
dxRotated *= 1 / gameObject.parentContainer.scaleX;
dyRotated *= 1 / gameObject.parentContainer.scaleY;
dragX = dxRotated + input.dragStartX;
dragY = dyRotated + input.dragStartY;
}
gameObject.emit(Events.GAMEOBJECT_DRAG, pointer, dragX, dragY);
this.emit(Events.DRAG, pointer, gameObject, dragX, dragY);
}
return list.length;
},
/**
* Processes a 'drag down' event for the given pointer. Checks the pointer state, builds-up the drag list
* and prepares them all for interaction.
*
* @method Phaser.Input.InputPlugin#processDragUpEvent
* @fires Phaser.Input.Events#DRAG_END
* @fires Phaser.Input.Events#DROP
* @fires Phaser.Input.Events#GAMEOBJECT_DRAG_END
* @fires Phaser.Input.Events#GAMEOBJECT_DROP
* @private
* @since 3.18.0
*
* @param {Phaser.Input.Pointer} pointer - The Pointer to process the drag event on.
*
* @return {number} The number of items that were updated by this drag event.
*/
processDragUpEvent: function(pointer) {
var list = this._drag[pointer.id];
if (list.length > 1) {
list = list.slice(0);
}
for (var i = 0; i < list.length; i++) {
var gameObject = list[i];
var input = gameObject.input;
if (input && input.dragState === 2) {
input.dragState = 0;
input.dragX = input.localX - gameObject.displayOriginX;
input.dragY = input.localY - gameObject.displayOriginY;
input.dragStartCamera = null;
var dropped = false;
var target = input.target;
if (target) {
gameObject.emit(Events.GAMEOBJECT_DROP, pointer, target);
this.emit(Events.DROP, pointer, gameObject, target);
input.target = null;
dropped = true;
}
if (gameObject.input && gameObject.input.enabled) {
gameObject.emit(Events.GAMEOBJECT_DRAG_END, pointer, input.dragX, input.dragY, dropped);
this.emit(Events.DRAG_END, pointer, gameObject, dropped);
}
}
}
this.setDragState(pointer, 0);
list.splice(0);
return 0;
},
/**
* An internal method that handles the Pointer movement event.
*
* @method Phaser.Input.InputPlugin#processMoveEvents
* @private
* @fires Phaser.Input.Events#GAMEOBJECT_POINTER_MOVE
* @fires Phaser.Input.Events#GAMEOBJECT_MOVE
* @fires Phaser.Input.Events#POINTER_MOVE
* @since 3.0.0
*
* @param {Phaser.Input.Pointer} pointer - The pointer to check for events against.
*
* @return {number} The total number of objects interacted with.
*/
processMoveEvents: function(pointer) {
var total = 0;
var currentlyOver = this._temp;
var _eventData = this._eventData;
var _eventContainer = this._eventContainer;
_eventData.cancelled = false;
for (var i = 0; i < currentlyOver.length; i++) {
var gameObject = currentlyOver[i];
if (!gameObject.input || !gameObject.input.enabled) {
continue;
}
total++;
gameObject.emit(Events.GAMEOBJECT_POINTER_MOVE, pointer, gameObject.input.localX, gameObject.input.localY, _eventContainer);
if (_eventData.cancelled || !this.isActive()) {
break;
}
if (gameObject.input && gameObject.input.enabled) {
this.emit(Events.GAMEOBJECT_MOVE, pointer, gameObject, _eventContainer);
if (_eventData.cancelled || !this.isActive()) {
break;
}
if (this.topOnly) {
break;
}
}
}
if (!_eventData.cancelled && this.isActive()) {
this.emit(Events.POINTER_MOVE, pointer, currentlyOver);
}
return total;
},
/**
* An internal method that handles a mouse wheel event.
*
* @method Phaser.Input.InputPlugin#processWheelEvent
* @private
* @fires Phaser.Input.Events#GAMEOBJECT_POINTER_WHEEL
* @fires Phaser.Input.Events#GAMEOBJECT_WHEEL
* @fires Phaser.Input.Events#POINTER_WHEEL
* @since 3.18.0
*
* @param {Phaser.Input.Pointer} pointer - The pointer to check for events against.
*
* @return {number} The total number of objects interacted with.
*/
processWheelEvent: function(pointer) {
var total = 0;
var currentlyOver = this._temp;
var _eventData = this._eventData;
var _eventContainer = this._eventContainer;
_eventData.cancelled = false;
var dx = pointer.deltaX;
var dy = pointer.deltaY;
var dz = pointer.deltaZ;
for (var i = 0; i < currentlyOver.length; i++) {
var gameObject = currentlyOver[i];
if (!gameObject.input || !gameObject.input.enabled) {
continue;
}
total++;
gameObject.emit(Events.GAMEOBJECT_POINTER_WHEEL, pointer, dx, dy, dz, _eventContainer);
if (_eventData.cancelled || !this.isActive()) {
break;
}
if (gameObject.input && gameObject.input.enabled) {
this.emit(Events.GAMEOBJECT_WHEEL, pointer, gameObject, dx, dy, dz, _eventContainer);
if (_eventData.cancelled || !this.isActive()) {
break;
}
}
}
if (!_eventData.cancelled && this.isActive()) {
this.emit(Events.POINTER_WHEEL, pointer, currentlyOver, dx, dy, dz);
}
return total;
},
/**
* An internal method that handles the Pointer over events.
* This is called when a touch input hits the canvas, having previously been off of it.
*
* @method Phaser.Input.InputPlugin#processOverEvents
* @private
* @fires Phaser.Input.Events#GAMEOBJECT_POINTER_OVER
* @fires Phaser.Input.Events#GAMEOBJECT_OVER
* @fires Phaser.Input.Events#POINTER_OVER
* @since 3.18.0
*
* @param {Phaser.Input.Pointer} pointer - The pointer to check for events against.
*
* @return {number} The total number of objects interacted with.
*/
processOverEvents: function(pointer) {
var currentlyOver = this._temp;
var totalInteracted = 0;
var total = currentlyOver.length;
var justOver = [];
if (total > 0) {
var manager = this.manager;
var _eventData = this._eventData;
var _eventContainer = this._eventContainer;
_eventData.cancelled = false;
for (var i = 0; i < total; i++) {
var gameObject = currentlyOver[i];
if (!gameObject.input || !gameObject.input.enabled) {
continue;
}
justOver.push(gameObject);
manager.setCursor(gameObject.input);
gameObject.emit(Events.GAMEOBJECT_POINTER_OVER, pointer, gameObject.input.localX, gameObject.input.localY, _eventContainer);
totalInteracted++;
if (_eventData.cancelled || !this.isActive()) {
break;
}
if (gameObject.input && gameObject.input.enabled) {
this.emit(Events.GAMEOBJECT_OVER, pointer, gameObject, _eventContainer);
if (_eventData.cancelled || !this.isActive()) {
break;
}
}
}
if (!_eventData.cancelled && this.isActive()) {
this.emit(Events.POINTER_OVER, pointer, justOver);
}
}
this._over[pointer.id] = justOver;
return totalInteracted;
},
/**
* An internal method that handles the Pointer out events.
* This is called when a touch input leaves the canvas, as it can never be 'over' in this case.
*
* @method Phaser.Input.InputPlugin#processOutEvents
* @private
* @fires Phaser.Input.Events#GAMEOBJECT_POINTER_OUT
* @fires Phaser.Input.Events#GAMEOBJECT_OUT
* @fires Phaser.Input.Events#POINTER_OUT
* @since 3.18.0
*
* @param {Phaser.Input.Pointer} pointer - The pointer to check for events against.
*
* @return {number} The total number of objects interacted with.
*/
processOutEvents: function(pointer) {
var previouslyOver = this._over[pointer.id];
var totalInteracted = 0;
var total = previouslyOver.length;
if (total > 0) {
var manager = this.manager;
var _eventData = this._eventData;
var _eventContainer = this._eventContainer;
_eventData.cancelled = false;
this.sortGameObjects(previouslyOver, pointer);
for (var i = 0; i < total; i++) {
var gameObject = previouslyOver[i];
gameObject = previouslyOver[i];
if (!gameObject.input || !gameObject.input.enabled) {
continue;
}
manager.resetCursor(gameObject.input);
gameObject.emit(Events.GAMEOBJECT_POINTER_OUT, pointer, _eventContainer);
totalInteracted++;
if (_eventData.cancelled || !this.isActive()) {
break;
}
if (gameObject.input && gameObject.input.enabled) {
this.emit(Events.GAMEOBJECT_OUT, pointer, gameObject, _eventContainer);
if (_eventData.cancelled || !this.isActive()) {
break;
}
}
}
if (!_eventData.cancelled && this.isActive()) {
this.emit(Events.POINTER_OUT, pointer, previouslyOver);
}
this._over[pointer.id] = [];
}
return totalInteracted;
},
/**
* An internal method that handles the Pointer over and out events.
*
* @method Phaser.Input.InputPlugin#processOverOutEvents
* @private
* @fires Phaser.Input.Events#GAMEOBJECT_POINTER_OVER
* @fires Phaser.Input.Events#GAMEOBJECT_OVER
* @fires Phaser.Input.Events#POINTER_OVER
* @fires Phaser.Input.Events#GAMEOBJECT_POINTER_OUT
* @fires Phaser.Input.Events#GAMEOBJECT_OUT
* @fires Phaser.Input.Events#POINTER_OUT
* @since 3.0.0
*
* @param {Phaser.Input.Pointer} pointer - The pointer to check for events against.
*
* @return {number} The total number of objects interacted with.
*/
processOverOutEvents: function(pointer) {
var currentlyOver = this._temp;
var i;
var gameObject;
var justOut = [];
var justOver = [];
var stillOver = [];
var previouslyOver = this._over[pointer.id];
var currentlyDragging = this._drag[pointer.id];
var manager = this.manager;
for (i = 0; i < previouslyOver.length; i++) {
gameObject = previouslyOver[i];
if (currentlyOver.indexOf(gameObject) === -1 && currentlyDragging.indexOf(gameObject) === -1) {
justOut.push(gameObject);
} else {
stillOver.push(gameObject);
}
}
for (i = 0; i < currentlyOver.length; i++) {
gameObject = currentlyOver[i];
if (previouslyOver.indexOf(gameObject) === -1) {
justOver.push(gameObject);
}
}
var total = justOut.length;
var totalInteracted = 0;
var _eventData = this._eventData;
var _eventContainer = this._eventContainer;
_eventData.cancelled = false;
if (total > 0) {
this.sortGameObjects(justOut, pointer);
for (i = 0; i < total; i++) {
gameObject = justOut[i];
if (!gameObject.input || !gameObject.input.enabled) {
continue;
}
manager.resetCursor(gameObject.input);
gameObject.emit(Events.GAMEOBJECT_POINTER_OUT, pointer, _eventContainer);
totalInteracted++;
if (_eventData.cancelled || !this.isActive()) {
break;
}
if (gameObject.input && gameObject.input.enabled) {
this.emit(Events.GAMEOBJECT_OUT, pointer, gameObject, _eventContainer);
if (_eventData.cancelled || !this.isActive()) {
break;
}
}
}
if (!_eventData.cancelled || this.isActive()) {
this.emit(Events.POINTER_OUT, pointer, justOut);
}
}
total = justOver.length;
_eventData.cancelled = false;
if (total > 0) {
this.sortGameObjects(justOver, pointer);
for (i = 0; i < total; i++) {
gameObject = justOver[i];
if (!gameObject.input || !gameObject.input.enabled) {
continue;
}
manager.setCursor(gameObject.input);
gameObject.emit(Events.GAMEOBJECT_POINTER_OVER, pointer, gameObject.input.localX, gameObject.input.localY, _eventContainer);
totalInteracted++;
if (_eventData.cancelled || !this.isActive()) {
break;
}
if (gameObject.input && gameObject.input.enabled) {
this.emit(Events.GAMEOBJECT_OVER, pointer, gameObject, _eventContainer);
if (_eventData.cancelled || !this.isActive()) {
break;
}
}
}
if (!_eventData.cancelled && this.isActive()) {
this.emit(Events.POINTER_OVER, pointer, justOver);
}
}
previouslyOver = stillOver.concat(justOver);
this._over[pointer.id] = this.sortGameObjects(previouslyOver, pointer);
return totalInteracted;
},
/**
* An internal method that handles the Pointer up events.
*
* @method Phaser.Input.InputPlugin#processUpEvents
* @private
* @fires Phaser.Input.Events#GAMEOBJECT_POINTER_UP
* @fires Phaser.Input.Events#GAMEOBJECT_UP
* @fires Phaser.Input.Events#POINTER_UP
* @fires Phaser.Input.Events#POINTER_UP_OUTSIDE
* @since 3.0.0
*
* @param {Phaser.Input.Pointer} pointer - The pointer to check for events against.
*
* @return {number} The total number of objects interacted with.
*/
processUpEvents: function(pointer) {
var currentlyOver = this._temp;
var _eventData = this._eventData;
var _eventContainer = this._eventContainer;
_eventData.cancelled = false;
for (var i = 0; i < currentlyOver.length; i++) {
var gameObject = currentlyOver[i];
if (!gameObject.input || !gameObject.input.enabled) {
continue;
}
gameObject.emit(Events.GAMEOBJECT_POINTER_UP, pointer, gameObject.input.localX, gameObject.input.localY, _eventContainer);
if (_eventData.cancelled || !this.isActive()) {
break;
}
if (gameObject.input && gameObject.input.enabled) {
this.emit(Events.GAMEOBJECT_UP, pointer, gameObject, _eventContainer);
if (_eventData.cancelled || !this.isActive()) {
break;
}
}
}
if (!_eventData.cancelled && this.isActive()) {
if (pointer.upElement === this.manager.game.canvas) {
this.emit(Events.POINTER_UP, pointer, currentlyOver);
} else {
this.emit(Events.POINTER_UP_OUTSIDE, pointer);
}
}
return currentlyOver.length;
},
/**
* This method will force the given Game Object into the 'down' input state.
*
* This will check to see if the Game Object is enabled for input, and if so,
* it will emit the `GAMEOBJECT_POINTER_DOWN` event for it. If that doesn't change
* the input state, it will then emit the `GAMEOBJECT_DOWN` event.
*
* The Game Object is not checked against the Pointer to see if it can enter this state,
* that is up to you to do before calling this method.
*
* @method Phaser.Input.InputPlugin#forceDownState
* @fires Phaser.Input.Events#GAMEOBJECT_POINTER_DOWN
* @fires Phaser.Input.Events#GAMEOBJECT_DOWN
* @since 3.85.0
*
* @param {Phaser.Input.Pointer} pointer - The pointer to use when setting the state.
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to have its state set.
*/
forceDownState: function(pointer, gameObject) {
this.forceState(pointer, gameObject, Events.GAMEOBJECT_POINTER_DOWN, Events.GAMEOBJECT_DOWN, false);
},
/**
* This method will force the given Game Object into the 'up' input state.
*
* This will check to see if the Game Object is enabled for input, and if so,
* it will emit the `GAMEOBJECT_POINTER_UP` event for it. If that doesn't change
* the input state, it will then emit the `GAMEOBJECT_UP` event.
*
* The Game Object is not checked against the Pointer to see if it can enter this state,
* that is up to you to do before calling this method.
*
* @method Phaser.Input.InputPlugin#forceUpState
* @fires Phaser.Input.Events#GAMEOBJECT_POINTER_UP
* @fires Phaser.Input.Events#GAMEOBJECT_UP
* @since 3.85.0
*
* @param {Phaser.Input.Pointer} pointer - The pointer to use when setting the state.
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to have its state set.
*/
forceUpState: function(pointer, gameObject) {
this.forceState(pointer, gameObject, Events.GAMEOBJECT_POINTER_UP, Events.GAMEOBJECT_UP, false);
},
/**
* This method will force the given Game Object into the 'over' input state.
*
* This will check to see if the Game Object is enabled for input, and if so,
* it will emit the `GAMEOBJECT_POINTER_OVER` event for it. If that doesn't change
* the input state, it will then emit the `GAMEOBJECT_OVER` event.
*
* The Game Object is not checked against the Pointer to see if it can enter this state,
* that is up to you to do before calling this method.
*
* @method Phaser.Input.InputPlugin#forceOverState
* @fires Phaser.Input.Events#GAMEOBJECT_POINTER_OVER
* @fires Phaser.Input.Events#GAMEOBJECT_OVER
* @since 3.85.0
*
* @param {Phaser.Input.Pointer} pointer - The pointer to use when setting the state.
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to have its state set.
*/
forceOverState: function(pointer, gameObject) {
this.forceState(pointer, gameObject, Events.GAMEOBJECT_POINTER_OVER, Events.GAMEOBJECT_OVER, true);
},
/**
* This method will force the given Game Object into the 'out' input state.
*
* This will check to see if the Game Object is enabled for input, and if so,
* it will emit the `GAMEOBJECT_POINTER_OUT` event for it. If that doesn't change
* the input state, it will then emit the `GAMEOBJECT_OUT` event.
*
* The Game Object is not checked against the Pointer to see if it can enter this state,
* that is up to you to do before calling this method.
*
* @method Phaser.Input.InputPlugin#forceOutState
* @fires Phaser.Input.Events#GAMEOBJECT_POINTER_OUT
* @fires Phaser.Input.Events#GAMEOBJECT_OUT
* @since 3.85.0
*
* @param {Phaser.Input.Pointer} pointer - The pointer to use when setting the state.
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to have its state set.
*/
forceOutState: function(pointer, gameObject) {
this.forceState(pointer, gameObject, Events.GAMEOBJECT_POINTER_OUT, Events.GAMEOBJECT_OUT, false);
},
/**
* This method will force the given Game Object into the given input state.
*
* @method Phaser.Input.InputPlugin#forceState
* @since 3.85.0
*
* @param {Phaser.Input.Pointer} pointer - The pointer to use when setting the state.
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to have its state set.
* @param {string} gameObjectEvent - The event to emit on the Game Object.
* @param {string} inputPluginEvent - The event to emit on the Input Plugin.
* @param {boolean} [setCursor=false] - Should the cursor be set to the Game Object's cursor?
*/
forceState: function(pointer, gameObject, gameObjectEvent, inputPluginEvent, setCursor) {
var _eventData = this._eventData;
var _eventContainer = this._eventContainer;
_eventData.cancelled = false;
if (gameObject.input && gameObject.input.enabled) {
gameObject.emit(gameObjectEvent, pointer, gameObject.input.localX, gameObject.input.localY, _eventContainer);
if (setCursor) {
this.setCursor(gameObject.input);
}
if (!_eventData.cancelled && this.isActive() && gameObject.input && gameObject.input.enabled) {
this.emit(inputPluginEvent, pointer, gameObject, _eventContainer);
}
}
},
/**
* Queues a Game Object for insertion into this Input Plugin on the next update.
*
* @method Phaser.Input.InputPlugin#queueForInsertion
* @private
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} child - The Game Object to add.
*
* @return {this} This InputPlugin object.
*/
queueForInsertion: function(child) {
if (this._pendingInsertion.indexOf(child) === -1 && this._list.indexOf(child) === -1) {
this._pendingInsertion.push(child);
}
return this;
},
/**
* Queues a Game Object for removal from this Input Plugin on the next update.
*
* @method Phaser.Input.InputPlugin#queueForRemoval
* @private
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} child - The Game Object to remove.
*
* @return {this} This InputPlugin object.
*/
queueForRemoval: function(child) {
this._pendingRemoval.push(child);
return this;
},
/**
* Sets the draggable state of the given array of Game Objects.
*
* They can either be set to be draggable, or can have their draggable state removed by passing `false`.
*
* A Game Object will not fire drag events unless it has been specifically enabled for drag.
*
* @method Phaser.Input.InputPlugin#setDraggable
* @since 3.0.0
*
* @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to change the draggable state on.
* @param {boolean} [value=true] - Set to `true` if the Game Objects should be made draggable, `false` if they should be unset.
*
* @return {this} This InputPlugin object.
*/
setDraggable: function(gameObjects, value) {
if (value === void 0) {
value = true;
}
if (!Array.isArray(gameObjects)) {
gameObjects = [gameObjects];
}
for (var i = 0; i < gameObjects.length; i++) {
var gameObject = gameObjects[i];
gameObject.input.draggable = value;
var index = this._draggable.indexOf(gameObject);
if (value && index === -1) {
this._draggable.push(gameObject);
} else if (!value && index > -1) {
this._draggable.splice(index, 1);
}
}
return this;
},
/**
* Creates a function that can be passed to `setInteractive`, `enable` or `setHitArea` that will handle
* pixel-perfect input detection on an Image or Sprite based Game Object, or any custom class that extends them.
*
* The following will create a sprite that is clickable on any pixel that has an alpha value >= 1.
*
* ```javascript
* this.add.sprite(x, y, key).setInteractive(this.input.makePixelPerfect());
* ```
*
* The following will create a sprite that is clickable on any pixel that has an alpha value >= 150.
*
* ```javascript
* this.add.sprite(x, y, key).setInteractive(this.input.makePixelPerfect(150));
* ```
*
* Once you have made an Interactive Object pixel perfect it impacts all input related events for it: down, up,
* dragstart, drag, etc.
*
* As a pointer interacts with the Game Object it will constantly poll the texture, extracting a single pixel from
* the given coordinates and checking its color values. This is an expensive process, so should only be enabled on
* Game Objects that really need it.
*
* You cannot make non-texture based Game Objects pixel perfect. So this will not work on Graphics, BitmapText,
* Render Textures, Text, Tilemaps, Containers or Particles.
*
* @method Phaser.Input.InputPlugin#makePixelPerfect
* @since 3.10.0
*
* @param {number} [alphaTolerance=1] - The alpha level that the pixel should be above to be included as a successful interaction.
*
* @return {function} A Pixel Perfect Handler for use as a hitArea shape callback.
*/
makePixelPerfect: function(alphaTolerance) {
if (alphaTolerance === void 0) {
alphaTolerance = 1;
}
var textureManager = this.systems.textures;
return CreatePixelPerfectHandler(textureManager, alphaTolerance);
},
/**
* Sets the hit area for the given array of Game Objects.
*
* A hit area is typically one of the geometric shapes Phaser provides, such as a `Phaser.Geom.Rectangle`
* or `Phaser.Geom.Circle`. However, it can be any object as long as it works with the provided callback.
*
* If no hit area is provided a Rectangle is created based on the size of the Game Object, if possible
* to calculate.
*
* The hit area callback is the function that takes an `x` and `y` coordinate and returns a boolean if
* those values fall within the area of the shape or not. All of the Phaser geometry objects provide this,
* such as `Phaser.Geom.Rectangle.Contains`.
*
* A hit area callback can be supplied to the `hitArea` parameter without using the `hitAreaCallback` parameter.
*
* @method Phaser.Input.InputPlugin#setHitArea
* @since 3.0.0
*
* @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to set the hit area on.
* @param {(Phaser.Types.Input.InputConfiguration|Phaser.Types.Input.HitAreaCallback|any)} [hitArea] - Either an input configuration object, a geometric shape that defines the hit area or a hit area callback. If not specified a Rectangle hit area will be used.
* @param {Phaser.Types.Input.HitAreaCallback} [hitAreaCallback] - The 'contains' function to invoke to check if the pointer is within the hit area.
*
* @return {this} This InputPlugin object.
*/
setHitArea: function(gameObjects, hitArea, hitAreaCallback) {
if (hitArea === void 0) {
return this.setHitAreaFromTexture(gameObjects);
}
if (!Array.isArray(gameObjects)) {
gameObjects = [gameObjects];
}
var draggable = false;
var dropZone = false;
var cursor = false;
var useHandCursor = false;
var pixelPerfect = false;
var customHitArea = true;
if (IsPlainObject(hitArea) && Object.keys(hitArea).length) {
var config = hitArea;
var isMesh = gameObjects.some(function(gameObject2) {
return gameObject2.hasOwnProperty("faces");
});
if (!isMesh) {
hitArea = GetFastValue(config, "hitArea", null);
hitAreaCallback = GetFastValue(config, "hitAreaCallback", null);
pixelPerfect = GetFastValue(config, "pixelPerfect", false);
var alphaTolerance = GetFastValue(config, "alphaTolerance", 1);
if (pixelPerfect) {
hitArea = {};
hitAreaCallback = this.makePixelPerfect(alphaTolerance);
}
}
draggable = GetFastValue(config, "draggable", false);
dropZone = GetFastValue(config, "dropZone", false);
cursor = GetFastValue(config, "cursor", false);
useHandCursor = GetFastValue(config, "useHandCursor", false);
if (!hitArea || !hitAreaCallback) {
this.setHitAreaFromTexture(gameObjects);
customHitArea = false;
}
} else if (typeof hitArea === "function" && !hitAreaCallback) {
hitAreaCallback = hitArea;
hitArea = {};
}
for (var i = 0; i < gameObjects.length; i++) {
var gameObject = gameObjects[i];
if (pixelPerfect && gameObject.type === "Container") {
console.warn("Cannot pixelPerfect test a Container. Use a custom callback.");
continue;
}
var io = !gameObject.input ? CreateInteractiveObject(gameObject, hitArea, hitAreaCallback) : gameObject.input;
io.customHitArea = customHitArea;
io.dropZone = dropZone;
io.cursor = useHandCursor ? "pointer" : cursor;
gameObject.input = io;
if (draggable) {
this.setDraggable(gameObject);
}
this.queueForInsertion(gameObject);
}
return this;
},
/**
* Sets the hit area for an array of Game Objects to be a `Phaser.Geom.Circle` shape, using
* the given coordinates and radius to control its position and size.
*
* @method Phaser.Input.InputPlugin#setHitAreaCircle
* @since 3.0.0
*
* @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to set as having a circle hit area.
* @param {number} x - The center of the circle.
* @param {number} y - The center of the circle.
* @param {number} radius - The radius of the circle.
* @param {Phaser.Types.Input.HitAreaCallback} [callback] - The hit area callback. If undefined it uses Circle.Contains.
*
* @return {this} This InputPlugin object.
*/
setHitAreaCircle: function(gameObjects, x, y, radius, callback) {
if (callback === void 0) {
callback = CircleContains;
}
var shape = new Circle(x, y, radius);
return this.setHitArea(gameObjects, shape, callback);
},
/**
* Sets the hit area for an array of Game Objects to be a `Phaser.Geom.Ellipse` shape, using
* the given coordinates and dimensions to control its position and size.
*
* @method Phaser.Input.InputPlugin#setHitAreaEllipse
* @since 3.0.0
*
* @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to set as having an ellipse hit area.
* @param {number} x - The center of the ellipse.
* @param {number} y - The center of the ellipse.
* @param {number} width - The width of the ellipse.
* @param {number} height - The height of the ellipse.
* @param {Phaser.Types.Input.HitAreaCallback} [callback] - The hit area callback. If undefined it uses Ellipse.Contains.
*
* @return {this} This InputPlugin object.
*/
setHitAreaEllipse: function(gameObjects, x, y, width, height, callback) {
if (callback === void 0) {
callback = EllipseContains;
}
var shape = new Ellipse(x, y, width, height);
return this.setHitArea(gameObjects, shape, callback);
},
/**
* Sets the hit area for an array of Game Objects to be a `Phaser.Geom.Rectangle` shape, using
* the Game Objects texture frame to define the position and size of the hit area.
*
* @method Phaser.Input.InputPlugin#setHitAreaFromTexture
* @since 3.0.0
*
* @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to set as having an ellipse hit area.
* @param {Phaser.Types.Input.HitAreaCallback} [callback] - The hit area callback. If undefined it uses Rectangle.Contains.
*
* @return {this} This InputPlugin object.
*/
setHitAreaFromTexture: function(gameObjects, callback) {
if (callback === void 0) {
callback = RectangleContains;
}
if (!Array.isArray(gameObjects)) {
gameObjects = [gameObjects];
}
for (var i = 0; i < gameObjects.length; i++) {
var gameObject = gameObjects[i];
var frame = gameObject.frame;
var width = 0;
var height = 0;
if (gameObject.width) {
width = gameObject.width;
height = gameObject.height;
} else if (frame) {
width = frame.realWidth;
height = frame.realHeight;
}
if (gameObject.type === "Container" && (width === 0 || height === 0)) {
console.warn("Container.setInteractive must specify a Shape or call setSize() first");
continue;
}
if (width !== 0 && height !== 0) {
gameObject.input = CreateInteractiveObject(gameObject, new Rectangle(0, 0, width, height), callback);
this.queueForInsertion(gameObject);
}
}
return this;
},
/**
* Sets the hit area for an array of Game Objects to be a `Phaser.Geom.Rectangle` shape, using
* the given coordinates and dimensions to control its position and size.
*
* @method Phaser.Input.InputPlugin#setHitAreaRectangle
* @since 3.0.0
*
* @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to set as having a rectangular hit area.
* @param {number} x - The top-left of the rectangle.
* @param {number} y - The top-left of the rectangle.
* @param {number} width - The width of the rectangle.
* @param {number} height - The height of the rectangle.
* @param {Phaser.Types.Input.HitAreaCallback} [callback] - The hit area callback. If undefined it uses Rectangle.Contains.
*
* @return {this} This InputPlugin object.
*/
setHitAreaRectangle: function(gameObjects, x, y, width, height, callback) {
if (callback === void 0) {
callback = RectangleContains;
}
var shape = new Rectangle(x, y, width, height);
return this.setHitArea(gameObjects, shape, callback);
},
/**
* Sets the hit area for an array of Game Objects to be a `Phaser.Geom.Triangle` shape, using
* the given coordinates to control the position of its points.
*
* @method Phaser.Input.InputPlugin#setHitAreaTriangle
* @since 3.0.0
*
* @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[])} gameObjects - An array of Game Objects to set as having a triangular hit area.
* @param {number} x1 - The x coordinate of the first point of the triangle.
* @param {number} y1 - The y coordinate of the first point of the triangle.
* @param {number} x2 - The x coordinate of the second point of the triangle.
* @param {number} y2 - The y coordinate of the second point of the triangle.
* @param {number} x3 - The x coordinate of the third point of the triangle.
* @param {number} y3 - The y coordinate of the third point of the triangle.
* @param {Phaser.Types.Input.HitAreaCallback} [callback] - The hit area callback. If undefined it uses Triangle.Contains.
*
* @return {this} This InputPlugin object.
*/
setHitAreaTriangle: function(gameObjects, x1, y1, x2, y2, x3, y3, callback) {
if (callback === void 0) {
callback = TriangleContains;
}
var shape = new Triangle(x1, y1, x2, y2, x3, y3);
return this.setHitArea(gameObjects, shape, callback);
},
/**
* Creates an Input Debug Shape for the given Game Object.
*
* The Game Object must have _already_ been enabled for input prior to calling this method.
*
* This is intended to assist you during development and debugging.
*
* Debug Shapes can only be created for Game Objects that are using standard Phaser Geometry for input,
* including: Circle, Ellipse, Line, Polygon, Rectangle and Triangle.
*
* Game Objects that are using their automatic hit areas are using Rectangles by default, so will also work.
*
* The Debug Shape is created and added to the display list and is then kept in sync with the Game Object
* it is connected with. Should you need to modify it yourself, such as to hide it, you can access it via
* the Game Object property: `GameObject.input.hitAreaDebug`.
*
* Calling this method on a Game Object that already has a Debug Shape will first destroy the old shape,
* before creating a new one. If you wish to remove the Debug Shape entirely, you should call the
* method `InputPlugin.removeDebug`.
*
* Note that the debug shape will only show the outline of the input area. If the input test is using a
* pixel perfect check, for example, then this is not displayed. If you are using a custom shape, that
* doesn't extend one of the base Phaser Geometry objects, as your hit area, then this method will not
* work.
*
* @method Phaser.Input.InputPlugin#enableDebug
* @since 3.19.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to create the input debug shape for.
* @param {number} [color=0x00ff00] - The outline color of the debug shape.
*
* @return {this} This Input Plugin.
*/
enableDebug: function(gameObject, color) {
if (color === void 0) {
color = 65280;
}
var input = gameObject.input;
if (!input || !input.hitArea) {
return this;
}
var shape = input.hitArea;
var shapeType = shape.type;
var debug = input.hitAreaDebug;
var factory = this.systems.add;
var updateList = this.systems.updateList;
if (debug) {
updateList.remove(debug);
debug.destroy();
debug = null;
}
var offsetx = 0;
var offsety = 0;
switch (shapeType) {
case GEOM_CONST.CIRCLE:
debug = factory.arc(0, 0, shape.radius);
offsetx = shape.x - shape.radius;
offsety = shape.y - shape.radius;
break;
case GEOM_CONST.ELLIPSE:
debug = factory.ellipse(0, 0, shape.width, shape.height);
offsetx = shape.x - shape.width / 2;
offsety = shape.y - shape.height / 2;
break;
case GEOM_CONST.LINE:
debug = factory.line(0, 0, shape.x1, shape.y1, shape.x2, shape.y2);
break;
case GEOM_CONST.POLYGON:
debug = factory.polygon(0, 0, shape.points);
break;
case GEOM_CONST.RECTANGLE:
debug = factory.rectangle(0, 0, shape.width, shape.height);
offsetx = shape.x;
offsety = shape.y;
break;
case GEOM_CONST.TRIANGLE:
debug = factory.triangle(0, 0, shape.x1, shape.y1, shape.x2, shape.y2, shape.x3, shape.y3);
break;
}
if (debug) {
debug.isFilled = false;
debug.strokeColor = color;
debug.preUpdate = function() {
debug.setVisible(gameObject.visible);
debug.setStrokeStyle(1 / gameObject.scale, debug.strokeColor);
debug.setDisplayOrigin(gameObject.displayOriginX, gameObject.displayOriginY);
var x = gameObject.x;
var y = gameObject.y;
var rotation = gameObject.rotation;
var scaleX = gameObject.scaleX;
var scaleY = gameObject.scaleY;
if (gameObject.parentContainer) {
var matrix = gameObject.getWorldTransformMatrix();
x = matrix.tx;
y = matrix.ty;
rotation = matrix.rotation;
scaleX = matrix.scaleX;
scaleY = matrix.scaleY;
}
debug.setRotation(rotation);
debug.setScale(scaleX, scaleY);
debug.setPosition(x + offsetx * scaleX, y + offsety * scaleY);
debug.setScrollFactor(gameObject.scrollFactorX, gameObject.scrollFactorY);
debug.setDepth(gameObject.depth);
};
updateList.add(debug);
input.hitAreaDebug = debug;
}
return this;
},
/**
* Removes an Input Debug Shape from the given Game Object.
*
* The shape is destroyed immediately and the `hitAreaDebug` property is set to `null`.
*
* @method Phaser.Input.InputPlugin#removeDebug
* @since 3.19.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to remove the input debug shape from.
*
* @return {this} This Input Plugin.
*/
removeDebug: function(gameObject) {
var input = gameObject.input;
if (input && input.hitAreaDebug) {
var debug = input.hitAreaDebug;
debug.destroy();
input.hitAreaDebug = null;
}
return this;
},
/**
* Sets the Pointers to always poll.
*
* When a pointer is polled it runs a hit test to see which Game Objects are currently below it,
* or being interacted with it, regardless if the Pointer has actually moved or not.
*
* You should enable this if you want objects in your game to fire over / out events, and the objects
* are constantly moving, but the pointer may not have. Polling every frame has additional computation
* costs, especially if there are a large number of interactive objects in your game.
*
* @method Phaser.Input.InputPlugin#setPollAlways
* @since 3.0.0
*
* @return {this} This InputPlugin object.
*/
setPollAlways: function() {
return this.setPollRate(0);
},
/**
* Sets the Pointers to only poll when they are moved or updated.
*
* When a pointer is polled it runs a hit test to see which Game Objects are currently below it,
* or being interacted with it.
*
* @method Phaser.Input.InputPlugin#setPollOnMove
* @since 3.0.0
*
* @return {this} This InputPlugin object.
*/
setPollOnMove: function() {
return this.setPollRate(-1);
},
/**
* Sets the poll rate value. This is the amount of time that should have elapsed before a pointer
* will be polled again. See the `setPollAlways` and `setPollOnMove` methods.
*
* @method Phaser.Input.InputPlugin#setPollRate
* @since 3.0.0
*
* @param {number} value - The amount of time, in ms, that should elapsed before re-polling the pointers.
*
* @return {this} This InputPlugin object.
*/
setPollRate: function(value) {
this.pollRate = value;
this._pollTimer = 0;
return this;
},
/**
* When set to `true` the global Input Manager will emulate DOM behavior by only emitting events from
* the top-most Scene in the Scene List. By default, if a Scene receives an input event it will then stop the event
* from flowing down to any Scenes below it in the Scene list. To disable this behavior call this method with `false`.
*
* @method Phaser.Input.InputPlugin#setGlobalTopOnly
* @since 3.0.0
*
* @param {boolean} value - Set to `true` to stop processing input events on the Scene that receives it, or `false` to let the event continue down the Scene list.
*
* @return {this} This InputPlugin object.
*/
setGlobalTopOnly: function(value) {
this.manager.globalTopOnly = value;
return this;
},
/**
* When set to `true` this Input Plugin will emulate DOM behavior by only emitting events from
* the top-most Game Objects in the Display List.
*
* If set to `false` it will emit events from all Game Objects below a Pointer, not just the top one.
*
* @method Phaser.Input.InputPlugin#setTopOnly
* @since 3.0.0
*
* @param {boolean} value - `true` to only include the top-most Game Object, or `false` to include all Game Objects in a hit test.
*
* @return {this} This InputPlugin object.
*/
setTopOnly: function(value) {
this.topOnly = value;
return this;
},
/**
* Given an array of Game Objects and a Pointer, sort the array and return it,
* so that the objects are in render order with the lowest at the bottom.
*
* @method Phaser.Input.InputPlugin#sortGameObjects
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject[]} gameObjects - An array of Game Objects to be sorted.
* @param {Phaser.Input.Pointer} pointer - The Pointer to check against the Game Objects.
*
* @return {Phaser.GameObjects.GameObject[]} The sorted array of Game Objects.
*/
sortGameObjects: function(gameObjects, pointer) {
if (gameObjects.length < 2 || !pointer.camera) {
return gameObjects;
}
var list = pointer.camera.renderList;
return gameObjects.sort(function(childA, childB) {
var indexA = Math.max(list.indexOf(childA), 0);
var indexB = Math.max(list.indexOf(childB), 0);
return indexB - indexA;
});
},
/**
* Given an array of Drop Zone Game Objects, sort the array and return it,
* so that the objects are in depth index order with the lowest at the bottom.
*
* @method Phaser.Input.InputPlugin#sortDropZones
* @since 3.52.0
*
* @param {Phaser.GameObjects.GameObject[]} gameObjects - An array of Game Objects to be sorted.
*
* @return {Phaser.GameObjects.GameObject[]} The sorted array of Game Objects.
*/
sortDropZones: function(gameObjects) {
if (gameObjects.length < 2) {
return gameObjects;
}
this.scene.sys.depthSort();
return gameObjects.sort(this.sortDropZoneHandler.bind(this));
},
/**
* Return the child lowest down the display list (with the smallest index)
* Will iterate through all parent containers, if present.
*
* Prior to version 3.52.0 this method was called `sortHandlerGO`.
*
* @method Phaser.Input.InputPlugin#sortDropZoneHandler
* @private
* @since 3.52.0
*
* @param {Phaser.GameObjects.GameObject} childA - The first Game Object to compare.
* @param {Phaser.GameObjects.GameObject} childB - The second Game Object to compare.
*
* @return {number} Returns either a negative or positive integer, or zero if they match.
*/
sortDropZoneHandler: function(childA, childB) {
if (!childA.parentContainer && !childB.parentContainer) {
return this.displayList.getIndex(childB) - this.displayList.getIndex(childA);
} else if (childA.parentContainer === childB.parentContainer) {
return childB.parentContainer.getIndex(childB) - childA.parentContainer.getIndex(childA);
} else if (childA.parentContainer === childB) {
return -1;
} else if (childB.parentContainer === childA) {
return 1;
} else {
var listA = childA.getIndexList();
var listB = childB.getIndexList();
var len = Math.min(listA.length, listB.length);
for (var i = 0; i < len; i++) {
var indexA = listA[i];
var indexB = listB[i];
if (indexA === indexB) {
continue;
} else {
return indexB - indexA;
}
}
return listB.length - listA.length;
}
return 0;
},
/**
* This method should be called from within an input event handler, such as `pointerdown`.
*
* When called, it stops the Input Manager from allowing _this specific event_ to be processed by any other Scene
* not yet handled in the scene list.
*
* @method Phaser.Input.InputPlugin#stopPropagation
* @since 3.0.0
*
* @return {this} This InputPlugin object.
*/
stopPropagation: function() {
this.manager._tempSkip = true;
return this;
},
/**
* Adds new Pointer objects to the Input Manager.
*
* By default Phaser creates 2 pointer objects: `mousePointer` and `pointer1`.
*
* You can create more either by calling this method, or by setting the `input.activePointers` property
* in the Game Config, up to a maximum of 10 pointers.
*
* The first 10 pointers are available via the `InputPlugin.pointerX` properties, once they have been added
* via this method.
*
* @method Phaser.Input.InputPlugin#addPointer
* @since 3.10.0
*
* @param {number} [quantity=1] The number of new Pointers to create. A maximum of 10 is allowed in total.
*
* @return {Phaser.Input.Pointer[]} An array containing all of the new Pointer objects that were created.
*/
addPointer: function(quantity) {
return this.manager.addPointer(quantity);
},
/**
* Tells the Input system to set a custom cursor.
*
* This cursor will be the default cursor used when interacting with the game canvas.
*
* If an Interactive Object also sets a custom cursor, this is the cursor that is reset after its use.
*
* Any valid CSS cursor value is allowed, including paths to image files, i.e.:
*
* ```javascript
* this.input.setDefaultCursor('url(assets/cursors/sword.cur), pointer');
* ```
*
* Please read about the differences between browsers when it comes to the file formats and sizes they support:
*
* https://developer.mozilla.org/en-US/docs/Web/CSS/cursor
* https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_User_Interface/Using_URL_values_for_the_cursor_property
*
* It's up to you to pick a suitable cursor format that works across the range of browsers you need to support.
*
* @method Phaser.Input.InputPlugin#setDefaultCursor
* @since 3.10.0
*
* @param {string} cursor - The CSS to be used when setting the default cursor.
*
* @return {this} This Input instance.
*/
setDefaultCursor: function(cursor) {
this.manager.setDefaultCursor(cursor);
return this;
},
/**
* The Scene that owns this plugin is transitioning in.
*
* @method Phaser.Input.InputPlugin#transitionIn
* @private
* @since 3.5.0
*/
transitionIn: function() {
this.enabled = this.settings.transitionAllowInput;
},
/**
* The Scene that owns this plugin has finished transitioning in.
*
* @method Phaser.Input.InputPlugin#transitionComplete
* @private
* @since 3.5.0
*/
transitionComplete: function() {
if (!this.settings.transitionAllowInput) {
this.enabled = true;
}
},
/**
* The Scene that owns this plugin is transitioning out.
*
* @method Phaser.Input.InputPlugin#transitionOut
* @private
* @since 3.5.0
*/
transitionOut: function() {
this.enabled = this.settings.transitionAllowInput;
},
/**
* The Scene that owns this plugin is shutting down.
* We need to kill and reset all internal properties as well as stop listening to Scene events.
*
* @method Phaser.Input.InputPlugin#shutdown
* @fires Phaser.Input.Events#SHUTDOWN
* @private
* @since 3.0.0
*/
shutdown: function() {
this.pluginEvents.emit(Events.SHUTDOWN);
this._temp.length = 0;
this._list.length = 0;
this._draggable.length = 0;
this._pendingRemoval.length = 0;
this._pendingInsertion.length = 0;
this._dragState.length = 0;
for (var i = 0; i < 10; i++) {
this._drag[i] = [];
this._over[i] = [];
}
this.removeAllListeners();
var manager = this.manager;
manager.canvas.style.cursor = manager.defaultCursor;
var eventEmitter = this.systems.events;
eventEmitter.off(SceneEvents.TRANSITION_START, this.transitionIn, this);
eventEmitter.off(SceneEvents.TRANSITION_OUT, this.transitionOut, this);
eventEmitter.off(SceneEvents.TRANSITION_COMPLETE, this.transitionComplete, this);
eventEmitter.off(SceneEvents.PRE_UPDATE, this.preUpdate, this);
manager.events.off(Events.GAME_OUT, this.onGameOut, this);
manager.events.off(Events.GAME_OVER, this.onGameOver, this);
eventEmitter.off(SceneEvents.SHUTDOWN, this.shutdown, this);
},
/**
* Loops through all of the Input Manager Pointer instances and calls `reset` on them.
*
* Use this function if you find that input has been stolen from Phaser via a 3rd
* party component, such as Vue, and you need to tell Phaser to reset the Pointer states.
*
* @method Phaser.Input.InputPlugin#resetPointers
* @since 3.60.0
*/
resetPointers: function() {
var pointers = this.manager.pointers;
for (var i = 0; i < pointers.length; i++) {
pointers[i].reset();
}
},
/**
* The Scene that owns this plugin is being destroyed.
* We need to shutdown and then kill off all external references.
*
* @method Phaser.Input.InputPlugin#destroy
* @fires Phaser.Input.Events#DESTROY
* @private
* @since 3.0.0
*/
destroy: function() {
this.shutdown();
this.pluginEvents.emit(Events.DESTROY);
this.pluginEvents.removeAllListeners();
this.scene.sys.events.off(SceneEvents.START, this.start, this);
this.scene = null;
this.cameras = null;
this.manager = null;
this.events = null;
this.mouse = null;
},
/**
* The x coordinates of the ActivePointer based on the first camera in the camera list.
* This is only safe to use if your game has just 1 non-transformed camera and doesn't use multi-touch.
*
* @name Phaser.Input.InputPlugin#x
* @type {number}
* @readonly
* @since 3.0.0
*/
x: {
get: function() {
return this.manager.activePointer.x;
}
},
/**
* The y coordinates of the ActivePointer based on the first camera in the camera list.
* This is only safe to use if your game has just 1 non-transformed camera and doesn't use multi-touch.
*
* @name Phaser.Input.InputPlugin#y
* @type {number}
* @readonly
* @since 3.0.0
*/
y: {
get: function() {
return this.manager.activePointer.y;
}
},
/**
* Are any mouse or touch pointers currently over the game canvas?
*
* @name Phaser.Input.InputPlugin#isOver
* @type {boolean}
* @readonly
* @since 3.16.0
*/
isOver: {
get: function() {
return this.manager.isOver;
}
},
/**
* The mouse has its own unique Pointer object, which you can reference directly if making a _desktop specific game_.
* If you are supporting both desktop and touch devices then do not use this property, instead use `activePointer`
* which will always map to the most recently interacted pointer.
*
* @name Phaser.Input.InputPlugin#mousePointer
* @type {Phaser.Input.Pointer}
* @readonly
* @since 3.10.0
*/
mousePointer: {
get: function() {
return this.manager.mousePointer;
}
},
/**
* The current active input Pointer.
*
* @name Phaser.Input.InputPlugin#activePointer
* @type {Phaser.Input.Pointer}
* @readonly
* @since 3.0.0
*/
activePointer: {
get: function() {
return this.manager.activePointer;
}
},
/**
* A touch-based Pointer object.
* This will be `undefined` by default unless you add a new Pointer using `addPointer`.
*
* @name Phaser.Input.InputPlugin#pointer1
* @type {Phaser.Input.Pointer}
* @readonly
* @since 3.10.0
*/
pointer1: {
get: function() {
return this.manager.pointers[1];
}
},
/**
* A touch-based Pointer object.
* This will be `undefined` by default unless you add a new Pointer using `addPointer`.
*
* @name Phaser.Input.InputPlugin#pointer2
* @type {Phaser.Input.Pointer}
* @readonly
* @since 3.10.0
*/
pointer2: {
get: function() {
return this.manager.pointers[2];
}
},
/**
* A touch-based Pointer object.
* This will be `undefined` by default unless you add a new Pointer using `addPointer`.
*
* @name Phaser.Input.InputPlugin#pointer3
* @type {Phaser.Input.Pointer}
* @readonly
* @since 3.10.0
*/
pointer3: {
get: function() {
return this.manager.pointers[3];
}
},
/**
* A touch-based Pointer object.
* This will be `undefined` by default unless you add a new Pointer using `addPointer`.
*
* @name Phaser.Input.InputPlugin#pointer4
* @type {Phaser.Input.Pointer}
* @readonly
* @since 3.10.0
*/
pointer4: {
get: function() {
return this.manager.pointers[4];
}
},
/**
* A touch-based Pointer object.
* This will be `undefined` by default unless you add a new Pointer using `addPointer`.
*
* @name Phaser.Input.InputPlugin#pointer5
* @type {Phaser.Input.Pointer}
* @readonly
* @since 3.10.0
*/
pointer5: {
get: function() {
return this.manager.pointers[5];
}
},
/**
* A touch-based Pointer object.
* This will be `undefined` by default unless you add a new Pointer using `addPointer`.
*
* @name Phaser.Input.InputPlugin#pointer6
* @type {Phaser.Input.Pointer}
* @readonly
* @since 3.10.0
*/
pointer6: {
get: function() {
return this.manager.pointers[6];
}
},
/**
* A touch-based Pointer object.
* This will be `undefined` by default unless you add a new Pointer using `addPointer`.
*
* @name Phaser.Input.InputPlugin#pointer7
* @type {Phaser.Input.Pointer}
* @readonly
* @since 3.10.0
*/
pointer7: {
get: function() {
return this.manager.pointers[7];
}
},
/**
* A touch-based Pointer object.
* This will be `undefined` by default unless you add a new Pointer using `addPointer`.
*
* @name Phaser.Input.InputPlugin#pointer8
* @type {Phaser.Input.Pointer}
* @readonly
* @since 3.10.0
*/
pointer8: {
get: function() {
return this.manager.pointers[8];
}
},
/**
* A touch-based Pointer object.
* This will be `undefined` by default unless you add a new Pointer using `addPointer`.
*
* @name Phaser.Input.InputPlugin#pointer9
* @type {Phaser.Input.Pointer}
* @readonly
* @since 3.10.0
*/
pointer9: {
get: function() {
return this.manager.pointers[9];
}
},
/**
* A touch-based Pointer object.
* This will be `undefined` by default unless you add a new Pointer using `addPointer`.
*
* @name Phaser.Input.InputPlugin#pointer10
* @type {Phaser.Input.Pointer}
* @readonly
* @since 3.10.0
*/
pointer10: {
get: function() {
return this.manager.pointers[10];
}
}
});
PluginCache.register("InputPlugin", InputPlugin, "input");
module2.exports = InputPlugin;
}
),
/***/
89639: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetValue = __webpack_require__2(35154);
var inputPlugins = {};
var InputPluginCache = {};
InputPluginCache.register = function(key, plugin, mapping, settingsKey, configKey) {
inputPlugins[key] = { plugin, mapping, settingsKey, configKey };
};
InputPluginCache.getPlugin = function(key) {
return inputPlugins[key];
};
InputPluginCache.install = function(target) {
var sys = target.scene.sys;
var settings = sys.settings.input;
var config = sys.game.config;
for (var key in inputPlugins) {
var source = inputPlugins[key].plugin;
var mapping = inputPlugins[key].mapping;
var settingsKey = inputPlugins[key].settingsKey;
var configKey = inputPlugins[key].configKey;
if (GetValue(settings, settingsKey, config[configKey])) {
target[mapping] = new source(target);
}
}
};
InputPluginCache.remove = function(key) {
if (inputPlugins.hasOwnProperty(key)) {
delete inputPlugins[key];
}
};
module2.exports = InputPluginCache;
}
),
/***/
42515: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Angle = __webpack_require__2(31040);
var Class = __webpack_require__2(83419);
var Distance = __webpack_require__2(20339);
var FuzzyEqual = __webpack_require__2(43855);
var SmoothStepInterpolation = __webpack_require__2(47235);
var Vector2 = __webpack_require__2(26099);
var OS = __webpack_require__2(25892);
var Pointer = new Class({
initialize: function Pointer2(manager, id) {
this.manager = manager;
this.id = id;
this.event;
this.downElement;
this.upElement;
this.camera = null;
this.button = 0;
this.buttons = 0;
this.position = new Vector2();
this.prevPosition = new Vector2();
this.midPoint = new Vector2(-1, -1);
this.velocity = new Vector2();
this.angle = 0;
this.distance = 0;
this.smoothFactor = 0;
this.motionFactor = 0.2;
this.worldX = 0;
this.worldY = 0;
this.moveTime = 0;
this.downX = 0;
this.downY = 0;
this.downTime = 0;
this.upX = 0;
this.upY = 0;
this.upTime = 0;
this.primaryDown = false;
this.isDown = false;
this.wasTouch = false;
this.wasCanceled = false;
this.movementX = 0;
this.movementY = 0;
this.identifier = 0;
this.pointerId = null;
this.active = id === 0 ? true : false;
this.locked = false;
this.deltaX = 0;
this.deltaY = 0;
this.deltaZ = 0;
},
/**
* Takes a Camera and updates this Pointer's `worldX` and `worldY` values so they are
* the result of a translation through the given Camera.
*
* Note that the values will be automatically replaced the moment the Pointer is
* updated by an input event, such as a mouse move, so should be used immediately.
*
* @method Phaser.Input.Pointer#updateWorldPoint
* @since 3.19.0
*
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera which is being tested against.
*
* @return {this} This Pointer object.
*/
updateWorldPoint: function(camera) {
var temp = camera.getWorldPoint(this.x, this.y);
this.worldX = temp.x;
this.worldY = temp.y;
return this;
},
/**
* Takes a Camera and returns a Vector2 containing the translated position of this Pointer
* within that Camera. This can be used to convert this Pointers position into camera space.
*
* @method Phaser.Input.Pointer#positionToCamera
* @since 3.0.0
*
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use for the translation.
* @param {(Phaser.Math.Vector2|object)} [output] - A Vector2-like object in which to store the translated position.
*
* @return {(Phaser.Math.Vector2|object)} A Vector2 containing the translated coordinates of this Pointer, based on the given camera.
*/
positionToCamera: function(camera, output) {
return camera.getWorldPoint(this.x, this.y, output);
},
/**
* Calculates the motion of this Pointer, including its velocity and angle of movement.
* This method is called automatically each frame by the Input Manager.
*
* @method Phaser.Input.Pointer#updateMotion
* @private
* @since 3.16.0
*/
updateMotion: function() {
var cx = this.position.x;
var cy = this.position.y;
var mx = this.midPoint.x;
var my = this.midPoint.y;
if (cx === mx && cy === my) {
return;
}
var vx = SmoothStepInterpolation(this.motionFactor, mx, cx);
var vy = SmoothStepInterpolation(this.motionFactor, my, cy);
if (FuzzyEqual(vx, cx, 0.1)) {
vx = cx;
}
if (FuzzyEqual(vy, cy, 0.1)) {
vy = cy;
}
this.midPoint.set(vx, vy);
var dx = cx - vx;
var dy = cy - vy;
this.velocity.set(dx, dy);
this.angle = Angle(vx, vy, cx, cy);
this.distance = Math.sqrt(dx * dx + dy * dy);
},
/**
* Internal method to handle a Mouse Up Event.
*
* @method Phaser.Input.Pointer#up
* @private
* @since 3.0.0
*
* @param {MouseEvent} event - The Mouse Event to process.
*/
up: function(event) {
if ("buttons" in event) {
this.buttons = event.buttons;
}
this.event = event;
this.button = event.button;
this.upElement = event.target;
this.manager.transformPointer(this, event.pageX, event.pageY, false);
if (event.button === 0) {
this.primaryDown = false;
this.upX = this.x;
this.upY = this.y;
}
if (this.buttons === 0) {
this.isDown = false;
this.upTime = event.timeStamp;
this.wasTouch = false;
}
},
/**
* Internal method to handle a Mouse Down Event.
*
* @method Phaser.Input.Pointer#down
* @private
* @since 3.0.0
*
* @param {MouseEvent} event - The Mouse Event to process.
*/
down: function(event) {
if ("buttons" in event) {
this.buttons = event.buttons;
}
this.event = event;
this.button = event.button;
this.downElement = event.target;
this.manager.transformPointer(this, event.pageX, event.pageY, false);
if (event.button === 0) {
this.primaryDown = true;
this.downX = this.x;
this.downY = this.y;
}
if (OS.macOS && event.ctrlKey) {
this.buttons = 2;
this.primaryDown = false;
}
if (!this.isDown) {
this.isDown = true;
this.downTime = event.timeStamp;
}
this.wasTouch = false;
},
/**
* Internal method to handle a Mouse Move Event.
*
* @method Phaser.Input.Pointer#move
* @private
* @since 3.0.0
*
* @param {MouseEvent} event - The Mouse Event to process.
*/
move: function(event) {
if ("buttons" in event) {
this.buttons = event.buttons;
}
this.event = event;
this.manager.transformPointer(this, event.pageX, event.pageY, true);
if (this.locked) {
this.movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0;
this.movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0;
}
this.moveTime = event.timeStamp;
this.wasTouch = false;
},
/**
* Internal method to handle a Mouse Wheel Event.
*
* @method Phaser.Input.Pointer#wheel
* @private
* @since 3.18.0
*
* @param {WheelEvent} event - The Wheel Event to process.
*/
wheel: function(event) {
if ("buttons" in event) {
this.buttons = event.buttons;
}
this.event = event;
this.manager.transformPointer(this, event.pageX, event.pageY, false);
this.deltaX = event.deltaX;
this.deltaY = event.deltaY;
this.deltaZ = event.deltaZ;
this.wasTouch = false;
},
/**
* Internal method to handle a Touch Start Event.
*
* @method Phaser.Input.Pointer#touchstart
* @private
* @since 3.0.0
*
* @param {Touch} touch - The Changed Touch from the Touch Event.
* @param {TouchEvent} event - The full Touch Event.
*/
touchstart: function(touch, event) {
if (touch["pointerId"]) {
this.pointerId = touch.pointerId;
}
this.identifier = touch.identifier;
this.target = touch.target;
this.active = true;
this.buttons = 1;
this.event = event;
this.downElement = touch.target;
this.manager.transformPointer(this, touch.pageX, touch.pageY, false);
this.primaryDown = true;
this.downX = this.x;
this.downY = this.y;
this.downTime = event.timeStamp;
this.isDown = true;
this.wasTouch = true;
this.wasCanceled = false;
this.updateMotion();
},
/**
* Internal method to handle a Touch Move Event.
*
* @method Phaser.Input.Pointer#touchmove
* @private
* @since 3.0.0
*
* @param {Touch} touch - The Changed Touch from the Touch Event.
* @param {TouchEvent} event - The full Touch Event.
*/
touchmove: function(touch, event) {
this.event = event;
this.manager.transformPointer(this, touch.pageX, touch.pageY, true);
this.moveTime = event.timeStamp;
this.wasTouch = true;
this.updateMotion();
},
/**
* Internal method to handle a Touch End Event.
*
* @method Phaser.Input.Pointer#touchend
* @private
* @since 3.0.0
*
* @param {Touch} touch - The Changed Touch from the Touch Event.
* @param {TouchEvent} event - The full Touch Event.
*/
touchend: function(touch, event) {
this.buttons = 0;
this.event = event;
this.upElement = touch.target;
this.manager.transformPointer(this, touch.pageX, touch.pageY, false);
this.primaryDown = false;
this.upX = this.x;
this.upY = this.y;
this.upTime = event.timeStamp;
this.isDown = false;
this.wasTouch = true;
this.wasCanceled = false;
this.active = false;
this.updateMotion();
},
/**
* Internal method to handle a Touch Cancel Event.
*
* @method Phaser.Input.Pointer#touchcancel
* @private
* @since 3.15.0
*
* @param {Touch} touch - The Changed Touch from the Touch Event.
* @param {TouchEvent} event - The full Touch Event.
*/
touchcancel: function(touch, event) {
this.buttons = 0;
this.event = event;
this.upElement = touch.target;
this.manager.transformPointer(this, touch.pageX, touch.pageY, false);
this.primaryDown = false;
this.upX = this.x;
this.upY = this.y;
this.upTime = event.timeStamp;
this.isDown = false;
this.wasTouch = true;
this.wasCanceled = true;
this.active = false;
},
/**
* Checks to see if any buttons are being held down on this Pointer.
*
* @method Phaser.Input.Pointer#noButtonDown
* @since 3.0.0
*
* @return {boolean} `true` if no buttons are being held down.
*/
noButtonDown: function() {
return this.buttons === 0;
},
/**
* Checks to see if the left button is being held down on this Pointer.
*
* @method Phaser.Input.Pointer#leftButtonDown
* @since 3.0.0
*
* @return {boolean} `true` if the left button is being held down.
*/
leftButtonDown: function() {
return this.buttons & 1 ? true : false;
},
/**
* Checks to see if the right button is being held down on this Pointer.
*
* @method Phaser.Input.Pointer#rightButtonDown
* @since 3.0.0
*
* @return {boolean} `true` if the right button is being held down.
*/
rightButtonDown: function() {
return this.buttons & 2 ? true : false;
},
/**
* Checks to see if the middle button is being held down on this Pointer.
*
* @method Phaser.Input.Pointer#middleButtonDown
* @since 3.0.0
*
* @return {boolean} `true` if the middle button is being held down.
*/
middleButtonDown: function() {
return this.buttons & 4 ? true : false;
},
/**
* Checks to see if the back button is being held down on this Pointer.
*
* @method Phaser.Input.Pointer#backButtonDown
* @since 3.0.0
*
* @return {boolean} `true` if the back button is being held down.
*/
backButtonDown: function() {
return this.buttons & 8 ? true : false;
},
/**
* Checks to see if the forward button is being held down on this Pointer.
*
* @method Phaser.Input.Pointer#forwardButtonDown
* @since 3.0.0
*
* @return {boolean} `true` if the forward button is being held down.
*/
forwardButtonDown: function() {
return this.buttons & 16 ? true : false;
},
/**
* Checks to see if the release of the left button was the most recent activity on this Pointer.
*
* @method Phaser.Input.Pointer#leftButtonReleased
* @since 3.18.0
*
* @return {boolean} `true` if the release of the left button was the most recent activity on this Pointer.
*/
leftButtonReleased: function() {
return this.buttons === 0 ? this.button === 0 && !this.isDown : this.button === 0;
},
/**
* Checks to see if the release of the right button was the most recent activity on this Pointer.
*
* @method Phaser.Input.Pointer#rightButtonReleased
* @since 3.18.0
*
* @return {boolean} `true` if the release of the right button was the most recent activity on this Pointer.
*/
rightButtonReleased: function() {
return this.buttons === 0 ? this.button === 2 && !this.isDown : this.button === 2;
},
/**
* Checks to see if the release of the middle button was the most recent activity on this Pointer.
*
* @method Phaser.Input.Pointer#middleButtonReleased
* @since 3.18.0
*
* @return {boolean} `true` if the release of the middle button was the most recent activity on this Pointer.
*/
middleButtonReleased: function() {
return this.buttons === 0 ? this.button === 1 && !this.isDown : this.button === 1;
},
/**
* Checks to see if the release of the back button was the most recent activity on this Pointer.
*
* @method Phaser.Input.Pointer#backButtonReleased
* @since 3.18.0
*
* @return {boolean} `true` if the release of the back button was the most recent activity on this Pointer.
*/
backButtonReleased: function() {
return this.buttons === 0 ? this.button === 3 && !this.isDown : this.button === 3;
},
/**
* Checks to see if the release of the forward button was the most recent activity on this Pointer.
*
* @method Phaser.Input.Pointer#forwardButtonReleased
* @since 3.18.0
*
* @return {boolean} `true` if the release of the forward button was the most recent activity on this Pointer.
*/
forwardButtonReleased: function() {
return this.buttons === 0 ? this.button === 4 && !this.isDown : this.button === 4;
},
/**
* If the Pointer has a button pressed down at the time this method is called, it will return the
* distance between the Pointer's `downX` and `downY` values and the current position.
*
* If no button is held down, it will return the last recorded distance, based on where
* the Pointer was when the button was released.
*
* If you wish to get the distance being travelled currently, based on the velocity of the Pointer,
* then see the `Pointer.distance` property.
*
* @method Phaser.Input.Pointer#getDistance
* @since 3.13.0
*
* @return {number} The distance the Pointer moved.
*/
getDistance: function() {
if (this.isDown) {
return Distance(this.downX, this.downY, this.x, this.y);
} else {
return Distance(this.downX, this.downY, this.upX, this.upY);
}
},
/**
* If the Pointer has a button pressed down at the time this method is called, it will return the
* horizontal distance between the Pointer's `downX` and `downY` values and the current position.
*
* If no button is held down, it will return the last recorded horizontal distance, based on where
* the Pointer was when the button was released.
*
* @method Phaser.Input.Pointer#getDistanceX
* @since 3.16.0
*
* @return {number} The horizontal distance the Pointer moved.
*/
getDistanceX: function() {
if (this.isDown) {
return Math.abs(this.downX - this.x);
} else {
return Math.abs(this.downX - this.upX);
}
},
/**
* If the Pointer has a button pressed down at the time this method is called, it will return the
* vertical distance between the Pointer's `downX` and `downY` values and the current position.
*
* If no button is held down, it will return the last recorded vertical distance, based on where
* the Pointer was when the button was released.
*
* @method Phaser.Input.Pointer#getDistanceY
* @since 3.16.0
*
* @return {number} The vertical distance the Pointer moved.
*/
getDistanceY: function() {
if (this.isDown) {
return Math.abs(this.downY - this.y);
} else {
return Math.abs(this.downY - this.upY);
}
},
/**
* If the Pointer has a button pressed down at the time this method is called, it will return the
* duration since the button was pressed down.
*
* If no button is held down, it will return the last recorded duration, based on the time
* the last button on the Pointer was released.
*
* @method Phaser.Input.Pointer#getDuration
* @since 3.16.0
*
* @return {number} The duration the Pointer was held down for in milliseconds.
*/
getDuration: function() {
if (this.isDown) {
return this.manager.time - this.downTime;
} else {
return this.upTime - this.downTime;
}
},
/**
* If the Pointer has a button pressed down at the time this method is called, it will return the
* angle between the Pointer's `downX` and `downY` values and the current position.
*
* If no button is held down, it will return the last recorded angle, based on where
* the Pointer was when the button was released.
*
* The angle is based on the old position facing to the current position.
*
* If you wish to get the current angle, based on the velocity of the Pointer, then
* see the `Pointer.angle` property.
*
* @method Phaser.Input.Pointer#getAngle
* @since 3.16.0
*
* @return {number} The angle between the Pointer's coordinates in radians.
*/
getAngle: function() {
if (this.isDown) {
return Angle(this.downX, this.downY, this.x, this.y);
} else {
return Angle(this.downX, this.downY, this.upX, this.upY);
}
},
/**
* Takes the previous and current Pointer positions and then generates an array of interpolated values between
* the two. The array will be populated up to the size of the `steps` argument.
*
* ```javaScript
* var points = pointer.getInterpolatedPosition(4);
*
* // points[0] = { x: 0, y: 0 }
* // points[1] = { x: 2, y: 1 }
* // points[2] = { x: 3, y: 2 }
* // points[3] = { x: 6, y: 3 }
* ```
*
* Use this if you need to get smoothed values between the previous and current pointer positions. DOM pointer
* events can often fire faster than the main browser loop, and this will help you avoid janky movement
* especially if you have an object following a Pointer.
*
* Note that if you provide an output array it will only be populated up to the number of steps provided.
* It will not clear any previous data that may have existed beyond the range of the steps count.
*
* Internally it uses the Smooth Step interpolation calculation.
*
* @method Phaser.Input.Pointer#getInterpolatedPosition
* @since 3.11.0
*
* @param {number} [steps=10] - The number of interpolation steps to use.
* @param {array} [out] - An array to store the results in. If not provided a new one will be created.
*
* @return {array} An array of interpolated values.
*/
getInterpolatedPosition: function(steps, out) {
if (steps === void 0) {
steps = 10;
}
if (out === void 0) {
out = [];
}
var prevX = this.prevPosition.x;
var prevY = this.prevPosition.y;
var curX = this.position.x;
var curY = this.position.y;
for (var i = 0; i < steps; i++) {
var t = 1 / steps * i;
out[i] = { x: SmoothStepInterpolation(t, prevX, curX), y: SmoothStepInterpolation(t, prevY, curY) };
}
return out;
},
/**
* Fully reset this Pointer back to its unitialized state.
*
* @method Phaser.Input.Pointer#reset
* @since 3.60.0
*/
reset: function() {
this.event = null;
this.downElement = null;
this.upElement = null;
this.button = 0;
this.buttons = 0;
this.position.set(0, 0);
this.prevPosition.set(0, 0);
this.midPoint.set(-1, -1);
this.velocity.set(0, 0);
this.angle = 0;
this.distance = 0;
this.worldX = 0;
this.worldY = 0;
this.downX = 0;
this.downY = 0;
this.upX = 0;
this.upY = 0;
this.moveTime = 0;
this.upTime = 0;
this.downTime = 0;
this.primaryDown = false;
this.isDown = false;
this.wasTouch = false;
this.wasCanceled = false;
this.movementX = 0;
this.movementY = 0;
this.identifier = 0;
this.pointerId = null;
this.deltaX = 0;
this.deltaY = 0;
this.deltaZ = 0;
this.active = this.id === 0 ? true : false;
},
/**
* Destroys this Pointer instance and resets its external references.
*
* @method Phaser.Input.Pointer#destroy
* @since 3.0.0
*/
destroy: function() {
this.camera = null;
this.manager = null;
this.position = null;
},
/**
* The x position of this Pointer.
* The value is in screen space.
* See `worldX` to get a camera converted position.
*
* @name Phaser.Input.Pointer#x
* @type {number}
* @since 3.0.0
*/
x: {
get: function() {
return this.position.x;
},
set: function(value) {
this.position.x = value;
}
},
/**
* The y position of this Pointer.
* The value is in screen space.
* See `worldY` to get a camera converted position.
*
* @name Phaser.Input.Pointer#y
* @type {number}
* @since 3.0.0
*/
y: {
get: function() {
return this.position.y;
},
set: function(value) {
this.position.y = value;
}
},
/**
* Time when this Pointer was most recently updated by a DOM Event.
* This comes directly from the `event.timeStamp` property.
* If no event has yet taken place, it will return zero.
*
* @name Phaser.Input.Pointer#time
* @type {number}
* @readonly
* @since 3.16.0
*/
time: {
get: function() {
return this.event ? this.event.timeStamp : 0;
}
}
});
module2.exports = Pointer;
}
),
/***/
93301: (
/***/
(module2) => {
var INPUT_CONST = {
/**
* The mouse pointer is being held down.
*
* @name Phaser.Input.MOUSE_DOWN
* @type {number}
* @since 3.10.0
*/
MOUSE_DOWN: 0,
/**
* The mouse pointer is being moved.
*
* @name Phaser.Input.MOUSE_MOVE
* @type {number}
* @since 3.10.0
*/
MOUSE_MOVE: 1,
/**
* The mouse pointer is released.
*
* @name Phaser.Input.MOUSE_UP
* @type {number}
* @since 3.10.0
*/
MOUSE_UP: 2,
/**
* A touch pointer has been started.
*
* @name Phaser.Input.TOUCH_START
* @type {number}
* @since 3.10.0
*/
TOUCH_START: 3,
/**
* A touch pointer has been started.
*
* @name Phaser.Input.TOUCH_MOVE
* @type {number}
* @since 3.10.0
*/
TOUCH_MOVE: 4,
/**
* A touch pointer has been started.
*
* @name Phaser.Input.TOUCH_END
* @type {number}
* @since 3.10.0
*/
TOUCH_END: 5,
/**
* The pointer lock has changed.
*
* @name Phaser.Input.POINTER_LOCK_CHANGE
* @type {number}
* @since 3.10.0
*/
POINTER_LOCK_CHANGE: 6,
/**
* A touch pointer has been been cancelled by the browser.
*
* @name Phaser.Input.TOUCH_CANCEL
* @type {number}
* @since 3.15.0
*/
TOUCH_CANCEL: 7,
/**
* The mouse wheel changes.
*
* @name Phaser.Input.MOUSE_WHEEL
* @type {number}
* @since 3.18.0
*/
MOUSE_WHEEL: 8
};
module2.exports = INPUT_CONST;
}
),
/***/
7179: (
/***/
(module2) => {
module2.exports = "boot";
}
),
/***/
85375: (
/***/
(module2) => {
module2.exports = "destroy";
}
),
/***/
39843: (
/***/
(module2) => {
module2.exports = "dragend";
}
),
/***/
23388: (
/***/
(module2) => {
module2.exports = "dragenter";
}
),
/***/
16133: (
/***/
(module2) => {
module2.exports = "drag";
}
),
/***/
27829: (
/***/
(module2) => {
module2.exports = "dragleave";
}
),
/***/
53904: (
/***/
(module2) => {
module2.exports = "dragover";
}
),
/***/
56058: (
/***/
(module2) => {
module2.exports = "dragstart";
}
),
/***/
2642: (
/***/
(module2) => {
module2.exports = "drop";
}
),
/***/
88171: (
/***/
(module2) => {
module2.exports = "gameobjectdown";
}
),
/***/
36147: (
/***/
(module2) => {
module2.exports = "dragend";
}
),
/***/
71692: (
/***/
(module2) => {
module2.exports = "dragenter";
}
),
/***/
96149: (
/***/
(module2) => {
module2.exports = "drag";
}
),
/***/
81285: (
/***/
(module2) => {
module2.exports = "dragleave";
}
),
/***/
74048: (
/***/
(module2) => {
module2.exports = "dragover";
}
),
/***/
21322: (
/***/
(module2) => {
module2.exports = "dragstart";
}
),
/***/
49378: (
/***/
(module2) => {
module2.exports = "drop";
}
),
/***/
86754: (
/***/
(module2) => {
module2.exports = "gameobjectmove";
}
),
/***/
86433: (
/***/
(module2) => {
module2.exports = "gameobjectout";
}
),
/***/
60709: (
/***/
(module2) => {
module2.exports = "gameobjectover";
}
),
/***/
24081: (
/***/
(module2) => {
module2.exports = "pointerdown";
}
),
/***/
11172: (
/***/
(module2) => {
module2.exports = "pointermove";
}
),
/***/
18907: (
/***/
(module2) => {
module2.exports = "pointerout";
}
),
/***/
95579: (
/***/
(module2) => {
module2.exports = "pointerover";
}
),
/***/
35368: (
/***/
(module2) => {
module2.exports = "pointerup";
}
),
/***/
26972: (
/***/
(module2) => {
module2.exports = "wheel";
}
),
/***/
47078: (
/***/
(module2) => {
module2.exports = "gameobjectup";
}
),
/***/
73802: (
/***/
(module2) => {
module2.exports = "gameobjectwheel";
}
),
/***/
56718: (
/***/
(module2) => {
module2.exports = "gameout";
}
),
/***/
25936: (
/***/
(module2) => {
module2.exports = "gameover";
}
),
/***/
27503: (
/***/
(module2) => {
module2.exports = "boot";
}
),
/***/
50852: (
/***/
(module2) => {
module2.exports = "process";
}
),
/***/
96438: (
/***/
(module2) => {
module2.exports = "update";
}
),
/***/
59152: (
/***/
(module2) => {
module2.exports = "pointerlockchange";
}
),
/***/
47777: (
/***/
(module2) => {
module2.exports = "pointerdown";
}
),
/***/
27957: (
/***/
(module2) => {
module2.exports = "pointerdownoutside";
}
),
/***/
19444: (
/***/
(module2) => {
module2.exports = "pointermove";
}
),
/***/
54251: (
/***/
(module2) => {
module2.exports = "pointerout";
}
),
/***/
18667: (
/***/
(module2) => {
module2.exports = "pointerover";
}
),
/***/
27192: (
/***/
(module2) => {
module2.exports = "pointerup";
}
),
/***/
24652: (
/***/
(module2) => {
module2.exports = "pointerupoutside";
}
),
/***/
45132: (
/***/
(module2) => {
module2.exports = "wheel";
}
),
/***/
44512: (
/***/
(module2) => {
module2.exports = "preupdate";
}
),
/***/
15757: (
/***/
(module2) => {
module2.exports = "shutdown";
}
),
/***/
41637: (
/***/
(module2) => {
module2.exports = "start";
}
),
/***/
93802: (
/***/
(module2) => {
module2.exports = "update";
}
),
/***/
8214: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
BOOT: __webpack_require__2(7179),
DESTROY: __webpack_require__2(85375),
DRAG_END: __webpack_require__2(39843),
DRAG_ENTER: __webpack_require__2(23388),
DRAG: __webpack_require__2(16133),
DRAG_LEAVE: __webpack_require__2(27829),
DRAG_OVER: __webpack_require__2(53904),
DRAG_START: __webpack_require__2(56058),
DROP: __webpack_require__2(2642),
GAME_OUT: __webpack_require__2(56718),
GAME_OVER: __webpack_require__2(25936),
GAMEOBJECT_DOWN: __webpack_require__2(88171),
GAMEOBJECT_DRAG_END: __webpack_require__2(36147),
GAMEOBJECT_DRAG_ENTER: __webpack_require__2(71692),
GAMEOBJECT_DRAG: __webpack_require__2(96149),
GAMEOBJECT_DRAG_LEAVE: __webpack_require__2(81285),
GAMEOBJECT_DRAG_OVER: __webpack_require__2(74048),
GAMEOBJECT_DRAG_START: __webpack_require__2(21322),
GAMEOBJECT_DROP: __webpack_require__2(49378),
GAMEOBJECT_MOVE: __webpack_require__2(86754),
GAMEOBJECT_OUT: __webpack_require__2(86433),
GAMEOBJECT_OVER: __webpack_require__2(60709),
GAMEOBJECT_POINTER_DOWN: __webpack_require__2(24081),
GAMEOBJECT_POINTER_MOVE: __webpack_require__2(11172),
GAMEOBJECT_POINTER_OUT: __webpack_require__2(18907),
GAMEOBJECT_POINTER_OVER: __webpack_require__2(95579),
GAMEOBJECT_POINTER_UP: __webpack_require__2(35368),
GAMEOBJECT_POINTER_WHEEL: __webpack_require__2(26972),
GAMEOBJECT_UP: __webpack_require__2(47078),
GAMEOBJECT_WHEEL: __webpack_require__2(73802),
MANAGER_BOOT: __webpack_require__2(27503),
MANAGER_PROCESS: __webpack_require__2(50852),
MANAGER_UPDATE: __webpack_require__2(96438),
POINTER_DOWN: __webpack_require__2(47777),
POINTER_DOWN_OUTSIDE: __webpack_require__2(27957),
POINTER_MOVE: __webpack_require__2(19444),
POINTER_OUT: __webpack_require__2(54251),
POINTER_OVER: __webpack_require__2(18667),
POINTER_UP: __webpack_require__2(27192),
POINTER_UP_OUTSIDE: __webpack_require__2(24652),
POINTER_WHEEL: __webpack_require__2(45132),
POINTERLOCK_CHANGE: __webpack_require__2(59152),
PRE_UPDATE: __webpack_require__2(44512),
SHUTDOWN: __webpack_require__2(15757),
START: __webpack_require__2(41637),
UPDATE: __webpack_require__2(93802)
};
}
),
/***/
97421: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Axis = new Class({
initialize: function Axis2(pad, index) {
this.pad = pad;
this.events = pad.events;
this.index = index;
this.value = 0;
this.threshold = 0.1;
},
/**
* Internal update handler for this Axis.
* Called automatically by the Gamepad as part of its update.
*
* @method Phaser.Input.Gamepad.Axis#update
* @private
* @since 3.0.0
*
* @param {number} value - The value of the axis movement.
*/
update: function(value) {
this.value = value;
},
/**
* Applies the `threshold` value to the axis and returns it.
*
* @method Phaser.Input.Gamepad.Axis#getValue
* @since 3.0.0
*
* @return {number} The axis value, adjusted for the movement threshold.
*/
getValue: function() {
return Math.abs(this.value) < this.threshold ? 0 : this.value;
},
/**
* Destroys this Axis instance and releases external references it holds.
*
* @method Phaser.Input.Gamepad.Axis#destroy
* @since 3.10.0
*/
destroy: function() {
this.pad = null;
this.events = null;
}
});
module2.exports = Axis;
}
),
/***/
28884: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Events = __webpack_require__2(92734);
var Button = new Class({
initialize: function Button2(pad, index) {
this.pad = pad;
this.events = pad.manager;
this.index = index;
this.value = 0;
this.threshold = 1;
this.pressed = false;
},
/**
* Internal update handler for this Button.
* Called automatically by the Gamepad as part of its update.
*
* @method Phaser.Input.Gamepad.Button#update
* @fires Phaser.Input.Gamepad.Events#BUTTON_DOWN
* @fires Phaser.Input.Gamepad.Events#BUTTON_UP
* @fires Phaser.Input.Gamepad.Events#GAMEPAD_BUTTON_DOWN
* @fires Phaser.Input.Gamepad.Events#GAMEPAD_BUTTON_UP
* @private
* @since 3.0.0
*
* @param {number} value - The value of the button. Between 0 and 1.
*/
update: function(value) {
this.value = value;
var pad = this.pad;
var index = this.index;
if (value >= this.threshold) {
if (!this.pressed) {
this.pressed = true;
this.events.emit(Events.BUTTON_DOWN, pad, this, value);
this.pad.emit(Events.GAMEPAD_BUTTON_DOWN, index, value, this);
}
} else if (this.pressed) {
this.pressed = false;
this.events.emit(Events.BUTTON_UP, pad, this, value);
this.pad.emit(Events.GAMEPAD_BUTTON_UP, index, value, this);
}
},
/**
* Destroys this Button instance and releases external references it holds.
*
* @method Phaser.Input.Gamepad.Button#destroy
* @since 3.10.0
*/
destroy: function() {
this.pad = null;
this.events = null;
}
});
module2.exports = Button;
}
),
/***/
99125: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Axis = __webpack_require__2(97421);
var Button = __webpack_require__2(28884);
var Class = __webpack_require__2(83419);
var EventEmitter = __webpack_require__2(50792);
var Vector2 = __webpack_require__2(26099);
var Gamepad = new Class({
Extends: EventEmitter,
initialize: function Gamepad2(manager, pad) {
EventEmitter.call(this);
this.manager = manager;
this.pad = pad;
this.id = pad.id;
this.index = pad.index;
var buttons = [];
for (var i = 0; i < pad.buttons.length; i++) {
buttons.push(new Button(this, i));
}
this.buttons = buttons;
var axes = [];
for (i = 0; i < pad.axes.length; i++) {
axes.push(new Axis(this, i));
}
this.axes = axes;
this.vibration = pad.vibrationActuator;
var _noButton = { value: 0, pressed: false };
this._LCLeft = buttons[14] ? buttons[14] : _noButton;
this._LCRight = buttons[15] ? buttons[15] : _noButton;
this._LCTop = buttons[12] ? buttons[12] : _noButton;
this._LCBottom = buttons[13] ? buttons[13] : _noButton;
this._RCLeft = buttons[2] ? buttons[2] : _noButton;
this._RCRight = buttons[1] ? buttons[1] : _noButton;
this._RCTop = buttons[3] ? buttons[3] : _noButton;
this._RCBottom = buttons[0] ? buttons[0] : _noButton;
this._FBLeftTop = buttons[4] ? buttons[4] : _noButton;
this._FBLeftBottom = buttons[6] ? buttons[6] : _noButton;
this._FBRightTop = buttons[5] ? buttons[5] : _noButton;
this._FBRightBottom = buttons[7] ? buttons[7] : _noButton;
var _noAxis = { value: 0 };
this._HAxisLeft = axes[0] ? axes[0] : _noAxis;
this._VAxisLeft = axes[1] ? axes[1] : _noAxis;
this._HAxisRight = axes[2] ? axes[2] : _noAxis;
this._VAxisRight = axes[3] ? axes[3] : _noAxis;
this.leftStick = new Vector2();
this.rightStick = new Vector2();
this._created = performance.now();
},
/**
* Gets the total number of axis this Gamepad claims to support.
*
* @method Phaser.Input.Gamepad.Gamepad#getAxisTotal
* @since 3.10.0
*
* @return {number} The total number of axes this Gamepad claims to support.
*/
getAxisTotal: function() {
return this.axes.length;
},
/**
* Gets the value of an axis based on the given index.
* The index must be valid within the range of axes supported by this Gamepad.
* The return value will be a float between 0 and 1.
*
* @method Phaser.Input.Gamepad.Gamepad#getAxisValue
* @since 3.10.0
*
* @param {number} index - The index of the axes to get the value for.
*
* @return {number} The value of the axis, between 0 and 1.
*/
getAxisValue: function(index) {
return this.axes[index].getValue();
},
/**
* Sets the threshold value of all axis on this Gamepad.
* The value is a float between 0 and 1 and is the amount below which the axis is considered as not having been moved.
*
* @method Phaser.Input.Gamepad.Gamepad#setAxisThreshold
* @since 3.10.0
*
* @param {number} value - A value between 0 and 1.
*/
setAxisThreshold: function(value) {
for (var i = 0; i < this.axes.length; i++) {
this.axes[i].threshold = value;
}
},
/**
* Gets the total number of buttons this Gamepad claims to have.
*
* @method Phaser.Input.Gamepad.Gamepad#getButtonTotal
* @since 3.10.0
*
* @return {number} The total number of buttons this Gamepad claims to have.
*/
getButtonTotal: function() {
return this.buttons.length;
},
/**
* Gets the value of a button based on the given index.
* The index must be valid within the range of buttons supported by this Gamepad.
*
* The return value will be either 0 or 1 for an analogue button, or a float between 0 and 1
* for a pressure-sensitive digital button, such as the shoulder buttons on a Dual Shock.
*
* @method Phaser.Input.Gamepad.Gamepad#getButtonValue
* @since 3.10.0
*
* @param {number} index - The index of the button to get the value for.
*
* @return {number} The value of the button, between 0 and 1.
*/
getButtonValue: function(index) {
return this.buttons[index].value;
},
/**
* Returns if the button is pressed down or not.
* The index must be valid within the range of buttons supported by this Gamepad.
*
* @method Phaser.Input.Gamepad.Gamepad#isButtonDown
* @since 3.10.0
*
* @param {number} index - The index of the button to get the value for.
*
* @return {boolean} `true` if the button is considered as being pressed down, otherwise `false`.
*/
isButtonDown: function(index) {
return this.buttons[index].pressed;
},
/**
* Internal update handler for this Gamepad.
* Called automatically by the Gamepad Manager as part of its update.
*
* @method Phaser.Input.Gamepad.Gamepad#update
* @private
* @since 3.0.0
*/
update: function(pad) {
if (pad.timestamp < this._created) {
return;
}
var i;
var localButtons = this.buttons;
var gamepadButtons = pad.buttons;
var len = localButtons.length;
for (i = 0; i < len; i++) {
localButtons[i].update(gamepadButtons[i].value);
}
var localAxes = this.axes;
var gamepadAxes = pad.axes;
len = localAxes.length;
for (i = 0; i < len; i++) {
localAxes[i].update(gamepadAxes[i]);
}
if (len >= 2) {
this.leftStick.set(localAxes[0].getValue(), localAxes[1].getValue());
if (len >= 4) {
this.rightStick.set(localAxes[2].getValue(), localAxes[3].getValue());
}
}
},
/**
* Destroys this Gamepad instance, its buttons and axes, and releases external references it holds.
*
* @method Phaser.Input.Gamepad.Gamepad#destroy
* @since 3.10.0
*/
destroy: function() {
this.removeAllListeners();
this.manager = null;
this.pad = null;
var i;
for (i = 0; i < this.buttons.length; i++) {
this.buttons[i].destroy();
}
for (i = 0; i < this.axes.length; i++) {
this.axes[i].destroy();
}
this.buttons = [];
this.axes = [];
},
/**
* Is this Gamepad currently connected or not?
*
* @name Phaser.Input.Gamepad.Gamepad#connected
* @type {boolean}
* @default true
* @since 3.0.0
*/
connected: {
get: function() {
return this.pad.connected;
}
},
/**
* A timestamp containing the most recent time this Gamepad was updated.
*
* @name Phaser.Input.Gamepad.Gamepad#timestamp
* @type {number}
* @since 3.0.0
*/
timestamp: {
get: function() {
return this.pad.timestamp;
}
},
/**
* Is the Gamepad's Left button being pressed?
* If the Gamepad doesn't have this button it will always return false.
* This is the d-pad left button under standard Gamepad mapping.
*
* @name Phaser.Input.Gamepad.Gamepad#left
* @type {boolean}
* @since 3.10.0
*/
left: {
get: function() {
return this._LCLeft.pressed;
}
},
/**
* Is the Gamepad's Right button being pressed?
* If the Gamepad doesn't have this button it will always return false.
* This is the d-pad right button under standard Gamepad mapping.
*
* @name Phaser.Input.Gamepad.Gamepad#right
* @type {boolean}
* @since 3.10.0
*/
right: {
get: function() {
return this._LCRight.pressed;
}
},
/**
* Is the Gamepad's Up button being pressed?
* If the Gamepad doesn't have this button it will always return false.
* This is the d-pad up button under standard Gamepad mapping.
*
* @name Phaser.Input.Gamepad.Gamepad#up
* @type {boolean}
* @since 3.10.0
*/
up: {
get: function() {
return this._LCTop.pressed;
}
},
/**
* Is the Gamepad's Down button being pressed?
* If the Gamepad doesn't have this button it will always return false.
* This is the d-pad down button under standard Gamepad mapping.
*
* @name Phaser.Input.Gamepad.Gamepad#down
* @type {boolean}
* @since 3.10.0
*/
down: {
get: function() {
return this._LCBottom.pressed;
}
},
/**
* Is the Gamepad's bottom button in the right button cluster being pressed?
* If the Gamepad doesn't have this button it will always return false.
* On a Dual Shock controller it's the X button.
* On an XBox controller it's the A button.
*
* @name Phaser.Input.Gamepad.Gamepad#A
* @type {boolean}
* @since 3.10.0
*/
A: {
get: function() {
return this._RCBottom.pressed;
}
},
/**
* Is the Gamepad's top button in the right button cluster being pressed?
* If the Gamepad doesn't have this button it will always return false.
* On a Dual Shock controller it's the Triangle button.
* On an XBox controller it's the Y button.
*
* @name Phaser.Input.Gamepad.Gamepad#Y
* @type {boolean}
* @since 3.10.0
*/
Y: {
get: function() {
return this._RCTop.pressed;
}
},
/**
* Is the Gamepad's left button in the right button cluster being pressed?
* If the Gamepad doesn't have this button it will always return false.
* On a Dual Shock controller it's the Square button.
* On an XBox controller it's the X button.
*
* @name Phaser.Input.Gamepad.Gamepad#X
* @type {boolean}
* @since 3.10.0
*/
X: {
get: function() {
return this._RCLeft.pressed;
}
},
/**
* Is the Gamepad's right button in the right button cluster being pressed?
* If the Gamepad doesn't have this button it will always return false.
* On a Dual Shock controller it's the Circle button.
* On an XBox controller it's the B button.
*
* @name Phaser.Input.Gamepad.Gamepad#B
* @type {boolean}
* @since 3.10.0
*/
B: {
get: function() {
return this._RCRight.pressed;
}
},
/**
* Returns the value of the Gamepad's top left shoulder button.
* If the Gamepad doesn't have this button it will always return zero.
* The value is a float between 0 and 1, corresponding to how depressed the button is.
* On a Dual Shock controller it's the L1 button.
* On an XBox controller it's the LB button.
*
* @name Phaser.Input.Gamepad.Gamepad#L1
* @type {number}
* @since 3.10.0
*/
L1: {
get: function() {
return this._FBLeftTop.value;
}
},
/**
* Returns the value of the Gamepad's bottom left shoulder button.
* If the Gamepad doesn't have this button it will always return zero.
* The value is a float between 0 and 1, corresponding to how depressed the button is.
* On a Dual Shock controller it's the L2 button.
* On an XBox controller it's the LT button.
*
* @name Phaser.Input.Gamepad.Gamepad#L2
* @type {number}
* @since 3.10.0
*/
L2: {
get: function() {
return this._FBLeftBottom.value;
}
},
/**
* Returns the value of the Gamepad's top right shoulder button.
* If the Gamepad doesn't have this button it will always return zero.
* The value is a float between 0 and 1, corresponding to how depressed the button is.
* On a Dual Shock controller it's the R1 button.
* On an XBox controller it's the RB button.
*
* @name Phaser.Input.Gamepad.Gamepad#R1
* @type {number}
* @since 3.10.0
*/
R1: {
get: function() {
return this._FBRightTop.value;
}
},
/**
* Returns the value of the Gamepad's bottom right shoulder button.
* If the Gamepad doesn't have this button it will always return zero.
* The value is a float between 0 and 1, corresponding to how depressed the button is.
* On a Dual Shock controller it's the R2 button.
* On an XBox controller it's the RT button.
*
* @name Phaser.Input.Gamepad.Gamepad#R2
* @type {number}
* @since 3.10.0
*/
R2: {
get: function() {
return this._FBRightBottom.value;
}
}
});
module2.exports = Gamepad;
}
),
/***/
56654: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var EventEmitter = __webpack_require__2(50792);
var Events = __webpack_require__2(92734);
var Gamepad = __webpack_require__2(99125);
var GetValue = __webpack_require__2(35154);
var InputPluginCache = __webpack_require__2(89639);
var InputEvents = __webpack_require__2(8214);
var GamepadPlugin = new Class({
Extends: EventEmitter,
initialize: function GamepadPlugin2(sceneInputPlugin) {
EventEmitter.call(this);
this.scene = sceneInputPlugin.scene;
this.settings = this.scene.sys.settings;
this.sceneInputPlugin = sceneInputPlugin;
this.enabled = true;
this.target;
this.gamepads = [];
this.queue = [];
this.onGamepadHandler;
this._pad1;
this._pad2;
this._pad3;
this._pad4;
sceneInputPlugin.pluginEvents.once(InputEvents.BOOT, this.boot, this);
sceneInputPlugin.pluginEvents.on(InputEvents.START, this.start, this);
},
/**
* This method is called automatically, only once, when the Scene is first created.
* Do not invoke it directly.
*
* @method Phaser.Input.Gamepad.GamepadPlugin#boot
* @private
* @since 3.10.0
*/
boot: function() {
var game = this.scene.sys.game;
var settings = this.settings.input;
var config = game.config;
this.enabled = GetValue(settings, "gamepad", config.inputGamepad) && game.device.input.gamepads;
this.target = GetValue(settings, "gamepad.target", config.inputGamepadEventTarget);
this.sceneInputPlugin.pluginEvents.once(InputEvents.DESTROY, this.destroy, this);
},
/**
* This method is called automatically by the Scene when it is starting up.
* It is responsible for creating local systems, properties and listening for Scene events.
* Do not invoke it directly.
*
* @method Phaser.Input.Gamepad.GamepadPlugin#start
* @private
* @since 3.10.0
*/
start: function() {
if (this.enabled) {
this.startListeners();
this.refreshPads();
}
this.sceneInputPlugin.pluginEvents.once(InputEvents.SHUTDOWN, this.shutdown, this);
},
/**
* Checks to see if both this plugin and the Scene to which it belongs is active.
*
* @method Phaser.Input.Gamepad.GamepadPlugin#isActive
* @since 3.10.0
*
* @return {boolean} `true` if the plugin and the Scene it belongs to is active.
*/
isActive: function() {
return this.enabled && this.scene.sys.isActive();
},
/**
* Starts the Gamepad Event listeners running.
* This is called automatically and does not need to be manually invoked.
*
* @method Phaser.Input.Gamepad.GamepadPlugin#startListeners
* @private
* @since 3.10.0
*/
startListeners: function() {
var _this = this;
var target = this.target;
var handler = function(event) {
if (event.defaultPrevented || !_this.isActive()) {
return;
}
_this.refreshPads();
_this.queue.push(event);
};
this.onGamepadHandler = handler;
target.addEventListener("gamepadconnected", handler, false);
target.addEventListener("gamepaddisconnected", handler, false);
this.sceneInputPlugin.pluginEvents.on(InputEvents.UPDATE, this.update, this);
},
/**
* Stops the Gamepad Event listeners.
* This is called automatically and does not need to be manually invoked.
*
* @method Phaser.Input.Gamepad.GamepadPlugin#stopListeners
* @private
* @since 3.10.0
*/
stopListeners: function() {
this.target.removeEventListener("gamepadconnected", this.onGamepadHandler);
this.target.removeEventListener("gamepaddisconnected", this.onGamepadHandler);
this.sceneInputPlugin.pluginEvents.off(InputEvents.UPDATE, this.update);
for (var i = 0; i < this.gamepads.length; i++) {
this.gamepads[i].removeAllListeners();
}
},
/**
* Disconnects all current Gamepads.
*
* @method Phaser.Input.Gamepad.GamepadPlugin#disconnectAll
* @since 3.10.0
*/
disconnectAll: function() {
for (var i = 0; i < this.gamepads.length; i++) {
this.gamepads[i].pad.connected = false;
}
},
/**
* Refreshes the list of connected Gamepads.
*
* This is called automatically when a gamepad is connected or disconnected,
* and during the update loop.
*
* @method Phaser.Input.Gamepad.GamepadPlugin#refreshPads
* @private
* @since 3.10.0
*/
refreshPads: function() {
var connectedPads = navigator.getGamepads();
if (!connectedPads) {
this.disconnectAll();
} else {
var currentPads = this.gamepads;
for (var i = 0; i < connectedPads.length; i++) {
var livePad = connectedPads[i];
if (!livePad) {
continue;
}
var id = livePad.id;
var index = livePad.index;
var currentPad = currentPads[index];
if (!currentPad) {
var newPad = new Gamepad(this, livePad);
currentPads[index] = newPad;
if (!this._pad1) {
this._pad1 = newPad;
} else if (!this._pad2) {
this._pad2 = newPad;
} else if (!this._pad3) {
this._pad3 = newPad;
} else if (!this._pad4) {
this._pad4 = newPad;
}
} else if (currentPad.id !== id) {
currentPad.destroy();
currentPads[index] = new Gamepad(this, livePad);
} else {
currentPad.update(livePad);
}
}
}
},
/**
* Returns an array of all currently connected Gamepads.
*
* @method Phaser.Input.Gamepad.GamepadPlugin#getAll
* @since 3.10.0
*
* @return {Phaser.Input.Gamepad.Gamepad[]} An array of all currently connected Gamepads.
*/
getAll: function() {
var out = [];
var pads = this.gamepads;
for (var i = 0; i < pads.length; i++) {
if (pads[i]) {
out.push(pads[i]);
}
}
return out;
},
/**
* Looks-up a single Gamepad based on the given index value.
*
* @method Phaser.Input.Gamepad.GamepadPlugin#getPad
* @since 3.10.0
*
* @param {number} index - The index of the Gamepad to get.
*
* @return {Phaser.Input.Gamepad.Gamepad} The Gamepad matching the given index, or undefined if none were found.
*/
getPad: function(index) {
var pads = this.gamepads;
for (var i = 0; i < pads.length; i++) {
if (pads[i] && pads[i].index === index) {
return pads[i];
}
}
},
/**
* The internal update loop. Refreshes all connected gamepads and processes their events.
*
* Called automatically by the Input Manager, invoked from the Game step.
*
* @method Phaser.Input.Gamepad.GamepadPlugin#update
* @private
* @fires Phaser.Input.Gamepad.Events#CONNECTED
* @fires Phaser.Input.Gamepad.Events#DISCONNECTED
* @since 3.10.0
*/
update: function() {
if (!this.enabled) {
return;
}
this.refreshPads();
var len = this.queue.length;
if (len === 0) {
return;
}
var queue = this.queue.splice(0, len);
for (var i = 0; i < len; i++) {
var event = queue[i];
var pad = this.getPad(event.gamepad.index);
if (event.type === "gamepadconnected") {
this.emit(Events.CONNECTED, pad, event);
} else if (event.type === "gamepaddisconnected") {
this.emit(Events.DISCONNECTED, pad, event);
}
}
},
/**
* Shuts the Gamepad Plugin down.
* All this does is remove any listeners bound to it.
*
* @method Phaser.Input.Gamepad.GamepadPlugin#shutdown
* @private
* @since 3.10.0
*/
shutdown: function() {
this.stopListeners();
this.removeAllListeners();
},
/**
* Destroys this Gamepad Plugin, disconnecting all Gamepads and releasing internal references.
*
* @method Phaser.Input.Gamepad.GamepadPlugin#destroy
* @private
* @since 3.10.0
*/
destroy: function() {
this.shutdown();
for (var i = 0; i < this.gamepads.length; i++) {
if (this.gamepads[i]) {
this.gamepads[i].destroy();
}
}
this.gamepads = [];
this.scene = null;
this.settings = null;
this.sceneInputPlugin = null;
this.target = null;
},
/**
* The total number of connected game pads.
*
* @name Phaser.Input.Gamepad.GamepadPlugin#total
* @type {number}
* @since 3.10.0
*/
total: {
get: function() {
return this.gamepads.length;
}
},
/**
* A reference to the first connected Gamepad.
*
* This will be undefined if either no pads are connected, or the browser
* has not yet issued a gamepadconnect, which can happen even if a Gamepad
* is plugged in, but hasn't yet had any buttons pressed on it.
*
* @name Phaser.Input.Gamepad.GamepadPlugin#pad1
* @type {Phaser.Input.Gamepad.Gamepad}
* @since 3.10.0
*/
pad1: {
get: function() {
return this._pad1;
}
},
/**
* A reference to the second connected Gamepad.
*
* This will be undefined if either no pads are connected, or the browser
* has not yet issued a gamepadconnect, which can happen even if a Gamepad
* is plugged in, but hasn't yet had any buttons pressed on it.
*
* @name Phaser.Input.Gamepad.GamepadPlugin#pad2
* @type {Phaser.Input.Gamepad.Gamepad}
* @since 3.10.0
*/
pad2: {
get: function() {
return this._pad2;
}
},
/**
* A reference to the third connected Gamepad.
*
* This will be undefined if either no pads are connected, or the browser
* has not yet issued a gamepadconnect, which can happen even if a Gamepad
* is plugged in, but hasn't yet had any buttons pressed on it.
*
* @name Phaser.Input.Gamepad.GamepadPlugin#pad3
* @type {Phaser.Input.Gamepad.Gamepad}
* @since 3.10.0
*/
pad3: {
get: function() {
return this._pad3;
}
},
/**
* A reference to the fourth connected Gamepad.
*
* This will be undefined if either no pads are connected, or the browser
* has not yet issued a gamepadconnect, which can happen even if a Gamepad
* is plugged in, but hasn't yet had any buttons pressed on it.
*
* @name Phaser.Input.Gamepad.GamepadPlugin#pad4
* @type {Phaser.Input.Gamepad.Gamepad}
* @since 3.10.0
*/
pad4: {
get: function() {
return this._pad4;
}
}
});
InputPluginCache.register("GamepadPlugin", GamepadPlugin, "gamepad", "gamepad", "inputGamepad");
module2.exports = GamepadPlugin;
}
),
/***/
89651: (
/***/
(module2) => {
module2.exports = {
/**
* D-Pad up
*
* @name Phaser.Input.Gamepad.Configs.SNES_USB.UP
* @const
* @type {number}
* @since 3.0.0
*/
UP: 12,
/**
* D-Pad down
*
* @name Phaser.Input.Gamepad.Configs.SNES_USB.DOWN
* @const
* @type {number}
* @since 3.0.0
*/
DOWN: 13,
/**
* D-Pad left
*
* @name Phaser.Input.Gamepad.Configs.SNES_USB.LEFT
* @const
* @type {number}
* @since 3.0.0
*/
LEFT: 14,
/**
* D-Pad right
*
* @name Phaser.Input.Gamepad.Configs.SNES_USB.RIGHT
* @const
* @type {number}
* @since 3.0.0
*/
RIGHT: 15,
/**
* Select button
*
* @name Phaser.Input.Gamepad.Configs.SNES_USB.SELECT
* @const
* @type {number}
* @since 3.0.0
*/
SELECT: 8,
/**
* Start button
*
* @name Phaser.Input.Gamepad.Configs.SNES_USB.START
* @const
* @type {number}
* @since 3.0.0
*/
START: 9,
/**
* B Button (Bottom)
*
* @name Phaser.Input.Gamepad.Configs.SNES_USB.B
* @const
* @type {number}
* @since 3.0.0
*/
B: 0,
/**
* A Button (Right)
*
* @name Phaser.Input.Gamepad.Configs.SNES_USB.A
* @const
* @type {number}
* @since 3.0.0
*/
A: 1,
/**
* Y Button (Left)
*
* @name Phaser.Input.Gamepad.Configs.SNES_USB.Y
* @const
* @type {number}
* @since 3.0.0
*/
Y: 2,
/**
* X Button (Top)
*
* @name Phaser.Input.Gamepad.Configs.SNES_USB.X
* @const
* @type {number}
* @since 3.0.0
*/
X: 3,
/**
* Left bumper
*
* @name Phaser.Input.Gamepad.Configs.SNES_USB.LEFT_SHOULDER
* @const
* @type {number}
* @since 3.0.0
*/
LEFT_SHOULDER: 4,
/**
* Right bumper
*
* @name Phaser.Input.Gamepad.Configs.SNES_USB.RIGHT_SHOULDER
* @const
* @type {number}
* @since 3.0.0
*/
RIGHT_SHOULDER: 5
};
}
),
/***/
65294: (
/***/
(module2) => {
module2.exports = {
/**
* D-Pad up
*
* @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.UP
* @const
* @type {number}
* @since 3.0.0
*/
UP: 12,
/**
* D-Pad down
*
* @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.DOWN
* @const
* @type {number}
* @since 3.0.0
*/
DOWN: 13,
/**
* D-Pad left
*
* @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.LEFT
* @const
* @type {number}
* @since 3.0.0
*/
LEFT: 14,
/**
* D-Pad up
*
* @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.RIGHT
* @const
* @type {number}
* @since 3.0.0
*/
RIGHT: 15,
/**
* Share button
*
* @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.SHARE
* @const
* @type {number}
* @since 3.0.0
*/
SHARE: 8,
/**
* Options button
*
* @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.OPTIONS
* @const
* @type {number}
* @since 3.0.0
*/
OPTIONS: 9,
/**
* PlayStation logo button
*
* @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.PS
* @const
* @type {number}
* @since 3.0.0
*/
PS: 16,
/**
* Touchpad click
*
* @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.TOUCHBAR
* @const
* @type {number}
* @since 3.0.0
*/
TOUCHBAR: 17,
/**
* Cross button (Bottom)
*
* @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.X
* @const
* @type {number}
* @since 3.0.0
*/
X: 0,
/**
* Circle button (Right)
*
* @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.CIRCLE
* @const
* @type {number}
* @since 3.0.0
*/
CIRCLE: 1,
/**
* Square button (Left)
*
* @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.SQUARE
* @const
* @type {number}
* @since 3.0.0
*/
SQUARE: 2,
/**
* Triangle button (Top)
*
* @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.TRIANGLE
* @const
* @type {number}
* @since 3.0.0
*/
TRIANGLE: 3,
/**
* Left bumper (L1)
*
* @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.L1
* @const
* @type {number}
* @since 3.0.0
*/
L1: 4,
/**
* Right bumper (R1)
*
* @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.R1
* @const
* @type {number}
* @since 3.0.0
*/
R1: 5,
/**
* Left trigger (L2)
*
* @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.L2
* @const
* @type {number}
* @since 3.0.0
*/
L2: 6,
/**
* Right trigger (R2)
*
* @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.R2
* @const
* @type {number}
* @since 3.0.0
*/
R2: 7,
/**
* Left stick click (L3)
*
* @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.L3
* @const
* @type {number}
* @since 3.0.0
*/
L3: 10,
/**
* Right stick click (R3)
*
* @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.R3
* @const
* @type {number}
* @since 3.0.0
*/
R3: 11,
/**
* Left stick horizontal
*
* @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.LEFT_STICK_H
* @const
* @type {number}
* @since 3.0.0
*/
LEFT_STICK_H: 0,
/**
* Left stick vertical
*
* @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.LEFT_STICK_V
* @const
* @type {number}
* @since 3.0.0
*/
LEFT_STICK_V: 1,
/**
* Right stick horizontal
*
* @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.RIGHT_STICK_H
* @const
* @type {number}
* @since 3.0.0
*/
RIGHT_STICK_H: 2,
/**
* Right stick vertical
*
* @name Phaser.Input.Gamepad.Configs.DUALSHOCK_4.RIGHT_STICK_V
* @const
* @type {number}
* @since 3.0.0
*/
RIGHT_STICK_V: 3
};
}
),
/***/
90089: (
/***/
(module2) => {
module2.exports = {
/**
* D-Pad up
*
* @name Phaser.Input.Gamepad.Configs.XBOX_360.UP
* @const
* @type {number}
* @since 3.0.0
*/
UP: 12,
/**
* D-Pad down
*
* @name Phaser.Input.Gamepad.Configs.XBOX_360.DOWN
* @const
* @type {number}
* @since 3.0.0
*/
DOWN: 13,
/**
* D-Pad left
*
* @name Phaser.Input.Gamepad.Configs.XBOX_360.LEFT
* @const
* @type {number}
* @since 3.0.0
*/
LEFT: 14,
/**
* D-Pad right
*
* @name Phaser.Input.Gamepad.Configs.XBOX_360.RIGHT
* @const
* @type {number}
* @since 3.0.0
*/
RIGHT: 15,
/**
* XBox menu button
*
* @name Phaser.Input.Gamepad.Configs.XBOX_360.MENU
* @const
* @type {number}
* @since 3.0.0
*/
MENU: 16,
/**
* A button (Bottom)
*
* @name Phaser.Input.Gamepad.Configs.XBOX_360.A
* @const
* @type {number}
* @since 3.0.0
*/
A: 0,
/**
* B button (Right)
*
* @name Phaser.Input.Gamepad.Configs.XBOX_360.B
* @const
* @type {number}
* @since 3.0.0
*/
B: 1,
/**
* X button (Left)
*
* @name Phaser.Input.Gamepad.Configs.XBOX_360.X
* @const
* @type {number}
* @since 3.0.0
*/
X: 2,
/**
* Y button (Top)
*
* @name Phaser.Input.Gamepad.Configs.XBOX_360.Y
* @const
* @type {number}
* @since 3.0.0
*/
Y: 3,
/**
* Left Bumper
*
* @name Phaser.Input.Gamepad.Configs.XBOX_360.LB
* @const
* @type {number}
* @since 3.0.0
*/
LB: 4,
/**
* Right Bumper
*
* @name Phaser.Input.Gamepad.Configs.XBOX_360.RB
* @const
* @type {number}
* @since 3.0.0
*/
RB: 5,
/**
* Left Trigger
*
* @name Phaser.Input.Gamepad.Configs.XBOX_360.LT
* @const
* @type {number}
* @since 3.0.0
*/
LT: 6,
/**
* Right Trigger
*
* @name Phaser.Input.Gamepad.Configs.XBOX_360.RT
* @const
* @type {number}
* @since 3.0.0
*/
RT: 7,
/**
* Back / Change View button
*
* @name Phaser.Input.Gamepad.Configs.XBOX_360.BACK
* @const
* @type {number}
* @since 3.0.0
*/
BACK: 8,
/**
* Start button
*
* @name Phaser.Input.Gamepad.Configs.XBOX_360.START
* @const
* @type {number}
* @since 3.0.0
*/
START: 9,
/**
* Left Stick press
*
* @name Phaser.Input.Gamepad.Configs.XBOX_360.LS
* @const
* @type {number}
* @since 3.0.0
*/
LS: 10,
/**
* Right stick press
*
* @name Phaser.Input.Gamepad.Configs.XBOX_360.RS
* @const
* @type {number}
* @since 3.0.0
*/
RS: 11,
/**
* Left Stick horizontal
*
* @name Phaser.Input.Gamepad.Configs.XBOX_360.LEFT_STICK_H
* @const
* @type {number}
* @since 3.0.0
*/
LEFT_STICK_H: 0,
/**
* Left Stick vertical
*
* @name Phaser.Input.Gamepad.Configs.XBOX_360.LEFT_STICK_V
* @const
* @type {number}
* @since 3.0.0
*/
LEFT_STICK_V: 1,
/**
* Right Stick horizontal
*
* @name Phaser.Input.Gamepad.Configs.XBOX_360.RIGHT_STICK_H
* @const
* @type {number}
* @since 3.0.0
*/
RIGHT_STICK_H: 2,
/**
* Right Stick vertical
*
* @name Phaser.Input.Gamepad.Configs.XBOX_360.RIGHT_STICK_V
* @const
* @type {number}
* @since 3.0.0
*/
RIGHT_STICK_V: 3
};
}
),
/***/
64894: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
DUALSHOCK_4: __webpack_require__2(65294),
SNES_USB: __webpack_require__2(89651),
XBOX_360: __webpack_require__2(90089)
};
}
),
/***/
46008: (
/***/
(module2) => {
module2.exports = "down";
}
),
/***/
7629: (
/***/
(module2) => {
module2.exports = "up";
}
),
/***/
42206: (
/***/
(module2) => {
module2.exports = "connected";
}
),
/***/
86544: (
/***/
(module2) => {
module2.exports = "disconnected";
}
),
/***/
94784: (
/***/
(module2) => {
module2.exports = "down";
}
),
/***/
14325: (
/***/
(module2) => {
module2.exports = "up";
}
),
/***/
92734: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
BUTTON_DOWN: __webpack_require__2(46008),
BUTTON_UP: __webpack_require__2(7629),
CONNECTED: __webpack_require__2(42206),
DISCONNECTED: __webpack_require__2(86544),
GAMEPAD_BUTTON_DOWN: __webpack_require__2(94784),
GAMEPAD_BUTTON_UP: __webpack_require__2(14325)
};
}
),
/***/
48646: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Axis: __webpack_require__2(97421),
Button: __webpack_require__2(28884),
Events: __webpack_require__2(92734),
Gamepad: __webpack_require__2(99125),
GamepadPlugin: __webpack_require__2(56654),
Configs: __webpack_require__2(64894)
};
}
),
/***/
14350: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(93301);
var Extend = __webpack_require__2(79291);
var Input = {
CreatePixelPerfectHandler: __webpack_require__2(84409),
CreateInteractiveObject: __webpack_require__2(74457),
Events: __webpack_require__2(8214),
Gamepad: __webpack_require__2(48646),
InputManager: __webpack_require__2(7003),
InputPlugin: __webpack_require__2(48205),
InputPluginCache: __webpack_require__2(89639),
Keyboard: __webpack_require__2(51442),
Mouse: __webpack_require__2(87078),
Pointer: __webpack_require__2(42515),
Touch: __webpack_require__2(95618)
};
Input = Extend(false, Input, CONST);
module2.exports = Input;
}
),
/***/
78970: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var ArrayRemove = __webpack_require__2(72905);
var Class = __webpack_require__2(83419);
var GameEvents = __webpack_require__2(8443);
var InputEvents = __webpack_require__2(8214);
var KeyCodes = __webpack_require__2(46032);
var NOOP = __webpack_require__2(29747);
var KeyboardManager = new Class({
initialize: function KeyboardManager2(inputManager) {
this.manager = inputManager;
this.queue = [];
this.preventDefault = true;
this.captures = [];
this.enabled = false;
this.target;
this.onKeyDown = NOOP;
this.onKeyUp = NOOP;
inputManager.events.once(InputEvents.MANAGER_BOOT, this.boot, this);
},
/**
* The Keyboard Manager boot process.
*
* @method Phaser.Input.Keyboard.KeyboardManager#boot
* @private
* @since 3.16.0
*/
boot: function() {
var config = this.manager.config;
this.enabled = config.inputKeyboard;
this.target = config.inputKeyboardEventTarget;
this.addCapture(config.inputKeyboardCapture);
if (!this.target && window) {
this.target = window;
}
if (this.enabled && this.target) {
this.startListeners();
}
this.manager.game.events.on(GameEvents.POST_STEP, this.postUpdate, this);
},
/**
* Starts the Keyboard Event listeners running.
* This is called automatically and does not need to be manually invoked.
*
* @method Phaser.Input.Keyboard.KeyboardManager#startListeners
* @since 3.16.0
*/
startListeners: function() {
var _this = this;
this.onKeyDown = function(event) {
if (event.defaultPrevented || !_this.enabled || !_this.manager) {
return;
}
_this.queue.push(event);
_this.manager.events.emit(InputEvents.MANAGER_PROCESS);
var modified = event.altKey || event.ctrlKey || event.shiftKey || event.metaKey;
if (_this.preventDefault && !modified && _this.captures.indexOf(event.keyCode) > -1) {
event.preventDefault();
}
};
this.onKeyUp = function(event) {
if (event.defaultPrevented || !_this.enabled || !_this.manager) {
return;
}
_this.queue.push(event);
_this.manager.events.emit(InputEvents.MANAGER_PROCESS);
var modified = event.altKey || event.ctrlKey || event.shiftKey || event.metaKey;
if (_this.preventDefault && !modified && _this.captures.indexOf(event.keyCode) > -1) {
event.preventDefault();
}
};
var target = this.target;
if (target) {
target.addEventListener("keydown", this.onKeyDown, false);
target.addEventListener("keyup", this.onKeyUp, false);
this.enabled = true;
}
},
/**
* Stops the Key Event listeners.
* This is called automatically and does not need to be manually invoked.
*
* @method Phaser.Input.Keyboard.KeyboardManager#stopListeners
* @since 3.16.0
*/
stopListeners: function() {
var target = this.target;
target.removeEventListener("keydown", this.onKeyDown, false);
target.removeEventListener("keyup", this.onKeyUp, false);
this.enabled = false;
},
/**
* Clears the event queue.
* Called automatically by the Input Manager.
*
* @method Phaser.Input.Keyboard.KeyboardManager#postUpdate
* @private
* @since 3.16.0
*/
postUpdate: function() {
this.queue = [];
},
/**
* By default when a key is pressed Phaser will not stop the event from propagating up to the browser.
* There are some keys this can be annoying for, like the arrow keys or space bar, which make the browser window scroll.
*
* This `addCapture` method enables consuming keyboard event for specific keys so it doesn't bubble up to the the browser
* and cause the default browser behavior.
*
* Please note that keyboard captures are global. This means that if you call this method from within a Scene, to say prevent
* the SPACE BAR from triggering a page scroll, then it will prevent it for any Scene in your game, not just the calling one.
*
* You can pass in a single key code value, or an array of key codes, or a string:
*
* ```javascript
* this.input.keyboard.addCapture(62);
* ```
*
* An array of key codes:
*
* ```javascript
* this.input.keyboard.addCapture([ 62, 63, 64 ]);
* ```
*
* Or a string:
*
* ```javascript
* this.input.keyboard.addCapture('W,S,A,D');
* ```
*
* To use non-alpha numeric keys, use a string, such as 'UP', 'SPACE' or 'LEFT'.
*
* You can also provide an array mixing both strings and key code integers.
*
* If there are active captures after calling this method, the `preventDefault` property is set to `true`.
*
* @method Phaser.Input.Keyboard.KeyboardManager#addCapture
* @since 3.16.0
*
* @param {(string|number|number[]|any[])} keycode - The Key Codes to enable capture for, preventing them reaching the browser.
*/
addCapture: function(keycode) {
if (typeof keycode === "string") {
keycode = keycode.split(",");
}
if (!Array.isArray(keycode)) {
keycode = [keycode];
}
var captures = this.captures;
for (var i = 0; i < keycode.length; i++) {
var code = keycode[i];
if (typeof code === "string") {
code = KeyCodes[code.trim().toUpperCase()];
}
if (captures.indexOf(code) === -1) {
captures.push(code);
}
}
this.preventDefault = captures.length > 0;
},
/**
* Removes an existing key capture.
*
* Please note that keyboard captures are global. This means that if you call this method from within a Scene, to remove
* the capture of a key, then it will remove it for any Scene in your game, not just the calling one.
*
* You can pass in a single key code value, or an array of key codes, or a string:
*
* ```javascript
* this.input.keyboard.removeCapture(62);
* ```
*
* An array of key codes:
*
* ```javascript
* this.input.keyboard.removeCapture([ 62, 63, 64 ]);
* ```
*
* Or a string:
*
* ```javascript
* this.input.keyboard.removeCapture('W,S,A,D');
* ```
*
* To use non-alpha numeric keys, use a string, such as 'UP', 'SPACE' or 'LEFT'.
*
* You can also provide an array mixing both strings and key code integers.
*
* If there are no captures left after calling this method, the `preventDefault` property is set to `false`.
*
* @method Phaser.Input.Keyboard.KeyboardManager#removeCapture
* @since 3.16.0
*
* @param {(string|number|number[]|any[])} keycode - The Key Codes to disable capture for, allowing them reaching the browser again.
*/
removeCapture: function(keycode) {
if (typeof keycode === "string") {
keycode = keycode.split(",");
}
if (!Array.isArray(keycode)) {
keycode = [keycode];
}
var captures = this.captures;
for (var i = 0; i < keycode.length; i++) {
var code = keycode[i];
if (typeof code === "string") {
code = KeyCodes[code.toUpperCase()];
}
ArrayRemove(captures, code);
}
this.preventDefault = captures.length > 0;
},
/**
* Removes all keyboard captures and sets the `preventDefault` property to `false`.
*
* @method Phaser.Input.Keyboard.KeyboardManager#clearCaptures
* @since 3.16.0
*/
clearCaptures: function() {
this.captures = [];
this.preventDefault = false;
},
/**
* Destroys this Keyboard Manager instance.
*
* @method Phaser.Input.Keyboard.KeyboardManager#destroy
* @since 3.16.0
*/
destroy: function() {
this.stopListeners();
this.clearCaptures();
this.queue = [];
this.manager.game.events.off(GameEvents.POST_RENDER, this.postUpdate, this);
this.target = null;
this.enabled = false;
this.manager = null;
}
});
module2.exports = KeyboardManager;
}
),
/***/
28846: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var EventEmitter = __webpack_require__2(50792);
var Events = __webpack_require__2(95922);
var GameEvents = __webpack_require__2(8443);
var GetValue = __webpack_require__2(35154);
var InputEvents = __webpack_require__2(8214);
var InputPluginCache = __webpack_require__2(89639);
var Key = __webpack_require__2(30472);
var KeyCodes = __webpack_require__2(46032);
var KeyCombo = __webpack_require__2(87960);
var KeyMap = __webpack_require__2(74600);
var SceneEvents = __webpack_require__2(44594);
var SnapFloor = __webpack_require__2(56583);
var KeyboardPlugin = new Class({
Extends: EventEmitter,
initialize: function KeyboardPlugin2(sceneInputPlugin) {
EventEmitter.call(this);
this.game = sceneInputPlugin.systems.game;
this.scene = sceneInputPlugin.scene;
this.settings = this.scene.sys.settings;
this.sceneInputPlugin = sceneInputPlugin;
this.manager = sceneInputPlugin.manager.keyboard;
this.enabled = true;
this.keys = [];
this.combos = [];
this.prevCode = null;
this.prevTime = 0;
this.prevType = null;
sceneInputPlugin.pluginEvents.once(InputEvents.BOOT, this.boot, this);
sceneInputPlugin.pluginEvents.on(InputEvents.START, this.start, this);
},
/**
* This method is called automatically, only once, when the Scene is first created.
* Do not invoke it directly.
*
* @method Phaser.Input.Keyboard.KeyboardPlugin#boot
* @private
* @since 3.10.0
*/
boot: function() {
var settings = this.settings.input;
this.enabled = GetValue(settings, "keyboard", true);
var captures = GetValue(settings, "keyboard.capture", null);
if (captures) {
this.addCaptures(captures);
}
this.sceneInputPlugin.pluginEvents.once(InputEvents.DESTROY, this.destroy, this);
},
/**
* This method is called automatically by the Scene when it is starting up.
* It is responsible for creating local systems, properties and listening for Scene events.
* Do not invoke it directly.
*
* @method Phaser.Input.Keyboard.KeyboardPlugin#start
* @private
* @since 3.10.0
*/
start: function() {
this.sceneInputPlugin.manager.events.on(InputEvents.MANAGER_PROCESS, this.update, this);
this.sceneInputPlugin.pluginEvents.once(InputEvents.SHUTDOWN, this.shutdown, this);
this.game.events.on(GameEvents.BLUR, this.resetKeys, this);
this.scene.sys.events.on(SceneEvents.PAUSE, this.resetKeys, this);
this.scene.sys.events.on(SceneEvents.SLEEP, this.resetKeys, this);
},
/**
* Checks to see if both this plugin and the Scene to which it belongs is active.
*
* @method Phaser.Input.Keyboard.KeyboardPlugin#isActive
* @since 3.10.0
*
* @return {boolean} `true` if the plugin and the Scene it belongs to is active.
*/
isActive: function() {
return this.enabled && this.scene.sys.canInput();
},
/**
* By default when a key is pressed Phaser will not stop the event from propagating up to the browser.
* There are some keys this can be annoying for, like the arrow keys or space bar, which make the browser window scroll.
*
* This `addCapture` method enables consuming keyboard events for specific keys, so they don't bubble up the browser
* and cause the default behaviors.
*
* Please note that keyboard captures are global. This means that if you call this method from within a Scene, to say prevent
* the SPACE BAR from triggering a page scroll, then it will prevent it for any Scene in your game, not just the calling one.
*
* You can pass a single key code value:
*
* ```javascript
* this.input.keyboard.addCapture(62);
* ```
*
* An array of key codes:
*
* ```javascript
* this.input.keyboard.addCapture([ 62, 63, 64 ]);
* ```
*
* Or, a comma-delimited string:
*
* ```javascript
* this.input.keyboard.addCapture('W,S,A,D');
* ```
*
* To use non-alpha numeric keys, use a string, such as 'UP', 'SPACE' or 'LEFT'.
*
* You can also provide an array mixing both strings and key code integers.
*
* @method Phaser.Input.Keyboard.KeyboardPlugin#addCapture
* @since 3.16.0
*
* @param {(string|number|number[]|any[])} keycode - The Key Codes to enable event capture for.
*
* @return {this} This KeyboardPlugin object.
*/
addCapture: function(keycode) {
this.manager.addCapture(keycode);
return this;
},
/**
* Removes an existing key capture.
*
* Please note that keyboard captures are global. This means that if you call this method from within a Scene, to remove
* the capture of a key, then it will remove it for any Scene in your game, not just the calling one.
*
* You can pass a single key code value:
*
* ```javascript
* this.input.keyboard.removeCapture(62);
* ```
*
* An array of key codes:
*
* ```javascript
* this.input.keyboard.removeCapture([ 62, 63, 64 ]);
* ```
*
* Or, a comma-delimited string:
*
* ```javascript
* this.input.keyboard.removeCapture('W,S,A,D');
* ```
*
* To use non-alpha numeric keys, use a string, such as 'UP', 'SPACE' or 'LEFT'.
*
* You can also provide an array mixing both strings and key code integers.
*
* @method Phaser.Input.Keyboard.KeyboardPlugin#removeCapture
* @since 3.16.0
*
* @param {(string|number|number[]|any[])} keycode - The Key Codes to disable event capture for.
*
* @return {this} This KeyboardPlugin object.
*/
removeCapture: function(keycode) {
this.manager.removeCapture(keycode);
return this;
},
/**
* Returns an array that contains all of the keyboard captures currently enabled.
*
* @method Phaser.Input.Keyboard.KeyboardPlugin#getCaptures
* @since 3.16.0
*
* @return {number[]} An array of all the currently capturing key codes.
*/
getCaptures: function() {
return this.manager.captures;
},
/**
* Allows Phaser to prevent any key captures you may have defined from bubbling up the browser.
* You can use this to re-enable event capturing if you had paused it via `disableGlobalCapture`.
*
* @method Phaser.Input.Keyboard.KeyboardPlugin#enableGlobalCapture
* @since 3.16.0
*
* @return {this} This KeyboardPlugin object.
*/
enableGlobalCapture: function() {
this.manager.preventDefault = true;
return this;
},
/**
* Disables Phaser from preventing any key captures you may have defined, without actually removing them.
* You can use this to temporarily disable event capturing if, for example, you swap to a DOM element.
*
* @method Phaser.Input.Keyboard.KeyboardPlugin#disableGlobalCapture
* @since 3.16.0
*
* @return {this} This KeyboardPlugin object.
*/
disableGlobalCapture: function() {
this.manager.preventDefault = false;
return this;
},
/**
* Removes all keyboard captures.
*
* Note that this is a global change. It will clear all event captures across your game, not just for this specific Scene.
*
* @method Phaser.Input.Keyboard.KeyboardPlugin#clearCaptures
* @since 3.16.0
*
* @return {this} This KeyboardPlugin object.
*/
clearCaptures: function() {
this.manager.clearCaptures();
return this;
},
/**
* Creates and returns an object containing 4 hotkeys for Up, Down, Left and Right, and also Space Bar and shift.
*
* @method Phaser.Input.Keyboard.KeyboardPlugin#createCursorKeys
* @since 3.10.0
*
* @return {Phaser.Types.Input.Keyboard.CursorKeys} An object containing the properties: `up`, `down`, `left`, `right`, `space` and `shift`.
*/
createCursorKeys: function() {
return this.addKeys({
up: KeyCodes.UP,
down: KeyCodes.DOWN,
left: KeyCodes.LEFT,
right: KeyCodes.RIGHT,
space: KeyCodes.SPACE,
shift: KeyCodes.SHIFT
});
},
/**
* A practical way to create an object containing user selected hotkeys.
*
* For example:
*
* ```javascript
* this.input.keyboard.addKeys({ 'up': Phaser.Input.Keyboard.KeyCodes.W, 'down': Phaser.Input.Keyboard.KeyCodes.S });
* ```
*
* would return an object containing the properties (`up` and `down`) mapped to W and S {@link Phaser.Input.Keyboard.Key} objects.
*
* You can also pass in a comma-separated string:
*
* ```javascript
* this.input.keyboard.addKeys('W,S,A,D');
* ```
*
* Which will return an object with the properties W, S, A and D mapped to the relevant Key objects.
*
* To use non-alpha numeric keys, use a string, such as 'UP', 'SPACE' or 'LEFT'.
*
* @method Phaser.Input.Keyboard.KeyboardPlugin#addKeys
* @since 3.10.0
*
* @param {(object|string)} keys - An object containing Key Codes, or a comma-separated string.
* @param {boolean} [enableCapture=true] - Automatically call `preventDefault` on the native DOM browser event for the key codes being added.
* @param {boolean} [emitOnRepeat=false] - Controls if the Key will continuously emit a 'down' event while being held down (true), or emit the event just once (false, the default).
*
* @return {object} An object containing Key objects mapped to the input properties.
*/
addKeys: function(keys, enableCapture, emitOnRepeat) {
if (enableCapture === void 0) {
enableCapture = true;
}
if (emitOnRepeat === void 0) {
emitOnRepeat = false;
}
var output = {};
if (typeof keys === "string") {
keys = keys.split(",");
for (var i = 0; i < keys.length; i++) {
var currentKey = keys[i].trim();
if (currentKey) {
output[currentKey] = this.addKey(currentKey, enableCapture, emitOnRepeat);
}
}
} else {
for (var key in keys) {
output[key] = this.addKey(keys[key], enableCapture, emitOnRepeat);
}
}
return output;
},
/**
* Adds a Key object to this Keyboard Plugin.
*
* The given argument can be either an existing Key object, a string, such as `A` or `SPACE`, or a key code value.
*
* If a Key object is given, and one already exists matching the same key code, the existing one is replaced with the new one.
*
* @method Phaser.Input.Keyboard.KeyboardPlugin#addKey
* @since 3.10.0
*
* @param {(Phaser.Input.Keyboard.Key|string|number)} key - Either a Key object, a string, such as `A` or `SPACE`, or a key code value.
* @param {boolean} [enableCapture=true] - Automatically call `preventDefault` on the native DOM browser event for the key codes being added.
* @param {boolean} [emitOnRepeat=false] - Controls if the Key will continuously emit a 'down' event while being held down (true), or emit the event just once (false, the default).
*
* @return {Phaser.Input.Keyboard.Key} The newly created Key object, or a reference to it if it already existed in the keys array.
*/
addKey: function(key, enableCapture, emitOnRepeat) {
if (enableCapture === void 0) {
enableCapture = true;
}
if (emitOnRepeat === void 0) {
emitOnRepeat = false;
}
var keys = this.keys;
if (key instanceof Key) {
var idx = keys.indexOf(key);
if (idx > -1) {
keys[idx] = key;
} else {
keys[key.keyCode] = key;
}
if (enableCapture) {
this.addCapture(key.keyCode);
}
key.setEmitOnRepeat(emitOnRepeat);
return key;
}
if (typeof key === "string") {
key = KeyCodes[key.toUpperCase()];
}
if (!keys[key]) {
keys[key] = new Key(this, key);
if (enableCapture) {
this.addCapture(key);
}
keys[key].setEmitOnRepeat(emitOnRepeat);
}
return keys[key];
},
/**
* Removes a Key object from this Keyboard Plugin.
*
* The given argument can be either a Key object, a string, such as `A` or `SPACE`, or a key code value.
*
* @method Phaser.Input.Keyboard.KeyboardPlugin#removeKey
* @since 3.10.0
*
* @param {(Phaser.Input.Keyboard.Key|string|number)} key - Either a Key object, a string, such as `A` or `SPACE`, or a key code value.
* @param {boolean} [destroy=false] - Call `Key.destroy` on the removed Key object?
* @param {boolean} [removeCapture=false] - Remove this Key from being captured? Only applies if set to capture when created.
*
* @return {this} This KeyboardPlugin object.
*/
removeKey: function(key, destroy, removeCapture) {
if (destroy === void 0) {
destroy = false;
}
if (removeCapture === void 0) {
removeCapture = false;
}
var keys = this.keys;
var ref;
if (key instanceof Key) {
var idx = keys.indexOf(key);
if (idx > -1) {
ref = this.keys[idx];
this.keys[idx] = void 0;
}
} else if (typeof key === "string") {
key = KeyCodes[key.toUpperCase()];
}
if (keys[key]) {
ref = keys[key];
keys[key] = void 0;
}
if (ref) {
ref.plugin = null;
if (removeCapture) {
this.removeCapture(ref.keyCode);
}
if (destroy) {
ref.destroy();
}
}
return this;
},
/**
* Removes all Key objects created by _this_ Keyboard Plugin.
*
* @method Phaser.Input.Keyboard.KeyboardPlugin#removeAllKeys
* @since 3.24.0
*
* @param {boolean} [destroy=false] - Call `Key.destroy` on each removed Key object?
* @param {boolean} [removeCapture=false] - Remove all key captures for Key objects owened by this plugin?
*
* @return {this} This KeyboardPlugin object.
*/
removeAllKeys: function(destroy, removeCapture) {
if (destroy === void 0) {
destroy = false;
}
if (removeCapture === void 0) {
removeCapture = false;
}
var keys = this.keys;
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (key) {
keys[i] = void 0;
if (removeCapture) {
this.removeCapture(key.keyCode);
}
if (destroy) {
key.destroy();
}
}
}
return this;
},
/**
* Creates a new KeyCombo.
*
* A KeyCombo will listen for a specific string of keys from the Keyboard, and when it receives them
* it will emit a `keycombomatch` event from this Keyboard Plugin.
*
* The keys to be listened for can be defined as:
*
* A string (i.e. 'ATARI')
* An array of either integers (key codes) or strings, or a mixture of both
* An array of objects (such as Key objects) with a public 'keyCode' property
*
* For example, to listen for the Konami code (up, up, down, down, left, right, left, right, b, a, enter)
* you could pass the following array of key codes:
*
* ```javascript
* this.input.keyboard.createCombo([ 38, 38, 40, 40, 37, 39, 37, 39, 66, 65, 13 ], { resetOnMatch: true });
*
* this.input.keyboard.on('keycombomatch', function (event) {
* console.log('Konami Code entered!');
* });
* ```
*
* Or, to listen for the user entering the word PHASER:
*
* ```javascript
* this.input.keyboard.createCombo('PHASER');
* ```
*
* @method Phaser.Input.Keyboard.KeyboardPlugin#createCombo
* @since 3.10.0
*
* @param {(string|number[]|object[])} keys - The keys that comprise this combo.
* @param {Phaser.Types.Input.Keyboard.KeyComboConfig} [config] - A Key Combo configuration object.
*
* @return {Phaser.Input.Keyboard.KeyCombo} The new KeyCombo object.
*/
createCombo: function(keys, config) {
return new KeyCombo(this, keys, config);
},
/**
* Checks if the given Key object is currently being held down.
*
* The difference between this method and checking the `Key.isDown` property directly is that you can provide
* a duration to this method. For example, if you wanted a key press to fire a bullet, but you only wanted
* it to be able to fire every 100ms, then you can call this method with a `duration` of 100 and it
* will only return `true` every 100ms.
*
* If the Keyboard Plugin has been disabled, this method will always return `false`.
*
* @method Phaser.Input.Keyboard.KeyboardPlugin#checkDown
* @since 3.11.0
*
* @param {Phaser.Input.Keyboard.Key} key - A Key object.
* @param {number} [duration=0] - The duration which must have elapsed before this Key is considered as being down.
*
* @return {boolean} `true` if the Key is down within the duration specified, otherwise `false`.
*/
checkDown: function(key, duration) {
if (duration === void 0) {
duration = 0;
}
if (this.enabled && key.isDown) {
var t = SnapFloor(this.time - key.timeDown, duration);
if (t > key._tick) {
key._tick = t;
return true;
}
}
return false;
},
/**
* Internal update handler called by the Input Plugin, which is in turn invoked by the Game step.
*
* @method Phaser.Input.Keyboard.KeyboardPlugin#update
* @private
* @since 3.10.0
*/
update: function() {
var queue = this.manager.queue;
var len = queue.length;
if (!this.isActive() || len === 0) {
return;
}
var keys = this.keys;
for (var i = 0; i < len; i++) {
var event = queue[i];
var code = event.keyCode;
var key = keys[code];
var repeat = false;
if (event.cancelled === void 0) {
event.cancelled = 0;
event.stopImmediatePropagation = function() {
event.cancelled = 1;
};
event.stopPropagation = function() {
event.cancelled = -1;
};
}
if (event.cancelled === -1) {
continue;
}
if (code === this.prevCode && event.timeStamp === this.prevTime && event.type === this.prevType) {
continue;
}
this.prevCode = code;
this.prevTime = event.timeStamp;
this.prevType = event.type;
if (event.type === "keydown") {
if (key) {
repeat = key.isDown;
key.onDown(event);
}
if (!event.cancelled && (!key || !repeat)) {
if (KeyMap[code]) {
this.emit(Events.KEY_DOWN + KeyMap[code], event);
}
if (!event.cancelled) {
this.emit(Events.ANY_KEY_DOWN, event);
}
}
} else {
if (key) {
key.onUp(event);
}
if (!event.cancelled) {
if (KeyMap[code]) {
this.emit(Events.KEY_UP + KeyMap[code], event);
}
if (!event.cancelled) {
this.emit(Events.ANY_KEY_UP, event);
}
}
}
if (event.cancelled === 1) {
event.cancelled = 0;
}
}
},
/**
* Resets all Key objects created by _this_ Keyboard Plugin back to their default un-pressed states.
* This can only reset keys created via the `addKey`, `addKeys` or `createCursorKeys` methods.
* If you have created a Key object directly you'll need to reset it yourself.
*
* This method is called automatically when the Keyboard Plugin shuts down, but can be
* invoked directly at any time you require.
*
* @method Phaser.Input.Keyboard.KeyboardPlugin#resetKeys
* @since 3.15.0
*
* @return {this} This KeyboardPlugin object.
*/
resetKeys: function() {
var keys = this.keys;
for (var i = 0; i < keys.length; i++) {
if (keys[i]) {
keys[i].reset();
}
}
return this;
},
/**
* Shuts this Keyboard Plugin down. This performs the following tasks:
*
* 1 - Removes all keys created by this Keyboard plugin.
* 2 - Stops and removes the keyboard event listeners.
* 3 - Clears out any pending requests in the queue, without processing them.
*
* @method Phaser.Input.Keyboard.KeyboardPlugin#shutdown
* @private
* @since 3.10.0
*/
shutdown: function() {
this.removeAllKeys(true);
this.removeAllListeners();
this.sceneInputPlugin.manager.events.off(InputEvents.MANAGER_PROCESS, this.update, this);
this.game.events.off(GameEvents.BLUR, this.resetKeys);
this.scene.sys.events.off(SceneEvents.PAUSE, this.resetKeys, this);
this.scene.sys.events.off(SceneEvents.SLEEP, this.resetKeys, this);
this.queue = [];
},
/**
* Destroys this Keyboard Plugin instance and all references it holds, plus clears out local arrays.
*
* @method Phaser.Input.Keyboard.KeyboardPlugin#destroy
* @private
* @since 3.10.0
*/
destroy: function() {
this.shutdown();
var keys = this.keys;
for (var i = 0; i < keys.length; i++) {
if (keys[i]) {
keys[i].destroy();
}
}
this.keys = [];
this.combos = [];
this.queue = [];
this.scene = null;
this.settings = null;
this.sceneInputPlugin = null;
this.manager = null;
},
/**
* Internal time value.
*
* @name Phaser.Input.Keyboard.KeyboardPlugin#time
* @type {number}
* @private
* @since 3.11.0
*/
time: {
get: function() {
return this.sceneInputPlugin.manager.time;
}
}
});
InputPluginCache.register("KeyboardPlugin", KeyboardPlugin, "keyboard", "keyboard", "inputKeyboard");
module2.exports = KeyboardPlugin;
}
),
/***/
66970: (
/***/
(module2) => {
var AdvanceKeyCombo = function(event, combo) {
combo.timeLastMatched = event.timeStamp;
combo.index++;
if (combo.index === combo.size) {
return true;
} else {
combo.current = combo.keyCodes[combo.index];
return false;
}
};
module2.exports = AdvanceKeyCombo;
}
),
/***/
87960: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Events = __webpack_require__2(95922);
var GetFastValue = __webpack_require__2(95540);
var ProcessKeyCombo = __webpack_require__2(68769);
var ResetKeyCombo = __webpack_require__2(92803);
var KeyCombo = new Class({
initialize: function KeyCombo2(keyboardPlugin, keys, config) {
if (config === void 0) {
config = {};
}
if (keys.length < 2) {
return false;
}
this.manager = keyboardPlugin;
this.enabled = true;
this.keyCodes = [];
for (var i = 0; i < keys.length; i++) {
var char = keys[i];
if (typeof char === "string") {
this.keyCodes.push(char.toUpperCase().charCodeAt(0));
} else if (typeof char === "number") {
this.keyCodes.push(char);
} else if (char.hasOwnProperty("keyCode")) {
this.keyCodes.push(char.keyCode);
}
}
this.current = this.keyCodes[0];
this.index = 0;
this.size = this.keyCodes.length;
this.timeLastMatched = 0;
this.matched = false;
this.timeMatched = 0;
this.resetOnWrongKey = GetFastValue(config, "resetOnWrongKey", true);
this.maxKeyDelay = GetFastValue(config, "maxKeyDelay", 0);
this.resetOnMatch = GetFastValue(config, "resetOnMatch", false);
this.deleteOnMatch = GetFastValue(config, "deleteOnMatch", false);
var _this = this;
var onKeyDownHandler = function(event) {
if (_this.matched || !_this.enabled) {
return;
}
var matched = ProcessKeyCombo(event, _this);
if (matched) {
_this.manager.emit(Events.COMBO_MATCH, _this, event);
if (_this.resetOnMatch) {
ResetKeyCombo(_this);
} else if (_this.deleteOnMatch) {
_this.destroy();
}
}
};
this.onKeyDown = onKeyDownHandler;
this.manager.on(Events.ANY_KEY_DOWN, this.onKeyDown);
},
/**
* How far complete is this combo? A value between 0 and 1.
*
* @name Phaser.Input.Keyboard.KeyCombo#progress
* @type {number}
* @readonly
* @since 3.0.0
*/
progress: {
get: function() {
return this.index / this.size;
}
},
/**
* Destroys this Key Combo and all of its references.
*
* @method Phaser.Input.Keyboard.KeyCombo#destroy
* @since 3.0.0
*/
destroy: function() {
this.enabled = false;
this.keyCodes = [];
this.manager.off(Events.ANY_KEY_DOWN, this.onKeyDown);
this.manager = null;
}
});
module2.exports = KeyCombo;
}
),
/***/
68769: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var AdvanceKeyCombo = __webpack_require__2(66970);
var ProcessKeyCombo = function(event, combo) {
if (combo.matched) {
return true;
}
var comboMatched = false;
var keyMatched = false;
if (event.keyCode === combo.current) {
if (combo.index > 0 && combo.maxKeyDelay > 0) {
var timeLimit = combo.timeLastMatched + combo.maxKeyDelay;
if (event.timeStamp <= timeLimit) {
keyMatched = true;
comboMatched = AdvanceKeyCombo(event, combo);
}
} else {
keyMatched = true;
comboMatched = AdvanceKeyCombo(event, combo);
}
}
if (!keyMatched && combo.resetOnWrongKey) {
combo.index = 0;
combo.current = combo.keyCodes[0];
}
if (comboMatched) {
combo.timeLastMatched = event.timeStamp;
combo.matched = true;
combo.timeMatched = event.timeStamp;
}
return comboMatched;
};
module2.exports = ProcessKeyCombo;
}
),
/***/
92803: (
/***/
(module2) => {
var ResetKeyCombo = function(combo) {
combo.current = combo.keyCodes[0];
combo.index = 0;
combo.timeLastMatched = 0;
combo.matched = false;
combo.timeMatched = 0;
return combo;
};
module2.exports = ResetKeyCombo;
}
),
/***/
92612: (
/***/
(module2) => {
module2.exports = "keydown";
}
),
/***/
23345: (
/***/
(module2) => {
module2.exports = "keyup";
}
),
/***/
21957: (
/***/
(module2) => {
module2.exports = "keycombomatch";
}
),
/***/
44743: (
/***/
(module2) => {
module2.exports = "down";
}
),
/***/
3771: (
/***/
(module2) => {
module2.exports = "keydown-";
}
),
/***/
46358: (
/***/
(module2) => {
module2.exports = "keyup-";
}
),
/***/
75674: (
/***/
(module2) => {
module2.exports = "up";
}
),
/***/
95922: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
ANY_KEY_DOWN: __webpack_require__2(92612),
ANY_KEY_UP: __webpack_require__2(23345),
COMBO_MATCH: __webpack_require__2(21957),
DOWN: __webpack_require__2(44743),
KEY_DOWN: __webpack_require__2(3771),
KEY_UP: __webpack_require__2(46358),
UP: __webpack_require__2(75674)
};
}
),
/***/
51442: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Events: __webpack_require__2(95922),
KeyboardManager: __webpack_require__2(78970),
KeyboardPlugin: __webpack_require__2(28846),
Key: __webpack_require__2(30472),
KeyCodes: __webpack_require__2(46032),
KeyCombo: __webpack_require__2(87960),
AdvanceKeyCombo: __webpack_require__2(66970),
ProcessKeyCombo: __webpack_require__2(68769),
ResetKeyCombo: __webpack_require__2(92803),
JustDown: __webpack_require__2(90229),
JustUp: __webpack_require__2(38796),
DownDuration: __webpack_require__2(37015),
UpDuration: __webpack_require__2(41170)
};
}
),
/***/
37015: (
/***/
(module2) => {
var DownDuration = function(key, duration) {
if (duration === void 0) {
duration = 50;
}
var current = key.plugin.game.loop.time - key.timeDown;
return key.isDown && current < duration;
};
module2.exports = DownDuration;
}
),
/***/
90229: (
/***/
(module2) => {
var JustDown = function(key) {
if (key._justDown) {
key._justDown = false;
return true;
} else {
return false;
}
};
module2.exports = JustDown;
}
),
/***/
38796: (
/***/
(module2) => {
var JustUp = function(key) {
if (key._justUp) {
key._justUp = false;
return true;
} else {
return false;
}
};
module2.exports = JustUp;
}
),
/***/
30472: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var EventEmitter = __webpack_require__2(50792);
var Events = __webpack_require__2(95922);
var Key = new Class({
Extends: EventEmitter,
initialize: function Key2(plugin, keyCode) {
EventEmitter.call(this);
this.plugin = plugin;
this.keyCode = keyCode;
this.originalEvent = void 0;
this.enabled = true;
this.isDown = false;
this.isUp = true;
this.altKey = false;
this.ctrlKey = false;
this.shiftKey = false;
this.metaKey = false;
this.location = 0;
this.timeDown = 0;
this.duration = 0;
this.timeUp = 0;
this.emitOnRepeat = false;
this.repeats = 0;
this._justDown = false;
this._justUp = false;
this._tick = -1;
},
/**
* Controls if this Key will continuously emit a `down` event while being held down (true),
* or emit the event just once, on first press, and then skip future events (false).
*
* @method Phaser.Input.Keyboard.Key#setEmitOnRepeat
* @since 3.16.0
*
* @param {boolean} value - Emit `down` events on repeated key down actions, or just once?
*
* @return {this} This Key instance.
*/
setEmitOnRepeat: function(value) {
this.emitOnRepeat = value;
return this;
},
/**
* Processes the Key Down action for this Key.
* Called automatically by the Keyboard Plugin.
*
* @method Phaser.Input.Keyboard.Key#onDown
* @fires Phaser.Input.Keyboard.Events#DOWN
* @since 3.16.0
*
* @param {KeyboardEvent} event - The native DOM Keyboard event.
*/
onDown: function(event) {
this.originalEvent = event;
if (!this.enabled) {
return;
}
this.altKey = event.altKey;
this.ctrlKey = event.ctrlKey;
this.shiftKey = event.shiftKey;
this.metaKey = event.metaKey;
this.location = event.location;
this.repeats++;
if (!this.isDown) {
this.isDown = true;
this.isUp = false;
this.timeDown = event.timeStamp;
this.duration = 0;
this._justDown = true;
this._justUp = false;
this.emit(Events.DOWN, this, event);
} else if (this.emitOnRepeat) {
this.emit(Events.DOWN, this, event);
}
},
/**
* Processes the Key Up action for this Key.
* Called automatically by the Keyboard Plugin.
*
* @method Phaser.Input.Keyboard.Key#onUp
* @fires Phaser.Input.Keyboard.Events#UP
* @since 3.16.0
*
* @param {KeyboardEvent} event - The native DOM Keyboard event.
*/
onUp: function(event) {
this.originalEvent = event;
if (!this.enabled) {
return;
}
this.isDown = false;
this.isUp = true;
this.timeUp = event.timeStamp;
this.duration = this.timeUp - this.timeDown;
this.repeats = 0;
this._justDown = false;
this._justUp = true;
this._tick = -1;
this.emit(Events.UP, this, event);
},
/**
* Resets this Key object back to its default un-pressed state.
*
* As of version 3.60.0 it no longer resets the `enabled` or `preventDefault` flags.
*
* @method Phaser.Input.Keyboard.Key#reset
* @since 3.6.0
*
* @return {this} This Key instance.
*/
reset: function() {
this.isDown = false;
this.isUp = true;
this.altKey = false;
this.ctrlKey = false;
this.shiftKey = false;
this.metaKey = false;
this.timeDown = 0;
this.duration = 0;
this.timeUp = 0;
this.repeats = 0;
this._justDown = false;
this._justUp = false;
this._tick = -1;
return this;
},
/**
* Returns the duration, in ms, that the Key has been held down for.
*
* If the key is not currently down it will return zero.
*
* To get the duration the Key was held down for in the previous up-down cycle,
* use the `Key.duration` property value instead.
*
* @method Phaser.Input.Keyboard.Key#getDuration
* @since 3.17.0
*
* @return {number} The duration, in ms, that the Key has been held down for if currently down.
*/
getDuration: function() {
if (this.isDown) {
return this.plugin.game.loop.time - this.timeDown;
} else {
return 0;
}
},
/**
* Removes any bound event handlers and removes local references.
*
* @method Phaser.Input.Keyboard.Key#destroy
* @since 3.16.0
*/
destroy: function() {
this.removeAllListeners();
this.originalEvent = null;
this.plugin = null;
}
});
module2.exports = Key;
}
),
/***/
46032: (
/***/
(module2) => {
var KeyCodes = {
/**
* The BACKSPACE key.
*
* @name Phaser.Input.Keyboard.KeyCodes.BACKSPACE
* @type {number}
* @since 3.0.0
*/
BACKSPACE: 8,
/**
* The TAB key.
*
* @name Phaser.Input.Keyboard.KeyCodes.TAB
* @type {number}
* @since 3.0.0
*/
TAB: 9,
/**
* The ENTER key.
*
* @name Phaser.Input.Keyboard.KeyCodes.ENTER
* @type {number}
* @since 3.0.0
*/
ENTER: 13,
/**
* The SHIFT key.
*
* @name Phaser.Input.Keyboard.KeyCodes.SHIFT
* @type {number}
* @since 3.0.0
*/
SHIFT: 16,
/**
* The CTRL key.
*
* @name Phaser.Input.Keyboard.KeyCodes.CTRL
* @type {number}
* @since 3.0.0
*/
CTRL: 17,
/**
* The ALT key.
*
* @name Phaser.Input.Keyboard.KeyCodes.ALT
* @type {number}
* @since 3.0.0
*/
ALT: 18,
/**
* The PAUSE key.
*
* @name Phaser.Input.Keyboard.KeyCodes.PAUSE
* @type {number}
* @since 3.0.0
*/
PAUSE: 19,
/**
* The CAPS_LOCK key.
*
* @name Phaser.Input.Keyboard.KeyCodes.CAPS_LOCK
* @type {number}
* @since 3.0.0
*/
CAPS_LOCK: 20,
/**
* The ESC key.
*
* @name Phaser.Input.Keyboard.KeyCodes.ESC
* @type {number}
* @since 3.0.0
*/
ESC: 27,
/**
* The SPACE key.
*
* @name Phaser.Input.Keyboard.KeyCodes.SPACE
* @type {number}
* @since 3.0.0
*/
SPACE: 32,
/**
* The PAGE_UP key.
*
* @name Phaser.Input.Keyboard.KeyCodes.PAGE_UP
* @type {number}
* @since 3.0.0
*/
PAGE_UP: 33,
/**
* The PAGE_DOWN key.
*
* @name Phaser.Input.Keyboard.KeyCodes.PAGE_DOWN
* @type {number}
* @since 3.0.0
*/
PAGE_DOWN: 34,
/**
* The END key.
*
* @name Phaser.Input.Keyboard.KeyCodes.END
* @type {number}
* @since 3.0.0
*/
END: 35,
/**
* The HOME key.
*
* @name Phaser.Input.Keyboard.KeyCodes.HOME
* @type {number}
* @since 3.0.0
*/
HOME: 36,
/**
* The LEFT key.
*
* @name Phaser.Input.Keyboard.KeyCodes.LEFT
* @type {number}
* @since 3.0.0
*/
LEFT: 37,
/**
* The UP key.
*
* @name Phaser.Input.Keyboard.KeyCodes.UP
* @type {number}
* @since 3.0.0
*/
UP: 38,
/**
* The RIGHT key.
*
* @name Phaser.Input.Keyboard.KeyCodes.RIGHT
* @type {number}
* @since 3.0.0
*/
RIGHT: 39,
/**
* The DOWN key.
*
* @name Phaser.Input.Keyboard.KeyCodes.DOWN
* @type {number}
* @since 3.0.0
*/
DOWN: 40,
/**
* The PRINT_SCREEN key.
*
* @name Phaser.Input.Keyboard.KeyCodes.PRINT_SCREEN
* @type {number}
* @since 3.0.0
*/
PRINT_SCREEN: 42,
/**
* The INSERT key.
*
* @name Phaser.Input.Keyboard.KeyCodes.INSERT
* @type {number}
* @since 3.0.0
*/
INSERT: 45,
/**
* The DELETE key.
*
* @name Phaser.Input.Keyboard.KeyCodes.DELETE
* @type {number}
* @since 3.0.0
*/
DELETE: 46,
/**
* The ZERO key.
*
* @name Phaser.Input.Keyboard.KeyCodes.ZERO
* @type {number}
* @since 3.0.0
*/
ZERO: 48,
/**
* The ONE key.
*
* @name Phaser.Input.Keyboard.KeyCodes.ONE
* @type {number}
* @since 3.0.0
*/
ONE: 49,
/**
* The TWO key.
*
* @name Phaser.Input.Keyboard.KeyCodes.TWO
* @type {number}
* @since 3.0.0
*/
TWO: 50,
/**
* The THREE key.
*
* @name Phaser.Input.Keyboard.KeyCodes.THREE
* @type {number}
* @since 3.0.0
*/
THREE: 51,
/**
* The FOUR key.
*
* @name Phaser.Input.Keyboard.KeyCodes.FOUR
* @type {number}
* @since 3.0.0
*/
FOUR: 52,
/**
* The FIVE key.
*
* @name Phaser.Input.Keyboard.KeyCodes.FIVE
* @type {number}
* @since 3.0.0
*/
FIVE: 53,
/**
* The SIX key.
*
* @name Phaser.Input.Keyboard.KeyCodes.SIX
* @type {number}
* @since 3.0.0
*/
SIX: 54,
/**
* The SEVEN key.
*
* @name Phaser.Input.Keyboard.KeyCodes.SEVEN
* @type {number}
* @since 3.0.0
*/
SEVEN: 55,
/**
* The EIGHT key.
*
* @name Phaser.Input.Keyboard.KeyCodes.EIGHT
* @type {number}
* @since 3.0.0
*/
EIGHT: 56,
/**
* The NINE key.
*
* @name Phaser.Input.Keyboard.KeyCodes.NINE
* @type {number}
* @since 3.0.0
*/
NINE: 57,
/**
* The NUMPAD_ZERO key.
*
* @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_ZERO
* @type {number}
* @since 3.0.0
*/
NUMPAD_ZERO: 96,
/**
* The NUMPAD_ONE key.
*
* @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_ONE
* @type {number}
* @since 3.0.0
*/
NUMPAD_ONE: 97,
/**
* The NUMPAD_TWO key.
*
* @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_TWO
* @type {number}
* @since 3.0.0
*/
NUMPAD_TWO: 98,
/**
* The NUMPAD_THREE key.
*
* @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_THREE
* @type {number}
* @since 3.0.0
*/
NUMPAD_THREE: 99,
/**
* The NUMPAD_FOUR key.
*
* @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_FOUR
* @type {number}
* @since 3.0.0
*/
NUMPAD_FOUR: 100,
/**
* The NUMPAD_FIVE key.
*
* @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_FIVE
* @type {number}
* @since 3.0.0
*/
NUMPAD_FIVE: 101,
/**
* The NUMPAD_SIX key.
*
* @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_SIX
* @type {number}
* @since 3.0.0
*/
NUMPAD_SIX: 102,
/**
* The NUMPAD_SEVEN key.
*
* @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_SEVEN
* @type {number}
* @since 3.0.0
*/
NUMPAD_SEVEN: 103,
/**
* The NUMPAD_EIGHT key.
*
* @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_EIGHT
* @type {number}
* @since 3.0.0
*/
NUMPAD_EIGHT: 104,
/**
* The NUMPAD_NINE key.
*
* @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_NINE
* @type {number}
* @since 3.0.0
*/
NUMPAD_NINE: 105,
/**
* The Numpad Addition (+) key.
*
* @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_ADD
* @type {number}
* @since 3.21.0
*/
NUMPAD_ADD: 107,
/**
* The Numpad Subtraction (-) key.
*
* @name Phaser.Input.Keyboard.KeyCodes.NUMPAD_SUBTRACT
* @type {number}
* @since 3.21.0
*/
NUMPAD_SUBTRACT: 109,
/**
* The A key.
*
* @name Phaser.Input.Keyboard.KeyCodes.A
* @type {number}
* @since 3.0.0
*/
A: 65,
/**
* The B key.
*
* @name Phaser.Input.Keyboard.KeyCodes.B
* @type {number}
* @since 3.0.0
*/
B: 66,
/**
* The C key.
*
* @name Phaser.Input.Keyboard.KeyCodes.C
* @type {number}
* @since 3.0.0
*/
C: 67,
/**
* The D key.
*
* @name Phaser.Input.Keyboard.KeyCodes.D
* @type {number}
* @since 3.0.0
*/
D: 68,
/**
* The E key.
*
* @name Phaser.Input.Keyboard.KeyCodes.E
* @type {number}
* @since 3.0.0
*/
E: 69,
/**
* The F key.
*
* @name Phaser.Input.Keyboard.KeyCodes.F
* @type {number}
* @since 3.0.0
*/
F: 70,
/**
* The G key.
*
* @name Phaser.Input.Keyboard.KeyCodes.G
* @type {number}
* @since 3.0.0
*/
G: 71,
/**
* The H key.
*
* @name Phaser.Input.Keyboard.KeyCodes.H
* @type {number}
* @since 3.0.0
*/
H: 72,
/**
* The I key.
*
* @name Phaser.Input.Keyboard.KeyCodes.I
* @type {number}
* @since 3.0.0
*/
I: 73,
/**
* The J key.
*
* @name Phaser.Input.Keyboard.KeyCodes.J
* @type {number}
* @since 3.0.0
*/
J: 74,
/**
* The K key.
*
* @name Phaser.Input.Keyboard.KeyCodes.K
* @type {number}
* @since 3.0.0
*/
K: 75,
/**
* The L key.
*
* @name Phaser.Input.Keyboard.KeyCodes.L
* @type {number}
* @since 3.0.0
*/
L: 76,
/**
* The M key.
*
* @name Phaser.Input.Keyboard.KeyCodes.M
* @type {number}
* @since 3.0.0
*/
M: 77,
/**
* The N key.
*
* @name Phaser.Input.Keyboard.KeyCodes.N
* @type {number}
* @since 3.0.0
*/
N: 78,
/**
* The O key.
*
* @name Phaser.Input.Keyboard.KeyCodes.O
* @type {number}
* @since 3.0.0
*/
O: 79,
/**
* The P key.
*
* @name Phaser.Input.Keyboard.KeyCodes.P
* @type {number}
* @since 3.0.0
*/
P: 80,
/**
* The Q key.
*
* @name Phaser.Input.Keyboard.KeyCodes.Q
* @type {number}
* @since 3.0.0
*/
Q: 81,
/**
* The R key.
*
* @name Phaser.Input.Keyboard.KeyCodes.R
* @type {number}
* @since 3.0.0
*/
R: 82,
/**
* The S key.
*
* @name Phaser.Input.Keyboard.KeyCodes.S
* @type {number}
* @since 3.0.0
*/
S: 83,
/**
* The T key.
*
* @name Phaser.Input.Keyboard.KeyCodes.T
* @type {number}
* @since 3.0.0
*/
T: 84,
/**
* The U key.
*
* @name Phaser.Input.Keyboard.KeyCodes.U
* @type {number}
* @since 3.0.0
*/
U: 85,
/**
* The V key.
*
* @name Phaser.Input.Keyboard.KeyCodes.V
* @type {number}
* @since 3.0.0
*/
V: 86,
/**
* The W key.
*
* @name Phaser.Input.Keyboard.KeyCodes.W
* @type {number}
* @since 3.0.0
*/
W: 87,
/**
* The X key.
*
* @name Phaser.Input.Keyboard.KeyCodes.X
* @type {number}
* @since 3.0.0
*/
X: 88,
/**
* The Y key.
*
* @name Phaser.Input.Keyboard.KeyCodes.Y
* @type {number}
* @since 3.0.0
*/
Y: 89,
/**
* The Z key.
*
* @name Phaser.Input.Keyboard.KeyCodes.Z
* @type {number}
* @since 3.0.0
*/
Z: 90,
/**
* The F1 key.
*
* @name Phaser.Input.Keyboard.KeyCodes.F1
* @type {number}
* @since 3.0.0
*/
F1: 112,
/**
* The F2 key.
*
* @name Phaser.Input.Keyboard.KeyCodes.F2
* @type {number}
* @since 3.0.0
*/
F2: 113,
/**
* The F3 key.
*
* @name Phaser.Input.Keyboard.KeyCodes.F3
* @type {number}
* @since 3.0.0
*/
F3: 114,
/**
* The F4 key.
*
* @name Phaser.Input.Keyboard.KeyCodes.F4
* @type {number}
* @since 3.0.0
*/
F4: 115,
/**
* The F5 key.
*
* @name Phaser.Input.Keyboard.KeyCodes.F5
* @type {number}
* @since 3.0.0
*/
F5: 116,
/**
* The F6 key.
*
* @name Phaser.Input.Keyboard.KeyCodes.F6
* @type {number}
* @since 3.0.0
*/
F6: 117,
/**
* The F7 key.
*
* @name Phaser.Input.Keyboard.KeyCodes.F7
* @type {number}
* @since 3.0.0
*/
F7: 118,
/**
* The F8 key.
*
* @name Phaser.Input.Keyboard.KeyCodes.F8
* @type {number}
* @since 3.0.0
*/
F8: 119,
/**
* The F9 key.
*
* @name Phaser.Input.Keyboard.KeyCodes.F9
* @type {number}
* @since 3.0.0
*/
F9: 120,
/**
* The F10 key.
*
* @name Phaser.Input.Keyboard.KeyCodes.F10
* @type {number}
* @since 3.0.0
*/
F10: 121,
/**
* The F11 key.
*
* @name Phaser.Input.Keyboard.KeyCodes.F11
* @type {number}
* @since 3.0.0
*/
F11: 122,
/**
* The F12 key.
*
* @name Phaser.Input.Keyboard.KeyCodes.F12
* @type {number}
* @since 3.0.0
*/
F12: 123,
/**
* The SEMICOLON key.
*
* @name Phaser.Input.Keyboard.KeyCodes.SEMICOLON
* @type {number}
* @since 3.0.0
*/
SEMICOLON: 186,
/**
* The PLUS key.
*
* @name Phaser.Input.Keyboard.KeyCodes.PLUS
* @type {number}
* @since 3.0.0
*/
PLUS: 187,
/**
* The COMMA key.
*
* @name Phaser.Input.Keyboard.KeyCodes.COMMA
* @type {number}
* @since 3.0.0
*/
COMMA: 188,
/**
* The MINUS key.
*
* @name Phaser.Input.Keyboard.KeyCodes.MINUS
* @type {number}
* @since 3.0.0
*/
MINUS: 189,
/**
* The PERIOD key.
*
* @name Phaser.Input.Keyboard.KeyCodes.PERIOD
* @type {number}
* @since 3.0.0
*/
PERIOD: 190,
/**
* The FORWARD_SLASH key.
*
* @name Phaser.Input.Keyboard.KeyCodes.FORWARD_SLASH
* @type {number}
* @since 3.0.0
*/
FORWARD_SLASH: 191,
/**
* The BACK_SLASH key.
*
* @name Phaser.Input.Keyboard.KeyCodes.BACK_SLASH
* @type {number}
* @since 3.0.0
*/
BACK_SLASH: 220,
/**
* The QUOTES key.
*
* @name Phaser.Input.Keyboard.KeyCodes.QUOTES
* @type {number}
* @since 3.0.0
*/
QUOTES: 222,
/**
* The BACKTICK key.
*
* @name Phaser.Input.Keyboard.KeyCodes.BACKTICK
* @type {number}
* @since 3.0.0
*/
BACKTICK: 192,
/**
* The OPEN_BRACKET key.
*
* @name Phaser.Input.Keyboard.KeyCodes.OPEN_BRACKET
* @type {number}
* @since 3.0.0
*/
OPEN_BRACKET: 219,
/**
* The CLOSED_BRACKET key.
*
* @name Phaser.Input.Keyboard.KeyCodes.CLOSED_BRACKET
* @type {number}
* @since 3.0.0
*/
CLOSED_BRACKET: 221,
/**
* The SEMICOLON_FIREFOX key.
*
* @name Phaser.Input.Keyboard.KeyCodes.SEMICOLON_FIREFOX
* @type {number}
* @since 3.0.0
*/
SEMICOLON_FIREFOX: 59,
/**
* The COLON key.
*
* @name Phaser.Input.Keyboard.KeyCodes.COLON
* @type {number}
* @since 3.0.0
*/
COLON: 58,
/**
* The COMMA_FIREFOX_WINDOWS key.
*
* @name Phaser.Input.Keyboard.KeyCodes.COMMA_FIREFOX_WINDOWS
* @type {number}
* @since 3.0.0
*/
COMMA_FIREFOX_WINDOWS: 60,
/**
* The COMMA_FIREFOX key.
*
* @name Phaser.Input.Keyboard.KeyCodes.COMMA_FIREFOX
* @type {number}
* @since 3.0.0
*/
COMMA_FIREFOX: 62,
/**
* The BRACKET_RIGHT_FIREFOX key.
*
* @name Phaser.Input.Keyboard.KeyCodes.BRACKET_RIGHT_FIREFOX
* @type {number}
* @since 3.0.0
*/
BRACKET_RIGHT_FIREFOX: 174,
/**
* The BRACKET_LEFT_FIREFOX key.
*
* @name Phaser.Input.Keyboard.KeyCodes.BRACKET_LEFT_FIREFOX
* @type {number}
* @since 3.0.0
*/
BRACKET_LEFT_FIREFOX: 175
};
module2.exports = KeyCodes;
}
),
/***/
74600: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var KeyCodes = __webpack_require__2(46032);
var KeyMap = {};
for (var key in KeyCodes) {
KeyMap[KeyCodes[key]] = key;
}
module2.exports = KeyMap;
}
),
/***/
41170: (
/***/
(module2) => {
var UpDuration = function(key, duration) {
if (duration === void 0) {
duration = 50;
}
var current = key.plugin.game.loop.time - key.timeUp;
return key.isUp && current < duration;
};
module2.exports = UpDuration;
}
),
/***/
85098: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Features = __webpack_require__2(89357);
var InputEvents = __webpack_require__2(8214);
var NOOP = __webpack_require__2(29747);
var MouseManager = new Class({
initialize: function MouseManager2(inputManager) {
this.manager = inputManager;
this.preventDefaultDown = true;
this.preventDefaultUp = true;
this.preventDefaultMove = true;
this.preventDefaultWheel = false;
this.enabled = false;
this.target;
this.locked = false;
this.onMouseMove = NOOP;
this.onMouseDown = NOOP;
this.onMouseUp = NOOP;
this.onMouseDownWindow = NOOP;
this.onMouseUpWindow = NOOP;
this.onMouseOver = NOOP;
this.onMouseOut = NOOP;
this.onMouseWheel = NOOP;
this.pointerLockChange = NOOP;
this.isTop = true;
inputManager.events.once(InputEvents.MANAGER_BOOT, this.boot, this);
},
/**
* The Touch Manager boot process.
*
* @method Phaser.Input.Mouse.MouseManager#boot
* @private
* @since 3.0.0
*/
boot: function() {
var config = this.manager.config;
this.enabled = config.inputMouse;
this.target = config.inputMouseEventTarget;
this.passive = config.inputMousePassive;
this.preventDefaultDown = config.inputMousePreventDefaultDown;
this.preventDefaultUp = config.inputMousePreventDefaultUp;
this.preventDefaultMove = config.inputMousePreventDefaultMove;
this.preventDefaultWheel = config.inputMousePreventDefaultWheel;
if (!this.target) {
this.target = this.manager.game.canvas;
} else if (typeof this.target === "string") {
this.target = document.getElementById(this.target);
}
if (config.disableContextMenu) {
this.disableContextMenu();
}
if (this.enabled && this.target) {
this.startListeners();
}
},
/**
* Attempts to disable the context menu from appearing if you right-click on the game canvas, or specified input target.
*
* Works by listening for the `contextmenu` event and prevent defaulting it.
*
* Use this if you need to enable right-button mouse support in your game, and the context
* menu keeps getting in the way.
*
* @method Phaser.Input.Mouse.MouseManager#disableContextMenu
* @since 3.0.0
*
* @return {this} This Mouse Manager instance.
*/
disableContextMenu: function() {
this.target.addEventListener("contextmenu", function(event) {
event.preventDefault();
return false;
});
return this;
},
/**
* If the browser supports it, you can request that the pointer be locked to the browser window.
*
* This is classically known as 'FPS controls', where the pointer can't leave the browser until
* the user presses an exit key.
*
* If the browser successfully enters a locked state, a `POINTER_LOCK_CHANGE_EVENT` will be dispatched,
* from the games Input Manager, with an `isPointerLocked` property.
*
* It is important to note that pointer lock can only be enabled after an 'engagement gesture',
* see: https://w3c.github.io/pointerlock/#dfn-engagement-gesture.
*
* Note for Firefox: There is a bug in certain Firefox releases that cause native DOM events like
* `mousemove` to fire continuously when in pointer lock mode. You can get around this by setting
* `this.preventDefaultMove` to `false` in this class. You may also need to do the same for
* `preventDefaultDown` and/or `preventDefaultUp`. Please test combinations of these if you encounter
* the error.
*
* @method Phaser.Input.Mouse.MouseManager#requestPointerLock
* @since 3.0.0
*/
requestPointerLock: function() {
if (Features.pointerLock) {
var element = this.target;
element.requestPointerLock = element.requestPointerLock || element.mozRequestPointerLock || element.webkitRequestPointerLock;
element.requestPointerLock();
}
},
/**
* If the browser supports pointer lock, this will request that the pointer lock is released. If
* the browser successfully enters a locked state, a 'POINTER_LOCK_CHANGE_EVENT' will be
* dispatched - from the game's input manager - with an `isPointerLocked` property.
*
* @method Phaser.Input.Mouse.MouseManager#releasePointerLock
* @since 3.0.0
*/
releasePointerLock: function() {
if (Features.pointerLock) {
document.exitPointerLock = document.exitPointerLock || document.mozExitPointerLock || document.webkitExitPointerLock;
document.exitPointerLock();
}
},
/**
* Starts the Mouse Event listeners running.
* This is called automatically and does not need to be manually invoked.
*
* @method Phaser.Input.Mouse.MouseManager#startListeners
* @since 3.0.0
*/
startListeners: function() {
var target = this.target;
if (!target) {
return;
}
var _this = this;
var manager = this.manager;
var canvas = manager.canvas;
var autoFocus = window && window.focus && manager.game.config.autoFocus;
this.onMouseMove = function(event) {
if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) {
manager.onMouseMove(event);
if (_this.preventDefaultMove) {
event.preventDefault();
}
}
};
this.onMouseDown = function(event) {
if (autoFocus) {
window.focus();
}
if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) {
manager.onMouseDown(event);
if (_this.preventDefaultDown && event.target === canvas) {
event.preventDefault();
}
}
};
this.onMouseDownWindow = function(event) {
if (event.sourceCapabilities && event.sourceCapabilities.firesTouchEvents) {
return;
}
if (!event.defaultPrevented && _this.enabled && manager && manager.enabled && event.target !== canvas) {
manager.onMouseDown(event);
}
};
this.onMouseUp = function(event) {
if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) {
manager.onMouseUp(event);
if (_this.preventDefaultUp && event.target === canvas) {
event.preventDefault();
}
}
};
this.onMouseUpWindow = function(event) {
if (event.sourceCapabilities && event.sourceCapabilities.firesTouchEvents) {
return;
}
if (!event.defaultPrevented && _this.enabled && manager && manager.enabled && event.target !== canvas) {
manager.onMouseUp(event);
}
};
this.onMouseOver = function(event) {
if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) {
manager.setCanvasOver(event);
}
};
this.onMouseOut = function(event) {
if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) {
manager.setCanvasOut(event);
}
};
this.onMouseWheel = function(event) {
if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) {
manager.onMouseWheel(event);
}
if (_this.preventDefaultWheel && event.target === canvas) {
event.preventDefault();
}
};
var passive = { passive: true };
target.addEventListener("mousemove", this.onMouseMove);
target.addEventListener("mousedown", this.onMouseDown);
target.addEventListener("mouseup", this.onMouseUp);
target.addEventListener("mouseover", this.onMouseOver, passive);
target.addEventListener("mouseout", this.onMouseOut, passive);
if (this.preventDefaultWheel) {
target.addEventListener("wheel", this.onMouseWheel, { passive: false });
} else {
target.addEventListener("wheel", this.onMouseWheel, passive);
}
if (window && manager.game.config.inputWindowEvents) {
try {
window.top.addEventListener("mousedown", this.onMouseDownWindow, passive);
window.top.addEventListener("mouseup", this.onMouseUpWindow, passive);
} catch (exception) {
window.addEventListener("mousedown", this.onMouseDownWindow, passive);
window.addEventListener("mouseup", this.onMouseUpWindow, passive);
this.isTop = false;
}
}
if (Features.pointerLock) {
this.pointerLockChange = function(event) {
var element = _this.target;
_this.locked = document.pointerLockElement === element || document.mozPointerLockElement === element || document.webkitPointerLockElement === element ? true : false;
manager.onPointerLockChange(event);
};
document.addEventListener("pointerlockchange", this.pointerLockChange, true);
document.addEventListener("mozpointerlockchange", this.pointerLockChange, true);
document.addEventListener("webkitpointerlockchange", this.pointerLockChange, true);
}
this.enabled = true;
},
/**
* Stops the Mouse Event listeners.
* This is called automatically and does not need to be manually invoked.
*
* @method Phaser.Input.Mouse.MouseManager#stopListeners
* @since 3.0.0
*/
stopListeners: function() {
var target = this.target;
target.removeEventListener("mousemove", this.onMouseMove);
target.removeEventListener("mousedown", this.onMouseDown);
target.removeEventListener("mouseup", this.onMouseUp);
target.removeEventListener("mouseover", this.onMouseOver);
target.removeEventListener("mouseout", this.onMouseOut);
if (window) {
target = this.isTop ? window.top : window;
target.removeEventListener("mousedown", this.onMouseDownWindow);
target.removeEventListener("mouseup", this.onMouseUpWindow);
}
if (Features.pointerLock) {
document.removeEventListener("pointerlockchange", this.pointerLockChange, true);
document.removeEventListener("mozpointerlockchange", this.pointerLockChange, true);
document.removeEventListener("webkitpointerlockchange", this.pointerLockChange, true);
}
},
/**
* Destroys this Mouse Manager instance.
*
* @method Phaser.Input.Mouse.MouseManager#destroy
* @since 3.0.0
*/
destroy: function() {
this.stopListeners();
this.target = null;
this.enabled = false;
this.manager = null;
}
});
module2.exports = MouseManager;
}
),
/***/
87078: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
MouseManager: __webpack_require__2(85098)
};
}
),
/***/
36210: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var InputEvents = __webpack_require__2(8214);
var NOOP = __webpack_require__2(29747);
var TouchManager = new Class({
initialize: function TouchManager2(inputManager) {
this.manager = inputManager;
this.capture = true;
this.enabled = false;
this.target;
this.onTouchStart = NOOP;
this.onTouchStartWindow = NOOP;
this.onTouchMove = NOOP;
this.onTouchEnd = NOOP;
this.onTouchEndWindow = NOOP;
this.onTouchCancel = NOOP;
this.onTouchCancelWindow = NOOP;
this.isTop = true;
inputManager.events.once(InputEvents.MANAGER_BOOT, this.boot, this);
},
/**
* The Touch Manager boot process.
*
* @method Phaser.Input.Touch.TouchManager#boot
* @private
* @since 3.0.0
*/
boot: function() {
var config = this.manager.config;
this.enabled = config.inputTouch;
this.target = config.inputTouchEventTarget;
this.capture = config.inputTouchCapture;
if (!this.target) {
this.target = this.manager.game.canvas;
} else if (typeof this.target === "string") {
this.target = document.getElementById(this.target);
}
if (config.disableContextMenu) {
this.disableContextMenu();
}
if (this.enabled && this.target) {
this.startListeners();
}
},
/**
* Attempts to disable the context menu from appearing if you touch-hold on the browser.
*
* Works by listening for the `contextmenu` event and prevent defaulting it.
*
* Use this if you need to disable the OS context menu on mobile.
*
* @method Phaser.Input.Touch.TouchManager#disableContextMenu
* @since 3.20.0
*
* @return {this} This Touch Manager instance.
*/
disableContextMenu: function() {
this.target.addEventListener("contextmenu", function(event) {
event.preventDefault();
return false;
});
return this;
},
/**
* Starts the Touch Event listeners running as long as an input target is set.
*
* This method is called automatically if Touch Input is enabled in the game config,
* which it is by default. However, you can call it manually should you need to
* delay input capturing until later in the game.
*
* @method Phaser.Input.Touch.TouchManager#startListeners
* @since 3.0.0
*/
startListeners: function() {
var target = this.target;
if (!target) {
return;
}
var _this = this;
var manager = this.manager;
var canvas = manager.canvas;
var autoFocus = window && window.focus && manager.game.config.autoFocus;
this.onTouchMove = function(event) {
if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) {
manager.onTouchMove(event);
if (_this.capture && event.cancelable) {
event.preventDefault();
}
}
};
this.onTouchStart = function(event) {
if (autoFocus) {
window.focus();
}
if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) {
manager.onTouchStart(event);
if (_this.capture && event.cancelable && event.target === canvas) {
event.preventDefault();
}
}
};
this.onTouchStartWindow = function(event) {
if (!event.defaultPrevented && _this.enabled && manager && manager.enabled && event.target !== canvas) {
manager.onTouchStart(event);
}
};
this.onTouchEnd = function(event) {
if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) {
manager.onTouchEnd(event);
if (_this.capture && event.cancelable && event.target === canvas) {
event.preventDefault();
}
}
};
this.onTouchEndWindow = function(event) {
if (!event.defaultPrevented && _this.enabled && manager && manager.enabled && event.target !== canvas) {
manager.onTouchEnd(event);
}
};
this.onTouchCancel = function(event) {
if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) {
manager.onTouchCancel(event);
if (_this.capture) {
event.preventDefault();
}
}
};
this.onTouchCancelWindow = function(event) {
if (!event.defaultPrevented && _this.enabled && manager && manager.enabled) {
manager.onTouchCancel(event);
}
};
var capture = this.capture;
var passive = { passive: true };
var nonPassive = { passive: false };
target.addEventListener("touchstart", this.onTouchStart, capture ? nonPassive : passive);
target.addEventListener("touchmove", this.onTouchMove, capture ? nonPassive : passive);
target.addEventListener("touchend", this.onTouchEnd, capture ? nonPassive : passive);
target.addEventListener("touchcancel", this.onTouchCancel, capture ? nonPassive : passive);
if (window && manager.game.config.inputWindowEvents) {
try {
window.top.addEventListener("touchstart", this.onTouchStartWindow, nonPassive);
window.top.addEventListener("touchend", this.onTouchEndWindow, nonPassive);
window.top.addEventListener("touchcancel", this.onTouchCancelWindow, nonPassive);
} catch (exception) {
window.addEventListener("touchstart", this.onTouchStartWindow, nonPassive);
window.addEventListener("touchend", this.onTouchEndWindow, nonPassive);
window.addEventListener("touchcancel", this.onTouchCancelWindow, nonPassive);
this.isTop = false;
}
}
this.enabled = true;
},
/**
* Stops the Touch Event listeners.
* This is called automatically and does not need to be manually invoked.
*
* @method Phaser.Input.Touch.TouchManager#stopListeners
* @since 3.0.0
*/
stopListeners: function() {
var target = this.target;
target.removeEventListener("touchstart", this.onTouchStart);
target.removeEventListener("touchmove", this.onTouchMove);
target.removeEventListener("touchend", this.onTouchEnd);
target.removeEventListener("touchcancel", this.onTouchCancel);
if (window) {
target = this.isTop ? window.top : window;
target.removeEventListener("touchstart", this.onTouchStartWindow);
target.removeEventListener("touchend", this.onTouchEndWindow);
target.removeEventListener("touchcancel", this.onTouchCancelWindow);
}
},
/**
* Destroys this Touch Manager instance.
*
* @method Phaser.Input.Touch.TouchManager#destroy
* @since 3.0.0
*/
destroy: function() {
this.stopListeners();
this.target = null;
this.enabled = false;
this.manager = null;
}
});
module2.exports = TouchManager;
}
),
/***/
95618: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
TouchManager: __webpack_require__2(36210)
};
}
),
/***/
41299: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(23906);
var Events = __webpack_require__2(54899);
var GetFastValue = __webpack_require__2(95540);
var GetURL = __webpack_require__2(98356);
var MergeXHRSettings = __webpack_require__2(3374);
var XHRLoader = __webpack_require__2(84376);
var XHRSettings = __webpack_require__2(92638);
var File = new Class({
initialize: function File2(loader, fileConfig) {
this.loader = loader;
this.cache = GetFastValue(fileConfig, "cache", false);
this.type = GetFastValue(fileConfig, "type", false);
if (!this.type) {
throw new Error("Invalid File type: " + this.type);
}
this.key = GetFastValue(fileConfig, "key", false);
var loadKey = this.key;
if (loader.prefix && loader.prefix !== "") {
this.key = loader.prefix + loadKey;
}
if (!this.key) {
throw new Error("Invalid File key: " + this.key);
}
var url = GetFastValue(fileConfig, "url");
if (url === void 0) {
url = loader.path + loadKey + "." + GetFastValue(fileConfig, "extension", "");
} else if (typeof url === "string" && !url.match(/^(?:blob:|data:|capacitor:\/\/|http:\/\/|https:\/\/|\/\/)/)) {
url = loader.path + url;
}
this.url = url;
this.src = "";
this.xhrSettings = XHRSettings(GetFastValue(fileConfig, "responseType", void 0));
if (GetFastValue(fileConfig, "xhrSettings", false)) {
this.xhrSettings = MergeXHRSettings(this.xhrSettings, GetFastValue(fileConfig, "xhrSettings", {}));
}
this.xhrLoader = null;
this.state = typeof this.url === "function" ? CONST.FILE_POPULATED : CONST.FILE_PENDING;
this.bytesTotal = 0;
this.bytesLoaded = -1;
this.percentComplete = -1;
this.crossOrigin = void 0;
this.data = void 0;
this.config = GetFastValue(fileConfig, "config", {});
this.multiFile;
this.linkFile;
this.base64 = typeof url === "string" && url.indexOf("data:") === 0;
this.retryAttempts = GetFastValue(fileConfig, "maxRetries", loader.maxRetries);
},
/**
* Links this File with another, so they depend upon each other for loading and processing.
*
* @method Phaser.Loader.File#setLink
* @since 3.7.0
*
* @param {Phaser.Loader.File} fileB - The file to link to this one.
*/
setLink: function(fileB) {
this.linkFile = fileB;
fileB.linkFile = this;
},
/**
* Resets the XHRLoader instance this file is using.
*
* @method Phaser.Loader.File#resetXHR
* @since 3.0.0
*/
resetXHR: function() {
if (this.xhrLoader) {
this.xhrLoader.onload = void 0;
this.xhrLoader.onerror = void 0;
this.xhrLoader.onprogress = void 0;
}
},
/**
* Called by the Loader, starts the actual file downloading.
* During the load the methods onLoad, onError and onProgress are called, based on the XHR events.
* You shouldn't normally call this method directly, it's meant to be invoked by the Loader.
*
* @method Phaser.Loader.File#load
* @since 3.0.0
*/
load: function() {
if (this.state === CONST.FILE_POPULATED) {
this.loader.nextFile(this, true);
} else {
this.state = CONST.FILE_LOADING;
this.src = GetURL(this, this.loader.baseURL);
if (!this.src) {
throw new Error("URL Error in File: " + this.key + " from: " + this.url);
}
if (this.src.indexOf("data:") === 0) {
this.base64 = true;
}
this.xhrLoader = XHRLoader(this, this.loader.xhr);
}
},
/**
* Called when the file finishes loading, is sent a DOM ProgressEvent.
*
* @method Phaser.Loader.File#onLoad
* @since 3.0.0
*
* @param {XMLHttpRequest} xhr - The XMLHttpRequest that caused this onload event.
* @param {ProgressEvent} event - The DOM ProgressEvent that resulted from this load.
*/
onLoad: function(xhr, event) {
var isLocalFile = xhr.responseURL && this.loader.localSchemes.some(function(scheme) {
return xhr.responseURL.indexOf(scheme) === 0;
});
var localFileOk = isLocalFile && event.target.status === 0;
var success = !(event.target && event.target.status !== 200) || localFileOk;
if (xhr.readyState === 4 && xhr.status >= 400 && xhr.status <= 599) {
success = false;
}
this.state = CONST.FILE_LOADED;
this.resetXHR();
this.loader.nextFile(this, success);
},
/**
* Called by the XHRLoader if it was given a File with base64 data to load.
*
* @method Phaser.Loader.File#onBase64Load
* @since 3.80.0
*
* @param {XMLHttpRequest} xhr - The FakeXHR object containing the decoded base64 data.
*/
onBase64Load: function(xhr) {
this.xhrLoader = xhr;
this.state = CONST.FILE_LOADED;
this.percentComplete = 1;
this.loader.emit(Events.FILE_PROGRESS, this, this.percentComplete);
this.loader.nextFile(this, true);
},
/**
* Called if the file errors while loading, is sent a DOM ProgressEvent.
*
* @method Phaser.Loader.File#onError
* @since 3.0.0
*
* @param {XMLHttpRequest} xhr - The XMLHttpRequest that caused this onload event.
* @param {ProgressEvent} event - The DOM ProgressEvent that resulted from this error.
*/
onError: function() {
this.resetXHR();
if (this.retryAttempts > 0) {
this.retryAttempts--;
this.load();
} else {
this.loader.nextFile(this, false);
}
},
/**
* Called during the file load progress. Is sent a DOM ProgressEvent.
*
* @method Phaser.Loader.File#onProgress
* @fires Phaser.Loader.Events#FILE_PROGRESS
* @since 3.0.0
*
* @param {ProgressEvent} event - The DOM ProgressEvent.
*/
onProgress: function(event) {
if (event.lengthComputable) {
this.bytesLoaded = event.loaded;
this.bytesTotal = event.total;
this.percentComplete = Math.min(this.bytesLoaded / this.bytesTotal, 1);
this.loader.emit(Events.FILE_PROGRESS, this, this.percentComplete);
}
},
/**
* Usually overridden by the FileTypes and is called by Loader.nextFile.
* This method controls what extra work this File does with its loaded data, for example a JSON file will parse itself during this stage.
*
* @method Phaser.Loader.File#onProcess
* @since 3.0.0
*/
onProcess: function() {
this.state = CONST.FILE_PROCESSING;
this.onProcessComplete();
},
/**
* Called when the File has completed processing.
* Checks on the state of its multifile, if set.
*
* @method Phaser.Loader.File#onProcessComplete
* @since 3.7.0
*/
onProcessComplete: function() {
this.state = CONST.FILE_COMPLETE;
if (this.multiFile) {
this.multiFile.onFileComplete(this);
}
this.loader.fileProcessComplete(this);
},
/**
* Called when the File has completed processing but it generated an error.
* Checks on the state of its multifile, if set.
*
* @method Phaser.Loader.File#onProcessError
* @since 3.7.0
*/
onProcessError: function() {
console.error('Failed to process file: %s "%s"', this.type, this.key);
this.state = CONST.FILE_ERRORED;
if (this.multiFile) {
this.multiFile.onFileFailed(this);
}
this.loader.fileProcessComplete(this);
},
/**
* Checks if a key matching the one used by this file exists in the target Cache or not.
* This is called automatically by the LoaderPlugin to decide if the file can be safely
* loaded or will conflict.
*
* @method Phaser.Loader.File#hasCacheConflict
* @since 3.7.0
*
* @return {boolean} `true` if adding this file will cause a conflict, otherwise `false`.
*/
hasCacheConflict: function() {
return this.cache && this.cache.exists(this.key);
},
/**
* Adds this file to its target cache upon successful loading and processing.
* This method is often overridden by specific file types.
*
* @method Phaser.Loader.File#addToCache
* @since 3.7.0
*/
addToCache: function() {
if (this.cache && this.data) {
this.cache.add(this.key, this.data);
}
},
/**
* Called once the file has been added to its cache and is now ready for deletion from the Loader.
* It will emit a `filecomplete` event from the LoaderPlugin.
*
* @method Phaser.Loader.File#pendingDestroy
* @fires Phaser.Loader.Events#FILE_COMPLETE
* @fires Phaser.Loader.Events#FILE_KEY_COMPLETE
* @since 3.7.0
*/
pendingDestroy: function(data) {
if (this.state === CONST.FILE_PENDING_DESTROY) {
return;
}
if (data === void 0) {
data = this.data;
}
var key = this.key;
var type = this.type;
this.loader.emit(Events.FILE_COMPLETE, key, type, data);
this.loader.emit(Events.FILE_KEY_COMPLETE + type + "-" + key, key, type, data);
this.loader.flagForRemoval(this);
this.state = CONST.FILE_PENDING_DESTROY;
},
/**
* Destroy this File and any references it holds.
*
* @method Phaser.Loader.File#destroy
* @since 3.7.0
*/
destroy: function() {
this.loader = null;
this.cache = null;
this.xhrSettings = null;
this.multiFile = null;
this.linkFile = null;
this.data = null;
}
});
File.createObjectURL = function(image, blob, defaultType) {
if (typeof URL === "function") {
image.src = URL.createObjectURL(blob);
} else {
var reader = new FileReader();
reader.onload = function() {
image.removeAttribute("crossOrigin");
image.src = "data:" + (blob.type || defaultType) + ";base64," + reader.result.split(",")[1];
};
reader.onerror = image.onerror;
reader.readAsDataURL(blob);
}
};
File.revokeObjectURL = function(image) {
if (typeof URL === "function") {
URL.revokeObjectURL(image.src);
}
};
module2.exports = File;
}
),
/***/
74099: (
/***/
(module2) => {
var types = {};
var FileTypesManager = {
/**
* Static method called when a LoaderPlugin is created.
*
* Loops through the local types object and injects all of them as
* properties into the LoaderPlugin instance.
*
* @method Phaser.Loader.FileTypesManager.install
* @since 3.0.0
*
* @param {Phaser.Loader.LoaderPlugin} loader - The LoaderPlugin to install the types into.
*/
install: function(loader) {
for (var key in types) {
loader[key] = types[key];
}
},
/**
* Static method called directly by the File Types.
*
* The key is a reference to the function used to load the files via the Loader, i.e. `image`.
*
* @method Phaser.Loader.FileTypesManager.register
* @since 3.0.0
*
* @param {string} key - The key that will be used as the method name in the LoaderPlugin.
* @param {function} factoryFunction - The function that will be called when LoaderPlugin.key is invoked.
*/
register: function(key, factoryFunction) {
types[key] = factoryFunction;
},
/**
* Removed all associated file types.
*
* @method Phaser.Loader.FileTypesManager.destroy
* @since 3.0.0
*/
destroy: function() {
types = {};
}
};
module2.exports = FileTypesManager;
}
),
/***/
98356: (
/***/
(module2) => {
var GetURL = function(file, baseURL) {
if (!file.url) {
return false;
}
if (file.url.match(/^(?:blob:|data:|capacitor:\/\/|http:\/\/|https:\/\/|\/\/)/)) {
return file.url;
} else {
return baseURL + file.url;
}
};
module2.exports = GetURL;
}
),
/***/
74261: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(23906);
var CustomSet = __webpack_require__2(35072);
var EventEmitter = __webpack_require__2(50792);
var Events = __webpack_require__2(54899);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var GetValue = __webpack_require__2(35154);
var IsPlainObject = __webpack_require__2(41212);
var PluginCache = __webpack_require__2(37277);
var SceneEvents = __webpack_require__2(44594);
var XHRSettings = __webpack_require__2(92638);
var LoaderPlugin = new Class({
Extends: EventEmitter,
initialize: function LoaderPlugin2(scene) {
EventEmitter.call(this);
var gameConfig = scene.sys.game.config;
var sceneConfig = scene.sys.settings.loader;
this.scene = scene;
this.systems = scene.sys;
this.cacheManager = scene.sys.cache;
this.textureManager = scene.sys.textures;
this.sceneManager = scene.sys.game.scene;
FileTypesManager.install(this);
this.prefix = "";
this.path = "";
this.baseURL = "";
this.setBaseURL(GetFastValue(sceneConfig, "baseURL", gameConfig.loaderBaseURL));
this.setPath(GetFastValue(sceneConfig, "path", gameConfig.loaderPath));
this.setPrefix(GetFastValue(sceneConfig, "prefix", gameConfig.loaderPrefix));
this.maxParallelDownloads = GetFastValue(sceneConfig, "maxParallelDownloads", gameConfig.loaderMaxParallelDownloads);
this.xhr = XHRSettings(
GetFastValue(sceneConfig, "responseType", gameConfig.loaderResponseType),
GetFastValue(sceneConfig, "async", gameConfig.loaderAsync),
GetFastValue(sceneConfig, "user", gameConfig.loaderUser),
GetFastValue(sceneConfig, "password", gameConfig.loaderPassword),
GetFastValue(sceneConfig, "timeout", gameConfig.loaderTimeout),
GetFastValue(sceneConfig, "withCredentials", gameConfig.loaderWithCredentials)
);
this.crossOrigin = GetFastValue(sceneConfig, "crossOrigin", gameConfig.loaderCrossOrigin);
this.imageLoadType = GetFastValue(sceneConfig, "imageLoadType", gameConfig.loaderImageLoadType);
this.localSchemes = GetFastValue(sceneConfig, "localScheme", gameConfig.loaderLocalScheme);
this.totalToLoad = 0;
this.progress = 0;
this.list = new CustomSet();
this.inflight = new CustomSet();
this.queue = new CustomSet();
this._deleteQueue = new CustomSet();
this.totalFailed = 0;
this.totalComplete = 0;
this.state = CONST.LOADER_IDLE;
this.multiKeyIndex = 0;
this.maxRetries = GetFastValue(sceneConfig, "maxRetries", gameConfig.loaderMaxRetries);
scene.sys.events.once(SceneEvents.BOOT, this.boot, this);
scene.sys.events.on(SceneEvents.START, this.pluginStart, this);
},
/**
* This method is called automatically, only once, when the Scene is first created.
* Do not invoke it directly.
*
* @method Phaser.Loader.LoaderPlugin#boot
* @private
* @since 3.5.1
*/
boot: function() {
this.systems.events.once(SceneEvents.DESTROY, this.destroy, this);
},
/**
* This method is called automatically by the Scene when it is starting up.
* It is responsible for creating local systems, properties and listening for Scene events.
* Do not invoke it directly.
*
* @method Phaser.Loader.LoaderPlugin#pluginStart
* @private
* @since 3.5.1
*/
pluginStart: function() {
this.systems.events.once(SceneEvents.SHUTDOWN, this.shutdown, this);
},
/**
* If you want to append a URL before the path of any asset you can set this here.
*
* Useful if allowing the asset base url to be configured outside of the game code.
*
* Once a base URL is set it will affect every file loaded by the Loader from that point on. It does _not_ change any
* file _already_ being loaded. To reset it, call this method with no arguments.
*
* @method Phaser.Loader.LoaderPlugin#setBaseURL
* @since 3.0.0
*
* @param {string} [url] - The URL to use. Leave empty to reset.
*
* @return {this} This Loader object.
*/
setBaseURL: function(url) {
if (url === void 0) {
url = "";
}
if (url !== "" && url.substr(-1) !== "/") {
url = url.concat("/");
}
this.baseURL = url;
return this;
},
/**
* The value of `path`, if set, is placed before any _relative_ file path given. For example:
*
* ```javascript
* this.load.setPath("images/sprites/");
* this.load.image("ball", "ball.png");
* this.load.image("tree", "level1/oaktree.png");
* this.load.image("boom", "http://server.com/explode.png");
* ```
*
* Would load the `ball` file from `images/sprites/ball.png` and the tree from
* `images/sprites/level1/oaktree.png` but the file `boom` would load from the URL
* given as it's an absolute URL.
*
* Please note that the path is added before the filename but *after* the baseURL (if set.)
*
* Once a path is set it will then affect every file added to the Loader from that point on. It does _not_ change any
* file _already_ in the load queue. To reset it, call this method with no arguments.
*
* @method Phaser.Loader.LoaderPlugin#setPath
* @since 3.0.0
*
* @param {string} [path] - The path to use. Leave empty to reset.
*
* @return {this} This Loader object.
*/
setPath: function(path) {
if (path === void 0) {
path = "";
}
if (path !== "" && path.substr(-1) !== "/") {
path = path.concat("/");
}
this.path = path;
return this;
},
/**
* An optional prefix that is automatically prepended to the start of every file key.
*
* If prefix was `MENU.` and you load an image with the key 'Background' the resulting key would be `MENU.Background`.
*
* Once a prefix is set it will then affect every file added to the Loader from that point on. It does _not_ change any
* file _already_ in the load queue. To reset it, call this method with no arguments.
*
* @method Phaser.Loader.LoaderPlugin#setPrefix
* @since 3.7.0
*
* @param {string} [prefix] - The prefix to use. Leave empty to reset.
*
* @return {this} This Loader object.
*/
setPrefix: function(prefix) {
if (prefix === void 0) {
prefix = "";
}
this.prefix = prefix;
return this;
},
/**
* Sets the Cross Origin Resource Sharing value used when loading files.
*
* Files can override this value on a per-file basis by specifying an alternative `crossOrigin` value in their file config.
*
* Once CORs is set it will then affect every file loaded by the Loader from that point on, as long as they don't have
* their own CORs setting. To reset it, call this method with no arguments.
*
* For more details about CORs see https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
*
* @method Phaser.Loader.LoaderPlugin#setCORS
* @since 3.0.0
*
* @param {string} [crossOrigin] - The value to use for the `crossOrigin` property in the load request.
*
* @return {this} This Loader object.
*/
setCORS: function(crossOrigin) {
this.crossOrigin = crossOrigin;
return this;
},
/**
* Adds a file, or array of files, into the load queue.
*
* The file must be an instance of `Phaser.Loader.File`, or a class that extends it. The Loader will check that the key
* used by the file won't conflict with any other key either in the loader, the inflight queue or the target cache.
* If allowed it will then add the file into the pending list, read for the load to start. Or, if the load has already
* started, ready for the next batch of files to be pulled from the list to the inflight queue.
*
* You should not normally call this method directly, but rather use one of the Loader methods like `image` or `atlas`,
* however you can call this as long as the file given to it is well formed.
*
* @method Phaser.Loader.LoaderPlugin#addFile
* @fires Phaser.Loader.Events#ADD
* @since 3.0.0
*
* @param {(Phaser.Loader.File|Phaser.Loader.File[])} file - The file, or array of files, to be added to the load queue.
*/
addFile: function(file) {
if (!Array.isArray(file)) {
file = [file];
}
for (var i = 0; i < file.length; i++) {
var item = file[i];
if (!this.keyExists(item)) {
this.list.set(item);
this.emit(Events.ADD, item.key, item.type, this, item);
if (this.isLoading()) {
this.totalToLoad++;
this.updateProgress();
}
}
}
},
/**
* Checks the key and type of the given file to see if it will conflict with anything already
* in a Cache, the Texture Manager, or the list or inflight queues.
*
* @method Phaser.Loader.LoaderPlugin#keyExists
* @since 3.7.0
*
* @param {Phaser.Loader.File} file - The file to check the key of.
*
* @return {boolean} `true` if adding this file will cause a cache or queue conflict, otherwise `false`.
*/
keyExists: function(file) {
var keyConflict = file.hasCacheConflict();
if (!keyConflict) {
this.list.iterate(function(item) {
if (item.type === file.type && item.key === file.key) {
keyConflict = true;
return false;
}
});
}
if (!keyConflict && this.isLoading()) {
this.inflight.iterate(function(item) {
if (item.type === file.type && item.key === file.key) {
keyConflict = true;
return false;
}
});
this.queue.iterate(function(item) {
if (item.type === file.type && item.key === file.key) {
keyConflict = true;
return false;
}
});
}
return keyConflict;
},
/**
* Takes a well formed, fully parsed pack file object and adds its entries into the load queue. Usually you do not call
* this method directly, but instead use `Loader.pack` and supply a path to a JSON file that holds the
* pack data. However, if you've got the data prepared you can pass it to this method.
*
* You can also provide an optional key. If you do then it will only add the entries from that part of the pack into
* to the load queue. If not specified it will add all entries it finds. For more details about the pack file format
* see the `LoaderPlugin.pack` method.
*
* @method Phaser.Loader.LoaderPlugin#addPack
* @since 3.7.0
*
* @param {any} pack - The Pack File data to be parsed and each entry of it to added to the load queue.
* @param {string} [packKey] - An optional key to use from the pack file data.
*
* @return {boolean} `true` if any files were added to the queue, otherwise `false`.
*/
addPack: function(pack, packKey) {
if (typeof packKey === "string") {
var subPack = GetValue(pack, packKey);
if (subPack) {
pack = { packKey: subPack };
}
}
var total = 0;
var currentBaseURL = this.baseURL;
var currentPath = this.path;
var currentPrefix = this.prefix;
for (var key in pack) {
if (!Object.prototype.hasOwnProperty.call(pack, key)) {
continue;
}
var config = pack[key];
var baseURL = GetFastValue(config, "baseURL", currentBaseURL);
var path = GetFastValue(config, "path", currentPath);
var prefix = GetFastValue(config, "prefix", currentPrefix);
var files = GetFastValue(config, "files", null);
var defaultType = GetFastValue(config, "defaultType", "void");
if (Array.isArray(files)) {
this.setBaseURL(baseURL);
this.setPath(path);
this.setPrefix(prefix);
for (var i = 0; i < files.length; i++) {
var file = files[i];
var type = file.hasOwnProperty("type") ? file.type : defaultType;
if (this[type]) {
this[type](file);
total++;
}
}
}
}
this.setBaseURL(currentBaseURL);
this.setPath(currentPath);
this.setPrefix(currentPrefix);
return total > 0;
},
/**
* Remove the resources listed in an Asset Pack.
*
* This removes Animations from the Animation Manager, Textures from the Texture Manager, and all other assets from their respective caches.
* It doesn't remove the Pack itself from the JSON cache, if it exists there.
* If the Pack includes another Pack, its resources will be removed too.
*
* @method Phaser.Loader.LoaderPlugin#removePack
* @since 3.85.0
*
* @param {(string|object)} packKey - The key of an Asset Pack in the JSON cache, or a Pack File data.
* @param {string} [dataKey] - A key in the Pack data, if you want to process only a section of it.
*/
removePack: function(packKey, dataKey) {
var animationManager = this.systems.anims;
var cacheManager = this.cacheManager;
var textureManager = this.textureManager;
var cacheMap = {
animation: "json",
aseprite: "json",
audio: "audio",
audioSprite: "audio",
binary: "binary",
bitmapFont: "bitmapFont",
css: null,
glsl: "shader",
html: "html",
json: "json",
obj: "obj",
plugin: null,
scenePlugin: null,
script: null,
spine: "json",
text: "text",
tilemapCSV: "tilemap",
tilemapImpact: "tilemap",
tilemapTiledJSON: "tilemap",
video: "video",
xml: "xml"
};
var pack;
if (IsPlainObject(packKey)) {
pack = packKey;
} else {
pack = cacheManager.json.get(packKey);
if (!pack) {
console.warn("Asset Pack not found in JSON cache:", packKey);
return;
}
}
if (dataKey) {
pack = { _: pack[dataKey] };
}
for (var configKey in pack) {
var config = pack[configKey];
var prefix = GetFastValue(config, "prefix", "");
var files = GetFastValue(config, "files");
var defaultType = GetFastValue(config, "defaultType");
if (Array.isArray(files)) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
var type = file.hasOwnProperty("type") ? file.type : defaultType;
if (!type) {
console.warn("No type:", file);
continue;
}
var fileKey = prefix + file.key;
if (type === "animation") {
animationManager.remove(fileKey);
}
if (type === "aseprite" || type === "atlas" || type === "atlasXML" || type === "htmlTexture" || type === "image" || type === "multiatlas" || type === "spritesheet" || type === "svg" || type === "texture" || type === "unityAtlas") {
textureManager.remove(fileKey);
if (!cacheMap[type]) {
continue;
}
}
if (type === "pack") {
this.removePack(fileKey, file.dataKey);
continue;
}
if (type === "spine") {
var spineAtlas = cacheManager.custom.spine.get(fileKey);
if (!spineAtlas) {
continue;
}
var spinePrefix = spineAtlas.prefix === void 0 ? "" : spineAtlas.prefix;
cacheManager.custom.spine.remove(fileKey);
var spineTexture = cacheManager.custom.spineTextures.get(fileKey);
if (!spineTexture) {
continue;
}
cacheManager.custom.spineTextures.remove(fileKey);
for (var j = 0; j < spineTexture.pages.length; j++) {
var page = spineTexture.pages[j];
var textureKey = spinePrefix + page.name;
var altTextureKey = fileKey + ":" + textureKey;
if (textureManager.exists(altTextureKey)) {
textureManager.remove(altTextureKey);
} else {
textureManager.remove(textureKey);
}
}
}
var cacheName = cacheMap[type];
if (cacheName === null) {
continue;
}
if (!cacheName) {
console.warn("Unknown type:", type);
continue;
}
var cache = cacheManager[cacheName];
cache.remove(fileKey);
}
}
}
},
/**
* Is the Loader actively loading, or processing loaded files?
*
* @method Phaser.Loader.LoaderPlugin#isLoading
* @since 3.0.0
*
* @return {boolean} `true` if the Loader is busy loading or processing, otherwise `false`.
*/
isLoading: function() {
return this.state === CONST.LOADER_LOADING || this.state === CONST.LOADER_PROCESSING;
},
/**
* Is the Loader ready to start a new load?
*
* @method Phaser.Loader.LoaderPlugin#isReady
* @since 3.0.0
*
* @return {boolean} `true` if the Loader is ready to start a new load, otherwise `false`.
*/
isReady: function() {
return this.state === CONST.LOADER_IDLE || this.state === CONST.LOADER_COMPLETE;
},
/**
* Starts the Loader running. This will reset the progress and totals and then emit a `start` event.
* If there is nothing in the queue the Loader will immediately complete, otherwise it will start
* loading the first batch of files.
*
* The Loader is started automatically if the queue is populated within your Scenes `preload` method.
*
* However, outside of this, you need to call this method to start it.
*
* If the Loader is already running this method will simply return.
*
* @method Phaser.Loader.LoaderPlugin#start
* @fires Phaser.Loader.Events#START
* @since 3.0.0
*/
start: function() {
if (!this.isReady()) {
return;
}
this.progress = 0;
this.totalFailed = 0;
this.totalComplete = 0;
this.totalToLoad = this.list.size;
this.emit(Events.START, this);
if (this.list.size === 0) {
this.loadComplete();
} else {
this.state = CONST.LOADER_LOADING;
this.inflight.clear();
this.queue.clear();
this.updateProgress();
this.checkLoadQueue();
this.systems.events.on(SceneEvents.UPDATE, this.update, this);
}
},
/**
* Called automatically during the load process.
* It updates the `progress` value and then emits a progress event, which you can use to
* display a loading bar in your game.
*
* @method Phaser.Loader.LoaderPlugin#updateProgress
* @fires Phaser.Loader.Events#PROGRESS
* @since 3.0.0
*/
updateProgress: function() {
this.progress = 1 - (this.list.size + this.inflight.size) / this.totalToLoad;
this.emit(Events.PROGRESS, this.progress);
},
/**
* Called automatically during the load process.
*
* @method Phaser.Loader.LoaderPlugin#update
* @since 3.10.0
*/
update: function() {
if (this.state === CONST.LOADER_LOADING && this.list.size > 0 && this.inflight.size < this.maxParallelDownloads) {
this.checkLoadQueue();
}
},
/**
* An internal method called by the Loader.
*
* It will check to see if there are any more files in the pending list that need loading, and if so it will move
* them from the list Set into the inflight Set, set their CORs flag and start them loading.
*
* It will carrying on doing this for each file in the pending list until it runs out, or hits the max allowed parallel downloads.
*
* @method Phaser.Loader.LoaderPlugin#checkLoadQueue
* @private
* @since 3.7.0
*/
checkLoadQueue: function() {
this.list.each(function(file) {
if (file.state === CONST.FILE_POPULATED || file.state === CONST.FILE_PENDING && this.inflight.size < this.maxParallelDownloads) {
this.inflight.set(file);
this.list.delete(file);
if (!file.crossOrigin) {
file.crossOrigin = this.crossOrigin;
}
file.load();
}
if (this.inflight.size === this.maxParallelDownloads) {
return false;
}
}, this);
},
/**
* An internal method called automatically by the XHRLoader belonging to a File.
*
* This method will remove the given file from the inflight Set and update the load progress.
* If the file was successful its `onProcess` method is called, otherwise it is added to the delete queue.
*
* @method Phaser.Loader.LoaderPlugin#nextFile
* @fires Phaser.Loader.Events#FILE_LOAD
* @fires Phaser.Loader.Events#FILE_LOAD_ERROR
* @since 3.0.0
*
* @param {Phaser.Loader.File} file - The File that just finished loading, or errored during load.
* @param {boolean} success - `true` if the file loaded successfully, otherwise `false`.
*/
nextFile: function(file, success) {
if (!this.inflight) {
return;
}
this.inflight.delete(file);
this.updateProgress();
if (success) {
this.totalComplete++;
this.queue.set(file);
this.emit(Events.FILE_LOAD, file);
file.onProcess();
} else {
this.totalFailed++;
this._deleteQueue.set(file);
this.emit(Events.FILE_LOAD_ERROR, file);
this.fileProcessComplete(file);
}
},
/**
* An internal method that is called automatically by the File when it has finished processing.
*
* If the process was successful, and the File isn't part of a MultiFile, its `addToCache` method is called.
*
* It this then removed from the queue. If there are no more files to load `loadComplete` is called.
*
* @method Phaser.Loader.LoaderPlugin#fileProcessComplete
* @since 3.7.0
*
* @param {Phaser.Loader.File} file - The file that has finished processing.
*/
fileProcessComplete: function(file) {
if (!this.scene || !this.systems || !this.systems.game || this.systems.game.pendingDestroy) {
return;
}
if (file.state === CONST.FILE_ERRORED) {
if (file.multiFile) {
file.multiFile.onFileFailed(file);
}
} else if (file.state === CONST.FILE_COMPLETE) {
if (file.multiFile) {
if (file.multiFile.isReadyToProcess()) {
file.multiFile.addToCache();
file.multiFile.pendingDestroy();
}
} else {
file.addToCache();
file.pendingDestroy();
}
}
this.queue.delete(file);
if (this.list.size === 0 && this.inflight.size === 0 && this.queue.size === 0) {
this.loadComplete();
}
},
/**
* Called at the end when the load queue is exhausted and all files have either loaded or errored.
* By this point every loaded file will now be in its associated cache and ready for use.
*
* Also clears down the Sets, puts progress to 1 and clears the deletion queue.
*
* @method Phaser.Loader.LoaderPlugin#loadComplete
* @fires Phaser.Loader.Events#COMPLETE
* @fires Phaser.Loader.Events#POST_PROCESS
* @since 3.7.0
*/
loadComplete: function() {
this.emit(Events.POST_PROCESS, this);
this.list.clear();
this.inflight.clear();
this.queue.clear();
this.progress = 1;
this.state = CONST.LOADER_COMPLETE;
this.systems.events.off(SceneEvents.UPDATE, this.update, this);
this._deleteQueue.iterateLocal("destroy");
this._deleteQueue.clear();
this.emit(Events.COMPLETE, this, this.totalComplete, this.totalFailed);
},
/**
* Adds a File into the pending-deletion queue.
*
* @method Phaser.Loader.LoaderPlugin#flagForRemoval
* @since 3.7.0
*
* @param {Phaser.Loader.File} file - The File to be queued for deletion when the Loader completes.
*/
flagForRemoval: function(file) {
this._deleteQueue.set(file);
},
/**
* Converts the given JSON data into a file that the browser then prompts you to download so you can save it locally.
*
* The data must be well formed JSON and ready-parsed, not a JavaScript object.
*
* @method Phaser.Loader.LoaderPlugin#saveJSON
* @since 3.0.0
*
* @param {*} data - The JSON data, ready parsed.
* @param {string} [filename=file.json] - The name to save the JSON file as.
*
* @return {this} This Loader plugin.
*/
saveJSON: function(data, filename) {
return this.save(JSON.stringify(data), filename);
},
/**
* Causes the browser to save the given data as a file to its default Downloads folder.
*
* Creates a DOM level anchor link, assigns it as being a `download` anchor, sets the href
* to be an ObjectURL based on the given data, and then invokes a click event.
*
* @method Phaser.Loader.LoaderPlugin#save
* @since 3.0.0
*
* @param {*} data - The data to be saved. Will be passed through URL.createObjectURL.
* @param {string} [filename=file.json] - The filename to save the file as.
* @param {string} [filetype=application/json] - The file type to use when saving the file. Defaults to JSON.
*
* @return {this} This Loader plugin.
*/
save: function(data, filename, filetype) {
if (filename === void 0) {
filename = "file.json";
}
if (filetype === void 0) {
filetype = "application/json";
}
var blob = new Blob([data], { type: filetype });
var url = URL.createObjectURL(blob);
var a = document.createElement("a");
a.download = filename;
a.textContent = "Download " + filename;
a.href = url;
a.click();
return this;
},
/**
* Resets the Loader.
*
* This will clear all lists and reset the base URL, path and prefix.
*
* Warning: If the Loader is currently downloading files, or has files in its queue, they will be aborted.
*
* @method Phaser.Loader.LoaderPlugin#reset
* @since 3.0.0
*/
reset: function() {
this.list.clear();
this.inflight.clear();
this.queue.clear();
var gameConfig = this.systems.game.config;
var sceneConfig = this.systems.settings.loader;
this.setBaseURL(GetFastValue(sceneConfig, "baseURL", gameConfig.loaderBaseURL));
this.setPath(GetFastValue(sceneConfig, "path", gameConfig.loaderPath));
this.setPrefix(GetFastValue(sceneConfig, "prefix", gameConfig.loaderPrefix));
this.state = CONST.LOADER_IDLE;
},
/**
* The Scene that owns this plugin is shutting down.
* We need to kill and reset all internal properties as well as stop listening to Scene events.
*
* @method Phaser.Loader.LoaderPlugin#shutdown
* @private
* @since 3.0.0
*/
shutdown: function() {
this.reset();
this.state = CONST.LOADER_SHUTDOWN;
this.removeAllListeners();
this.systems.events.off(SceneEvents.UPDATE, this.update, this);
this.systems.events.off(SceneEvents.SHUTDOWN, this.shutdown, this);
},
/**
* The Scene that owns this plugin is being destroyed.
* We need to shutdown and then kill off all external references.
*
* @method Phaser.Loader.LoaderPlugin#destroy
* @private
* @since 3.0.0
*/
destroy: function() {
this.shutdown();
this.state = CONST.LOADER_DESTROYED;
this.systems.events.off(SceneEvents.UPDATE, this.update, this);
this.systems.events.off(SceneEvents.START, this.pluginStart, this);
this.list = null;
this.inflight = null;
this.queue = null;
this.scene = null;
this.systems = null;
this.textureManager = null;
this.cacheManager = null;
this.sceneManager = null;
}
});
PluginCache.register("Loader", LoaderPlugin, "load");
module2.exports = LoaderPlugin;
}
),
/***/
3374: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Extend = __webpack_require__2(79291);
var XHRSettings = __webpack_require__2(92638);
var MergeXHRSettings = function(global, local) {
var output = global === void 0 ? XHRSettings() : Extend({}, global);
if (local) {
for (var setting in local) {
if (local[setting] !== void 0) {
output[setting] = local[setting];
}
}
}
return output;
};
module2.exports = MergeXHRSettings;
}
),
/***/
26430: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(23906);
var Events = __webpack_require__2(54899);
var MultiFile = new Class({
initialize: function MultiFile2(loader, type, key, files) {
var finalFiles = [];
files.forEach(function(file) {
if (file) {
finalFiles.push(file);
}
});
this.loader = loader;
this.type = type;
this.key = key;
var loadKey = this.key;
if (loader.prefix && loader.prefix !== "") {
this.key = loader.prefix + loadKey;
}
this.multiKeyIndex = loader.multiKeyIndex++;
this.files = finalFiles;
this.state = CONST.FILE_PENDING;
this.complete = false;
this.pending = finalFiles.length;
this.failed = 0;
this.config = {};
this.baseURL = loader.baseURL;
this.path = loader.path;
this.prefix = loader.prefix;
for (var i = 0; i < finalFiles.length; i++) {
finalFiles[i].multiFile = this;
}
},
/**
* Checks if this MultiFile is ready to process its children or not.
*
* @method Phaser.Loader.MultiFile#isReadyToProcess
* @since 3.7.0
*
* @return {boolean} `true` if all children of this MultiFile have loaded, otherwise `false`.
*/
isReadyToProcess: function() {
return this.pending === 0 && this.failed === 0 && !this.complete;
},
/**
* Adds another child to this MultiFile, increases the pending count and resets the completion status.
*
* @method Phaser.Loader.MultiFile#addToMultiFile
* @since 3.7.0
*
* @param {Phaser.Loader.File} files - The File to add to this MultiFile.
*
* @return {Phaser.Loader.MultiFile} This MultiFile instance.
*/
addToMultiFile: function(file) {
this.files.push(file);
file.multiFile = this;
this.pending++;
this.complete = false;
return this;
},
/**
* Called by each File when it finishes loading.
*
* @method Phaser.Loader.MultiFile#onFileComplete
* @since 3.7.0
*
* @param {Phaser.Loader.File} file - The File that has completed processing.
*/
onFileComplete: function(file) {
var index = this.files.indexOf(file);
if (index !== -1) {
this.pending--;
}
},
/**
* Called by each File that fails to load.
*
* @method Phaser.Loader.MultiFile#onFileFailed
* @since 3.7.0
*
* @param {Phaser.Loader.File} file - The File that has failed to load.
*/
onFileFailed: function(file) {
var index = this.files.indexOf(file);
if (index !== -1) {
this.failed++;
console.error('File failed: %s "%s" (via %s "%s")', this.type, this.key, file.type, file.key);
}
},
/**
* Called once all children of this multi file have been added to their caches and is now
* ready for deletion from the Loader.
*
* It will emit a `filecomplete` event from the LoaderPlugin.
*
* @method Phaser.Loader.MultiFile#pendingDestroy
* @fires Phaser.Loader.Events#FILE_COMPLETE
* @fires Phaser.Loader.Events#FILE_KEY_COMPLETE
* @since 3.60.0
*/
pendingDestroy: function() {
if (this.state === CONST.FILE_PENDING_DESTROY) {
return;
}
var key = this.key;
var type = this.type;
this.loader.emit(Events.FILE_COMPLETE, key, type);
this.loader.emit(Events.FILE_KEY_COMPLETE + type + "-" + key, key, type);
this.loader.flagForRemoval(this);
for (var i = 0; i < this.files.length; i++) {
this.files[i].pendingDestroy();
}
this.state = CONST.FILE_PENDING_DESTROY;
},
/**
* Destroy this Multi File and any references it holds.
*
* @method Phaser.Loader.MultiFile#destroy
* @since 3.60.0
*/
destroy: function() {
this.loader = null;
this.files = null;
this.config = null;
}
});
module2.exports = MultiFile;
}
),
/***/
84376: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var MergeXHRSettings = __webpack_require__2(3374);
var XHRLoader = function(file, globalXHRSettings) {
var config = MergeXHRSettings(globalXHRSettings, file.xhrSettings);
if (file.base64) {
var base64Data = file.url.split(";base64,").pop() || file.url.split(",").pop();
var fakeXHR = {
responseText: atob(base64Data)
};
file.onBase64Load(fakeXHR);
return;
}
var xhr = new XMLHttpRequest();
xhr.open("GET", file.src, config.async, config.user, config.password);
xhr.responseType = file.xhrSettings.responseType;
xhr.timeout = config.timeout;
if (config.headers) {
for (var key in config.headers) {
xhr.setRequestHeader(key, config.headers[key]);
}
}
if (config.header && config.headerValue) {
xhr.setRequestHeader(config.header, config.headerValue);
}
if (config.requestedWith) {
xhr.setRequestHeader("X-Requested-With", config.requestedWith);
}
if (config.overrideMimeType) {
xhr.overrideMimeType(config.overrideMimeType);
}
if (config.withCredentials) {
xhr.withCredentials = true;
}
xhr.onload = file.onLoad.bind(file, xhr);
xhr.onerror = file.onError.bind(file, xhr);
xhr.onprogress = file.onProgress.bind(file);
xhr.ontimeout = file.onError.bind(file, xhr);
xhr.send();
return xhr;
};
module2.exports = XHRLoader;
}
),
/***/
92638: (
/***/
(module2) => {
var XHRSettings = function(responseType, async, user, password, timeout, withCredentials) {
if (responseType === void 0) {
responseType = "";
}
if (async === void 0) {
async = true;
}
if (user === void 0) {
user = "";
}
if (password === void 0) {
password = "";
}
if (timeout === void 0) {
timeout = 0;
}
if (withCredentials === void 0) {
withCredentials = false;
}
return {
// Ignored by the Loader, only used by File.
responseType,
async,
// credentials
user,
password,
// timeout in ms (0 = no timeout)
timeout,
// setRequestHeader
headers: void 0,
header: void 0,
headerValue: void 0,
requestedWith: false,
// overrideMimeType
overrideMimeType: void 0,
// withCredentials
withCredentials
};
};
module2.exports = XHRSettings;
}
),
/***/
23906: (
/***/
(module2) => {
var FILE_CONST = {
/**
* The Loader is idle.
*
* @name Phaser.Loader.LOADER_IDLE
* @type {number}
* @since 3.0.0
*/
LOADER_IDLE: 0,
/**
* The Loader is actively loading.
*
* @name Phaser.Loader.LOADER_LOADING
* @type {number}
* @since 3.0.0
*/
LOADER_LOADING: 1,
/**
* The Loader is processing files is has loaded.
*
* @name Phaser.Loader.LOADER_PROCESSING
* @type {number}
* @since 3.0.0
*/
LOADER_PROCESSING: 2,
/**
* The Loader has completed loading and processing.
*
* @name Phaser.Loader.LOADER_COMPLETE
* @type {number}
* @since 3.0.0
*/
LOADER_COMPLETE: 3,
/**
* The Loader is shutting down.
*
* @name Phaser.Loader.LOADER_SHUTDOWN
* @type {number}
* @since 3.0.0
*/
LOADER_SHUTDOWN: 4,
/**
* The Loader has been destroyed.
*
* @name Phaser.Loader.LOADER_DESTROYED
* @type {number}
* @since 3.0.0
*/
LOADER_DESTROYED: 5,
/**
* File is in the load queue but not yet started.
*
* @name Phaser.Loader.FILE_PENDING
* @type {number}
* @since 3.0.0
*/
FILE_PENDING: 10,
/**
* File has been started to load by the loader (onLoad called)
*
* @name Phaser.Loader.FILE_LOADING
* @type {number}
* @since 3.0.0
*/
FILE_LOADING: 11,
/**
* File has loaded successfully, awaiting processing.
*
* @name Phaser.Loader.FILE_LOADED
* @type {number}
* @since 3.0.0
*/
FILE_LOADED: 12,
/**
* File failed to load.
*
* @name Phaser.Loader.FILE_FAILED
* @type {number}
* @since 3.0.0
*/
FILE_FAILED: 13,
/**
* File is being processed (onProcess callback)
*
* @name Phaser.Loader.FILE_PROCESSING
* @type {number}
* @since 3.0.0
*/
FILE_PROCESSING: 14,
/**
* The File has errored somehow during processing.
*
* @name Phaser.Loader.FILE_ERRORED
* @type {number}
* @since 3.0.0
*/
FILE_ERRORED: 16,
/**
* File has finished processing.
*
* @name Phaser.Loader.FILE_COMPLETE
* @type {number}
* @since 3.0.0
*/
FILE_COMPLETE: 17,
/**
* File has been destroyed.
*
* @name Phaser.Loader.FILE_DESTROYED
* @type {number}
* @since 3.0.0
*/
FILE_DESTROYED: 18,
/**
* File was populated from local data and doesn't need an HTTP request.
*
* @name Phaser.Loader.FILE_POPULATED
* @type {number}
* @since 3.0.0
*/
FILE_POPULATED: 19,
/**
* File is pending being destroyed.
*
* @name Phaser.Loader.FILE_PENDING_DESTROY
* @type {number}
* @since 3.60.0
*/
FILE_PENDING_DESTROY: 20
};
module2.exports = FILE_CONST;
}
),
/***/
42155: (
/***/
(module2) => {
module2.exports = "addfile";
}
),
/***/
38991: (
/***/
(module2) => {
module2.exports = "complete";
}
),
/***/
27540: (
/***/
(module2) => {
module2.exports = "filecomplete";
}
),
/***/
87464: (
/***/
(module2) => {
module2.exports = "filecomplete-";
}
),
/***/
94486: (
/***/
(module2) => {
module2.exports = "loaderror";
}
),
/***/
13035: (
/***/
(module2) => {
module2.exports = "load";
}
),
/***/
38144: (
/***/
(module2) => {
module2.exports = "fileprogress";
}
),
/***/
97520: (
/***/
(module2) => {
module2.exports = "postprocess";
}
),
/***/
85595: (
/***/
(module2) => {
module2.exports = "progress";
}
),
/***/
55680: (
/***/
(module2) => {
module2.exports = "start";
}
),
/***/
54899: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
ADD: __webpack_require__2(42155),
COMPLETE: __webpack_require__2(38991),
FILE_COMPLETE: __webpack_require__2(27540),
FILE_KEY_COMPLETE: __webpack_require__2(87464),
FILE_LOAD_ERROR: __webpack_require__2(94486),
FILE_LOAD: __webpack_require__2(13035),
FILE_PROGRESS: __webpack_require__2(38144),
POST_PROCESS: __webpack_require__2(97520),
PROGRESS: __webpack_require__2(85595),
START: __webpack_require__2(55680)
};
}
),
/***/
14135: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var FileTypesManager = __webpack_require__2(74099);
var JSONFile = __webpack_require__2(518);
var LoaderEvents = __webpack_require__2(54899);
var AnimationJSONFile = new Class({
Extends: JSONFile,
initialize: (
// url can either be a string, in which case it is treated like a proper url, or an object, in which case it is treated as a ready-made JS Object
// dataKey allows you to pluck a specific object out of the JSON and put just that into the cache, rather than the whole thing
function AnimationJSONFile2(loader, key, url, xhrSettings, dataKey) {
JSONFile.call(this, loader, key, url, xhrSettings, dataKey);
this.type = "animationJSON";
}
),
/**
* Called automatically by Loader.nextFile.
* This method controls what extra work this File does with its loaded data.
*
* @method Phaser.Loader.FileTypes.AnimationJSONFile#onProcess
* @since 3.7.0
*/
onProcess: function() {
this.loader.once(LoaderEvents.POST_PROCESS, this.onLoadComplete, this);
JSONFile.prototype.onProcess.call(this);
},
/**
* Called at the end of the load process, after the Loader has finished all files in its queue.
*
* @method Phaser.Loader.FileTypes.AnimationJSONFile#onLoadComplete
* @since 3.7.0
*/
onLoadComplete: function() {
this.loader.systems.anims.fromJSON(this.data);
}
});
FileTypesManager.register("animation", function(key, url, dataKey, xhrSettings) {
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
this.addFile(new AnimationJSONFile(this, key[i]));
}
} else {
this.addFile(new AnimationJSONFile(this, key, url, xhrSettings, dataKey));
}
return this;
});
module2.exports = AnimationJSONFile;
}
),
/***/
76272: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var ImageFile = __webpack_require__2(19550);
var IsPlainObject = __webpack_require__2(41212);
var JSONFile = __webpack_require__2(518);
var MultiFile = __webpack_require__2(26430);
var AsepriteFile = new Class({
Extends: MultiFile,
initialize: function AsepriteFile2(loader, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) {
var image;
var data;
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
image = new ImageFile(loader, {
key,
url: GetFastValue(config, "textureURL"),
extension: GetFastValue(config, "textureExtension", "png"),
normalMap: GetFastValue(config, "normalMap"),
xhrSettings: GetFastValue(config, "textureXhrSettings")
});
data = new JSONFile(loader, {
key,
url: GetFastValue(config, "atlasURL"),
extension: GetFastValue(config, "atlasExtension", "json"),
xhrSettings: GetFastValue(config, "atlasXhrSettings")
});
} else {
image = new ImageFile(loader, key, textureURL, textureXhrSettings);
data = new JSONFile(loader, key, atlasURL, atlasXhrSettings);
}
if (image.linkFile) {
MultiFile.call(this, loader, "atlasjson", key, [image, data, image.linkFile]);
} else {
MultiFile.call(this, loader, "atlasjson", key, [image, data]);
}
},
/**
* Adds this file to its target cache upon successful loading and processing.
*
* @method Phaser.Loader.FileTypes.AsepriteFile#addToCache
* @since 3.7.0
*/
addToCache: function() {
if (this.isReadyToProcess()) {
var image = this.files[0];
var json = this.files[1];
var normalMap = this.files[2] ? this.files[2].data : null;
this.loader.textureManager.addAtlas(image.key, image.data, json.data, normalMap);
json.addToCache();
this.complete = true;
}
}
});
FileTypesManager.register("aseprite", function(key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) {
var multifile;
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
multifile = new AsepriteFile(this, key[i]);
this.addFile(multifile.files);
}
} else {
multifile = new AsepriteFile(this, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings);
this.addFile(multifile.files);
}
return this;
});
module2.exports = AsepriteFile;
}
),
/***/
38734: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var ImageFile = __webpack_require__2(19550);
var IsPlainObject = __webpack_require__2(41212);
var JSONFile = __webpack_require__2(518);
var MultiFile = __webpack_require__2(26430);
var AtlasJSONFile = new Class({
Extends: MultiFile,
initialize: function AtlasJSONFile2(loader, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) {
var image;
var data;
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
image = new ImageFile(loader, {
key,
url: GetFastValue(config, "textureURL"),
extension: GetFastValue(config, "textureExtension", "png"),
normalMap: GetFastValue(config, "normalMap"),
xhrSettings: GetFastValue(config, "textureXhrSettings")
});
data = new JSONFile(loader, {
key,
url: GetFastValue(config, "atlasURL"),
extension: GetFastValue(config, "atlasExtension", "json"),
xhrSettings: GetFastValue(config, "atlasXhrSettings")
});
} else {
image = new ImageFile(loader, key, textureURL, textureXhrSettings);
data = new JSONFile(loader, key, atlasURL, atlasXhrSettings);
}
if (image.linkFile) {
MultiFile.call(this, loader, "atlasjson", key, [image, data, image.linkFile]);
} else {
MultiFile.call(this, loader, "atlasjson", key, [image, data]);
}
},
/**
* Adds this file to its target cache upon successful loading and processing.
*
* @method Phaser.Loader.FileTypes.AtlasJSONFile#addToCache
* @since 3.7.0
*/
addToCache: function() {
if (this.isReadyToProcess()) {
var image = this.files[0];
var json = this.files[1];
var normalMap = this.files[2] ? this.files[2].data : null;
this.loader.textureManager.addAtlas(image.key, image.data, json.data, normalMap);
this.complete = true;
}
}
});
FileTypesManager.register("atlas", function(key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) {
var multifile;
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
multifile = new AtlasJSONFile(this, key[i]);
this.addFile(multifile.files);
}
} else {
multifile = new AtlasJSONFile(this, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings);
this.addFile(multifile.files);
}
return this;
});
module2.exports = AtlasJSONFile;
}
),
/***/
74599: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var ImageFile = __webpack_require__2(19550);
var IsPlainObject = __webpack_require__2(41212);
var MultiFile = __webpack_require__2(26430);
var XMLFile = __webpack_require__2(57318);
var AtlasXMLFile = new Class({
Extends: MultiFile,
initialize: function AtlasXMLFile2(loader, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) {
var image;
var data;
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
image = new ImageFile(loader, {
key,
url: GetFastValue(config, "textureURL"),
extension: GetFastValue(config, "textureExtension", "png"),
normalMap: GetFastValue(config, "normalMap"),
xhrSettings: GetFastValue(config, "textureXhrSettings")
});
data = new XMLFile(loader, {
key,
url: GetFastValue(config, "atlasURL"),
extension: GetFastValue(config, "atlasExtension", "xml"),
xhrSettings: GetFastValue(config, "atlasXhrSettings")
});
} else {
image = new ImageFile(loader, key, textureURL, textureXhrSettings);
data = new XMLFile(loader, key, atlasURL, atlasXhrSettings);
}
if (image.linkFile) {
MultiFile.call(this, loader, "atlasxml", key, [image, data, image.linkFile]);
} else {
MultiFile.call(this, loader, "atlasxml", key, [image, data]);
}
},
/**
* Adds this file to its target cache upon successful loading and processing.
*
* @method Phaser.Loader.FileTypes.AtlasXMLFile#addToCache
* @since 3.7.0
*/
addToCache: function() {
if (this.isReadyToProcess()) {
var image = this.files[0];
var xml = this.files[1];
var normalMap = this.files[2] ? this.files[2].data : null;
this.loader.textureManager.addAtlasXML(image.key, image.data, xml.data, normalMap);
this.complete = true;
}
}
});
FileTypesManager.register("atlasXML", function(key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) {
var multifile;
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
multifile = new AtlasXMLFile(this, key[i]);
this.addFile(multifile.files);
}
} else {
multifile = new AtlasXMLFile(this, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings);
this.addFile(multifile.files);
}
return this;
});
module2.exports = AtlasXMLFile;
}
),
/***/
21097: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(23906);
var File = __webpack_require__2(41299);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var HTML5AudioFile = __webpack_require__2(89749);
var IsPlainObject = __webpack_require__2(41212);
var AudioFile = new Class({
Extends: File,
initialize: (
// URL is an object created by AudioFile.findAudioURL
function AudioFile2(loader, key, urlConfig, xhrSettings, audioContext) {
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
xhrSettings = GetFastValue(config, "xhrSettings");
audioContext = GetFastValue(config, "context", audioContext);
}
var fileConfig = {
type: "audio",
cache: loader.cacheManager.audio,
extension: urlConfig.type,
responseType: "arraybuffer",
key,
url: urlConfig.url,
xhrSettings,
config: { context: audioContext }
};
File.call(this, loader, fileConfig);
}
),
/**
* Called automatically by Loader.nextFile.
* This method controls what extra work this File does with its loaded data.
*
* @method Phaser.Loader.FileTypes.AudioFile#onProcess
* @since 3.0.0
*/
onProcess: function() {
this.state = CONST.FILE_PROCESSING;
var _this = this;
this.config.context.decodeAudioData(
this.xhrLoader.response,
function(audioBuffer) {
_this.data = audioBuffer;
_this.onProcessComplete();
},
function(e) {
console.error("Error decoding audio: " + _this.key + " - ", e ? e.message : null);
_this.onProcessError();
}
);
this.config.context = null;
}
});
AudioFile.create = function(loader, key, urls, config, xhrSettings) {
var game = loader.systems.game;
var audioConfig = game.config.audio;
var deviceAudio = game.device.audio;
if (IsPlainObject(key)) {
urls = GetFastValue(key, "url", []);
config = GetFastValue(key, "config", {});
}
var urlConfig = AudioFile.getAudioURL(game, urls);
if (!urlConfig) {
console.warn('No audio URLs for "%s" can play on this device', key);
return null;
}
if (deviceAudio.webAudio && !audioConfig.disableWebAudio) {
return new AudioFile(loader, key, urlConfig, xhrSettings, game.sound.context);
} else {
return new HTML5AudioFile(loader, key, urlConfig, config);
}
};
AudioFile.getAudioURL = function(game, urls) {
if (!Array.isArray(urls)) {
urls = [urls];
}
for (var i = 0; i < urls.length; i++) {
var url = GetFastValue(urls[i], "url", urls[i]);
if (url.indexOf("blob:") === 0 || url.indexOf("data:") === 0) {
return {
url,
type: ""
};
}
var audioType = url.match(/\.([a-zA-Z0-9]+)($|\?)/);
audioType = GetFastValue(urls[i], "type", audioType ? audioType[1] : "").toLowerCase();
if (game.device.audio[audioType]) {
return {
url,
type: audioType
};
}
}
return null;
};
FileTypesManager.register("audio", function(key, urls, config, xhrSettings) {
var game = this.systems.game;
var audioConfig = game.config.audio;
var deviceAudio = game.device.audio;
if (audioConfig.noAudio || !deviceAudio.webAudio && !deviceAudio.audioData) {
return this;
}
var audioFile;
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
audioFile = AudioFile.create(this, key[i]);
if (audioFile) {
this.addFile(audioFile);
}
}
} else {
audioFile = AudioFile.create(this, key, urls, config, xhrSettings);
if (audioFile) {
this.addFile(audioFile);
}
}
return this;
});
module2.exports = AudioFile;
}
),
/***/
89524: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var AudioFile = __webpack_require__2(21097);
var Class = __webpack_require__2(83419);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var IsPlainObject = __webpack_require__2(41212);
var JSONFile = __webpack_require__2(518);
var MultiFile = __webpack_require__2(26430);
var AudioSpriteFile = new Class({
Extends: MultiFile,
initialize: function AudioSpriteFile2(loader, key, jsonURL, audioURL, audioConfig, audioXhrSettings, jsonXhrSettings) {
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
jsonURL = GetFastValue(config, "jsonURL");
audioURL = GetFastValue(config, "audioURL");
audioConfig = GetFastValue(config, "audioConfig");
audioXhrSettings = GetFastValue(config, "audioXhrSettings");
jsonXhrSettings = GetFastValue(config, "jsonXhrSettings");
}
var data;
if (!audioURL) {
data = new JSONFile(loader, key, jsonURL, jsonXhrSettings);
MultiFile.call(this, loader, "audiosprite", key, [data]);
this.config.resourceLoad = true;
this.config.audioConfig = audioConfig;
this.config.audioXhrSettings = audioXhrSettings;
} else {
var audio = AudioFile.create(loader, key, audioURL, audioConfig, audioXhrSettings);
if (audio) {
data = new JSONFile(loader, key, jsonURL, jsonXhrSettings);
MultiFile.call(this, loader, "audiosprite", key, [audio, data]);
this.config.resourceLoad = false;
}
}
},
/**
* Called by each File when it finishes loading.
*
* @method Phaser.Loader.FileTypes.AudioSpriteFile#onFileComplete
* @since 3.7.0
*
* @param {Phaser.Loader.File} file - The File that has completed processing.
*/
onFileComplete: function(file) {
var index = this.files.indexOf(file);
if (index !== -1) {
this.pending--;
if (this.config.resourceLoad && file.type === "json" && file.data.hasOwnProperty("resources")) {
var urls = file.data.resources;
var audioConfig = GetFastValue(this.config, "audioConfig");
var audioXhrSettings = GetFastValue(this.config, "audioXhrSettings");
var audio = AudioFile.create(this.loader, file.key, urls, audioConfig, audioXhrSettings);
if (audio) {
this.addToMultiFile(audio);
this.loader.addFile(audio);
}
}
}
},
/**
* Adds this file to its target cache upon successful loading and processing.
*
* @method Phaser.Loader.FileTypes.AudioSpriteFile#addToCache
* @since 3.7.0
*/
addToCache: function() {
if (this.isReadyToProcess()) {
var fileA = this.files[0];
var fileB = this.files[1];
fileA.addToCache();
fileB.addToCache();
this.complete = true;
}
}
});
FileTypesManager.register("audioSprite", function(key, jsonURL, audioURL, audioConfig, audioXhrSettings, jsonXhrSettings) {
var game = this.systems.game;
var gameAudioConfig = game.config.audio;
var deviceAudio = game.device.audio;
if (gameAudioConfig && gameAudioConfig.noAudio || !deviceAudio.webAudio && !deviceAudio.audioData) {
return this;
}
var multifile;
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
multifile = new AudioSpriteFile(this, key[i]);
if (multifile.files) {
this.addFile(multifile.files);
}
}
} else {
multifile = new AudioSpriteFile(this, key, jsonURL, audioURL, audioConfig, audioXhrSettings, jsonXhrSettings);
if (multifile.files) {
this.addFile(multifile.files);
}
}
return this;
});
}
),
/***/
85722: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(23906);
var File = __webpack_require__2(41299);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var IsPlainObject = __webpack_require__2(41212);
var BinaryFile = new Class({
Extends: File,
initialize: function BinaryFile2(loader, key, url, xhrSettings, dataType) {
var extension = "bin";
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
url = GetFastValue(config, "url");
xhrSettings = GetFastValue(config, "xhrSettings");
extension = GetFastValue(config, "extension", extension);
dataType = GetFastValue(config, "dataType", dataType);
}
var fileConfig = {
type: "binary",
cache: loader.cacheManager.binary,
extension,
responseType: "arraybuffer",
key,
url,
xhrSettings,
config: { dataType }
};
File.call(this, loader, fileConfig);
},
/**
* Called automatically by Loader.nextFile.
* This method controls what extra work this File does with its loaded data.
*
* @method Phaser.Loader.FileTypes.BinaryFile#onProcess
* @since 3.7.0
*/
onProcess: function() {
this.state = CONST.FILE_PROCESSING;
var ctor = this.config.dataType;
this.data = ctor ? new ctor(this.xhrLoader.response) : this.xhrLoader.response;
this.onProcessComplete();
}
});
FileTypesManager.register("binary", function(key, url, dataType, xhrSettings) {
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
this.addFile(new BinaryFile(this, key[i]));
}
} else {
this.addFile(new BinaryFile(this, key, url, xhrSettings, dataType));
}
return this;
});
module2.exports = BinaryFile;
}
),
/***/
97025: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var ImageFile = __webpack_require__2(19550);
var IsPlainObject = __webpack_require__2(41212);
var MultiFile = __webpack_require__2(26430);
var ParseXMLBitmapFont = __webpack_require__2(21859);
var XMLFile = __webpack_require__2(57318);
var BitmapFontFile = new Class({
Extends: MultiFile,
initialize: function BitmapFontFile2(loader, key, textureURL, fontDataURL, textureXhrSettings, fontDataXhrSettings) {
var image;
var data;
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
image = new ImageFile(loader, {
key,
url: GetFastValue(config, "textureURL"),
extension: GetFastValue(config, "textureExtension", "png"),
normalMap: GetFastValue(config, "normalMap"),
xhrSettings: GetFastValue(config, "textureXhrSettings")
});
data = new XMLFile(loader, {
key,
url: GetFastValue(config, "fontDataURL"),
extension: GetFastValue(config, "fontDataExtension", "xml"),
xhrSettings: GetFastValue(config, "fontDataXhrSettings")
});
} else {
image = new ImageFile(loader, key, textureURL, textureXhrSettings);
data = new XMLFile(loader, key, fontDataURL, fontDataXhrSettings);
}
if (image.linkFile) {
MultiFile.call(this, loader, "bitmapfont", key, [image, data, image.linkFile]);
} else {
MultiFile.call(this, loader, "bitmapfont", key, [image, data]);
}
},
/**
* Adds this file to its target cache upon successful loading and processing.
*
* @method Phaser.Loader.FileTypes.BitmapFontFile#addToCache
* @since 3.7.0
*/
addToCache: function() {
if (this.isReadyToProcess()) {
var image = this.files[0];
var xml = this.files[1];
image.addToCache();
var texture = image.cache.get(image.key);
var data = ParseXMLBitmapFont(xml.data, image.cache.getFrame(image.key), 0, 0, texture);
this.loader.cacheManager.bitmapFont.add(image.key, { data, texture: image.key, frame: null });
this.complete = true;
}
}
});
FileTypesManager.register("bitmapFont", function(key, textureURL, fontDataURL, textureXhrSettings, fontDataXhrSettings) {
var multifile;
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
multifile = new BitmapFontFile(this, key[i]);
this.addFile(multifile.files);
}
} else {
multifile = new BitmapFontFile(this, key, textureURL, fontDataURL, textureXhrSettings, fontDataXhrSettings);
this.addFile(multifile.files);
}
return this;
});
module2.exports = BitmapFontFile;
}
),
/***/
16024: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(23906);
var File = __webpack_require__2(41299);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var IsPlainObject = __webpack_require__2(41212);
var CSSFile = new Class({
Extends: File,
initialize: function CSSFile2(loader, key, url, xhrSettings) {
var extension = "css";
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
url = GetFastValue(config, "url");
xhrSettings = GetFastValue(config, "xhrSettings");
extension = GetFastValue(config, "extension", extension);
}
var fileConfig = {
type: "script",
cache: false,
extension,
responseType: "text",
key,
url,
xhrSettings
};
File.call(this, loader, fileConfig);
},
/**
* Called automatically by Loader.nextFile.
* This method controls what extra work this File does with its loaded data.
*
* @method Phaser.Loader.FileTypes.CSSFile#onProcess
* @since 3.17.0
*/
onProcess: function() {
this.state = CONST.FILE_PROCESSING;
this.data = document.createElement("style");
this.data.defer = false;
this.data.innerHTML = this.xhrLoader.responseText;
document.head.appendChild(this.data);
this.onProcessComplete();
}
});
FileTypesManager.register("css", function(key, url, xhrSettings) {
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
this.addFile(new CSSFile(this, key[i]));
}
} else {
this.addFile(new CSSFile(this, key, url, xhrSettings));
}
return this;
});
module2.exports = CSSFile;
}
),
/***/
69559: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var AtlasJSONFile = __webpack_require__2(38734);
var BinaryFile = __webpack_require__2(85722);
var Class = __webpack_require__2(83419);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var ImageFile = __webpack_require__2(19550);
var IsPlainObject = __webpack_require__2(41212);
var JSONFile = __webpack_require__2(518);
var KTXParser = __webpack_require__2(31403);
var Merge = __webpack_require__2(46975);
var MultiAtlasFile = __webpack_require__2(59327);
var MultiFile = __webpack_require__2(26430);
var PVRParser = __webpack_require__2(82038);
var verifyCompressedTexture = __webpack_require__2(55222);
var CompressedTextureFile = new Class({
Extends: MultiFile,
initialize: function CompressedTextureFile2(loader, key, entry, xhrSettings) {
if (entry.multiAtlasURL) {
var multi = new JSONFile(loader, {
key,
url: entry.multiAtlasURL,
xhrSettings,
config: entry
});
MultiFile.call(this, loader, "texture", key, [multi]);
} else {
var extension = entry.textureURL.substr(entry.textureURL.length - 3);
if (!entry.type) {
entry.type = extension.toLowerCase() === "ktx" ? "KTX" : "PVR";
}
var image = new BinaryFile(loader, {
key,
url: entry.textureURL,
extension,
xhrSettings,
config: entry
});
if (entry.atlasURL) {
var data = new JSONFile(loader, {
key,
url: entry.atlasURL,
xhrSettings,
config: entry
});
MultiFile.call(this, loader, "texture", key, [image, data]);
} else {
MultiFile.call(this, loader, "texture", key, [image]);
}
}
this.config = entry;
},
/**
* Called by each File when it finishes loading.
*
* @method Phaser.Loader.FileTypes.CompressedTextureFile#onFileComplete
* @since 3.60.0
*
* @param {Phaser.Loader.File} file - The File that has completed processing.
*/
onFileComplete: function(file) {
var index = this.files.indexOf(file);
if (index !== -1) {
this.pending--;
if (!this.config.multiAtlasURL) {
return;
}
if (file.type === "json" && file.data.hasOwnProperty("textures")) {
var textures = file.data.textures;
var config = this.config;
var loader = this.loader;
var currentBaseURL = loader.baseURL;
var currentPath = loader.path;
var currentPrefix = loader.prefix;
var baseURL = GetFastValue(config, "multiBaseURL", this.baseURL);
var path = GetFastValue(config, "multiPath", this.path);
var prefix = GetFastValue(config, "prefix", this.prefix);
var textureXhrSettings = GetFastValue(config, "textureXhrSettings");
if (baseURL) {
loader.setBaseURL(baseURL);
}
if (path) {
loader.setPath(path);
}
if (prefix) {
loader.setPrefix(prefix);
}
for (var i = 0; i < textures.length; i++) {
var textureURL = textures[i].image;
var key = "CMA" + this.multiKeyIndex + "_" + textureURL;
var image = new BinaryFile(loader, key, textureURL, textureXhrSettings);
this.addToMultiFile(image);
loader.addFile(image);
if (textures[i].normalMap) {
var normalMap = new BinaryFile(loader, key, textures[i].normalMap, textureXhrSettings);
normalMap.type = "normalMap";
image.setLink(normalMap);
this.addToMultiFile(normalMap);
loader.addFile(normalMap);
}
}
loader.setBaseURL(currentBaseURL);
loader.setPath(currentPath);
loader.setPrefix(currentPrefix);
}
}
},
/**
* Adds this file to its target cache upon successful loading and processing.
*
* @method Phaser.Loader.FileTypes.CompressedTextureFile#addToCache
* @since 3.60.0
*/
addToCache: function() {
function compressionWarning(message) {
console.warn('Compressed Texture Invalid: "' + image.key + '". ' + message);
}
if (this.isReadyToProcess()) {
var entry = this.config;
if (entry.multiAtlasURL) {
this.addMultiToCache();
} else {
var renderer = this.loader.systems.renderer;
var textureManager = this.loader.textureManager;
var textureData;
var image = this.files[0];
var json = this.files[1];
if (entry.type === "PVR") {
textureData = PVRParser(image.data);
} else if (entry.type === "KTX") {
textureData = KTXParser(image.data);
if (!textureData) {
compressionWarning("KTX file contains unsupported format.");
}
}
if (textureData && !verifyCompressedTexture(textureData)) {
compressionWarning("Texture dimensions failed verification. Check the texture format specifications for " + entry.format + " 0x" + textureData.internalFormat.toString(16) + ".");
textureData = null;
}
if (textureData && !renderer.supportsCompressedTexture(entry.format, textureData.internalFormat)) {
compressionWarning("Texture format " + entry.format + " with internal format " + textureData.internalFormat + " not supported by the GPU. Texture invalid. This is often due to the texture using sRGB instead of linear RGB.");
textureData = null;
}
if (textureData) {
textureData.format = renderer.getCompressedTextureName(entry.format, textureData.internalFormat);
var atlasData = json && json.data ? json.data : null;
textureManager.addCompressedTexture(image.key, textureData, atlasData);
}
}
this.complete = true;
}
},
/**
* Adds all of the multi-file entties to their target caches upon successful loading and processing.
*
* @method Phaser.Loader.FileTypes.CompressedTextureFile#addMultiToCache
* @since 3.60.0
*/
addMultiToCache: function() {
var entry = this.config;
var json = this.files[0];
var data = [];
var images = [];
var normalMaps = [];
var renderer = this.loader.systems.renderer;
var textureManager = this.loader.textureManager;
var textureData;
for (var i = 1; i < this.files.length; i++) {
var file = this.files[i];
if (file.type === "normalMap") {
continue;
}
var pos = file.key.indexOf("_");
var key = file.key.substr(pos + 1);
var image = file.data;
for (var t = 0; t < json.data.textures.length; t++) {
var item = json.data.textures[t];
if (item.image === key) {
if (entry.type === "PVR") {
textureData = PVRParser(image);
} else if (entry.type === "KTX") {
textureData = KTXParser(image);
}
if (textureData && renderer.supportsCompressedTexture(entry.format, textureData.internalFormat)) {
textureData.format = renderer.getCompressedTextureName(entry.format, textureData.internalFormat);
images.push(textureData);
data.push(item);
if (file.linkFile) {
normalMaps.push(file.linkFile.data);
}
}
break;
}
}
}
if (normalMaps.length === 0) {
normalMaps = void 0;
}
textureManager.addAtlasJSONArray(this.key, images, data, normalMaps);
this.complete = true;
}
});
FileTypesManager.register("texture", function(key, url, xhrSettings) {
var renderer = this.systems.renderer;
var AddEntry = function(loader, key2, urls, xhrSettings2) {
var entry = {
format: null,
type: null,
textureURL: void 0,
atlasURL: void 0,
multiAtlasURL: void 0,
multiPath: void 0,
multiBaseURL: void 0
};
if (IsPlainObject(key2)) {
var config = key2;
key2 = GetFastValue(config, "key");
urls = GetFastValue(config, "url"), xhrSettings2 = GetFastValue(config, "xhrSettings");
}
var matched = false;
for (var textureBaseFormat in urls) {
if (renderer.supportsCompressedTexture(textureBaseFormat)) {
var urlEntry = urls[textureBaseFormat];
if (typeof urlEntry === "string") {
entry.textureURL = urlEntry;
} else {
entry = Merge(urlEntry, entry);
}
entry.format = textureBaseFormat.toUpperCase();
matched = true;
break;
}
}
if (!matched) {
console.warn("No supported compressed texture format or IMG fallback", key2);
} else if (entry.format === "IMG") {
var file;
var multifile;
if (entry.multiAtlasURL) {
multifile = new MultiAtlasFile(loader, key2, entry.multiAtlasURL, entry.multiPath, entry.multiBaseURL, xhrSettings2);
file = multifile.files;
} else if (entry.atlasURL) {
multifile = new AtlasJSONFile(loader, key2, entry.textureURL, entry.atlasURL, xhrSettings2);
file = multifile.files;
} else {
file = new ImageFile(loader, key2, entry.textureURL, xhrSettings2);
}
loader.addFile(file);
} else {
var texture = new CompressedTextureFile(loader, key2, entry, xhrSettings2);
loader.addFile(texture.files);
}
};
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
AddEntry(this, key[i]);
}
} else {
AddEntry(this, key, url, xhrSettings);
}
return this;
});
module2.exports = CompressedTextureFile;
}
),
/***/
47931: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(23906);
var File = __webpack_require__2(41299);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var IsPlainObject = __webpack_require__2(41212);
var Shader = __webpack_require__2(73894);
var GLSLFile = new Class({
Extends: File,
initialize: function GLSLFile2(loader, key, url, shaderType, xhrSettings) {
var extension = "glsl";
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
url = GetFastValue(config, "url");
shaderType = GetFastValue(config, "shaderType", "fragment");
xhrSettings = GetFastValue(config, "xhrSettings");
extension = GetFastValue(config, "extension", extension);
} else if (shaderType === void 0) {
shaderType = "fragment";
}
var fileConfig = {
type: "glsl",
cache: loader.cacheManager.shader,
extension,
responseType: "text",
key,
url,
config: {
shaderType
},
xhrSettings
};
File.call(this, loader, fileConfig);
},
/**
* Called automatically by Loader.nextFile.
* This method controls what extra work this File does with its loaded data.
*
* @method Phaser.Loader.FileTypes.GLSLFile#onProcess
* @since 3.7.0
*/
onProcess: function() {
this.state = CONST.FILE_PROCESSING;
this.data = this.xhrLoader.responseText;
this.onProcessComplete();
},
/**
* Adds this file to its target cache upon successful loading and processing.
*
* @method Phaser.Loader.FileTypes.GLSLFile#addToCache
* @since 3.17.0
*/
addToCache: function() {
var data = this.data.split("\n");
var block = this.extractBlock(data, 0);
if (block) {
while (block) {
var key = this.getShaderName(block.header);
var shaderType = this.getShaderType(block.header);
var uniforms = this.getShaderUniforms(block.header);
var shaderSrc = block.shader;
if (this.cache.has(key)) {
var shader = this.cache.get(key);
if (shaderType === "fragment") {
shader.fragmentSrc = shaderSrc;
} else {
shader.vertexSrc = shaderSrc;
}
if (!shader.uniforms) {
shader.uniforms = uniforms;
}
} else if (shaderType === "fragment") {
this.cache.add(key, new Shader(key, shaderSrc, "", uniforms));
} else {
this.cache.add(key, new Shader(key, "", shaderSrc, uniforms));
}
block = this.extractBlock(data, block.offset);
}
} else if (this.config.shaderType === "fragment") {
this.cache.add(this.key, new Shader(this.key, this.data));
} else {
this.cache.add(this.key, new Shader(this.key, "", this.data));
}
},
/**
* Returns the name of the shader from the header block.
*
* @method Phaser.Loader.FileTypes.GLSLFile#getShaderName
* @since 3.17.0
*
* @param {string[]} headerSource - The header data.
*
* @return {string} The shader name.
*/
getShaderName: function(headerSource) {
for (var i = 0; i < headerSource.length; i++) {
var line = headerSource[i].trim();
if (line.substring(0, 5) === "name:") {
return line.substring(5).trim();
}
}
return this.key;
},
/**
* Returns the type of the shader from the header block.
*
* @method Phaser.Loader.FileTypes.GLSLFile#getShaderType
* @since 3.17.0
*
* @param {string[]} headerSource - The header data.
*
* @return {string} The shader type. Either 'fragment' or 'vertex'.
*/
getShaderType: function(headerSource) {
for (var i = 0; i < headerSource.length; i++) {
var line = headerSource[i].trim();
if (line.substring(0, 5) === "type:") {
return line.substring(5).trim();
}
}
return this.config.shaderType;
},
/**
* Returns the shader uniforms from the header block.
*
* @method Phaser.Loader.FileTypes.GLSLFile#getShaderUniforms
* @since 3.17.0
*
* @param {string[]} headerSource - The header data.
*
* @return {any} The shader uniforms object.
*/
getShaderUniforms: function(headerSource) {
var uniforms = {};
for (var i = 0; i < headerSource.length; i++) {
var line = headerSource[i].trim();
if (line.substring(0, 8) === "uniform.") {
var pos = line.indexOf(":");
if (pos) {
var key = line.substring(8, pos);
try {
uniforms[key] = JSON.parse(line.substring(pos + 1));
} catch (e) {
console.warn("Invalid uniform JSON: " + key);
}
}
}
}
return uniforms;
},
/**
* Processes the shader file and extracts the relevant data.
*
* @method Phaser.Loader.FileTypes.GLSLFile#extractBlock
* @private
* @since 3.17.0
*
* @param {string[]} data - The array of shader data to process.
* @param {number} offset - The offset to start processing from.
*
* @return {any} The processed shader block, or null.
*/
extractBlock: function(data, offset) {
var headerStart = -1;
var headerEnd = -1;
var blockEnd = -1;
var headerOpen = false;
var captureSource = false;
var headerSource = [];
var shaderSource = [];
for (var i = offset; i < data.length; i++) {
var line = data[i].trim();
if (line === "---") {
if (headerStart === -1) {
headerStart = i;
headerOpen = true;
} else if (headerOpen) {
headerEnd = i;
headerOpen = false;
captureSource = true;
} else {
captureSource = false;
break;
}
} else if (headerOpen) {
headerSource.push(line);
} else if (captureSource) {
shaderSource.push(line);
blockEnd = i;
}
}
if (!headerOpen && headerEnd !== -1) {
return { header: headerSource, shader: shaderSource.join("\n"), offset: blockEnd };
} else {
return null;
}
}
});
FileTypesManager.register("glsl", function(key, url, shaderType, xhrSettings) {
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
this.addFile(new GLSLFile(this, key[i]));
}
} else {
this.addFile(new GLSLFile(this, key, url, shaderType, xhrSettings));
}
return this;
});
module2.exports = GLSLFile;
}
),
/***/
89749: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Events = __webpack_require__2(54899);
var File = __webpack_require__2(41299);
var GetFastValue = __webpack_require__2(95540);
var GetURL = __webpack_require__2(98356);
var IsPlainObject = __webpack_require__2(41212);
var HTML5AudioFile = new Class({
Extends: File,
initialize: function HTML5AudioFile2(loader, key, urlConfig, audioConfig) {
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
audioConfig = GetFastValue(config, "config", audioConfig);
}
var fileConfig = {
type: "audio",
cache: loader.cacheManager.audio,
extension: urlConfig.type,
key,
url: urlConfig.url,
config: audioConfig
};
File.call(this, loader, fileConfig);
this.locked = "ontouchstart" in window;
this.loaded = false;
this.filesLoaded = 0;
this.filesTotal = 0;
},
/**
* Called when the file finishes loading.
*
* @method Phaser.Loader.FileTypes.HTML5AudioFile#onLoad
* @since 3.0.0
*/
onLoad: function() {
if (this.loaded) {
return;
}
this.loaded = true;
this.loader.nextFile(this, true);
},
/**
* Called if the file errors while loading.
*
* @method Phaser.Loader.FileTypes.HTML5AudioFile#onError
* @since 3.0.0
*/
onError: function() {
for (var i = 0; i < this.data.length; i++) {
var audio = this.data[i];
audio.oncanplaythrough = null;
audio.onerror = null;
}
this.loader.nextFile(this, false);
},
/**
* Called during the file load progress. Is sent a DOM ProgressEvent.
*
* @method Phaser.Loader.FileTypes.HTML5AudioFile#onProgress
* @fires Phaser.Loader.Events#FILE_PROGRESS
* @since 3.0.0
*/
onProgress: function(event) {
var audio = event.target;
audio.oncanplaythrough = null;
audio.onerror = null;
this.filesLoaded++;
this.percentComplete = Math.min(this.filesLoaded / this.filesTotal, 1);
this.loader.emit(Events.FILE_PROGRESS, this, this.percentComplete);
if (this.filesLoaded === this.filesTotal) {
this.onLoad();
}
},
/**
* Called by the Loader, starts the actual file downloading.
* During the load the methods onLoad, onError and onProgress are called, based on the XHR events.
* You shouldn't normally call this method directly, it's meant to be invoked by the Loader.
*
* @method Phaser.Loader.FileTypes.HTML5AudioFile#load
* @since 3.0.0
*/
load: function() {
this.data = [];
var instances = this.config && this.config.instances || 1;
this.filesTotal = instances;
this.filesLoaded = 0;
this.percentComplete = 0;
for (var i = 0; i < instances; i++) {
var audio = new Audio();
if (!audio.dataset) {
audio.dataset = {};
}
audio.dataset.name = this.key + ("0" + i).slice(-2);
audio.dataset.used = "false";
if (this.locked) {
audio.dataset.locked = "true";
} else {
audio.dataset.locked = "false";
audio.preload = "auto";
audio.oncanplaythrough = this.onProgress.bind(this);
audio.onerror = this.onError.bind(this);
}
this.data.push(audio);
}
for (i = 0; i < this.data.length; i++) {
audio = this.data[i];
audio.src = GetURL(this, this.loader.baseURL);
if (!this.locked) {
audio.load();
}
}
if (this.locked) {
setTimeout(this.onLoad.bind(this));
}
}
});
module2.exports = HTML5AudioFile;
}
),
/***/
88470: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(23906);
var File = __webpack_require__2(41299);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var IsPlainObject = __webpack_require__2(41212);
var HTMLFile = new Class({
Extends: File,
initialize: function HTMLFile2(loader, key, url, xhrSettings) {
var extension = "html";
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
url = GetFastValue(config, "url");
xhrSettings = GetFastValue(config, "xhrSettings");
extension = GetFastValue(config, "extension", extension);
}
var fileConfig = {
type: "text",
cache: loader.cacheManager.html,
extension,
responseType: "text",
key,
url,
xhrSettings
};
File.call(this, loader, fileConfig);
},
/**
* Called automatically by Loader.nextFile.
* This method controls what extra work this File does with its loaded data.
*
* @method Phaser.Loader.FileTypes.HTMLFile#onProcess
* @since 3.7.0
*/
onProcess: function() {
this.state = CONST.FILE_PROCESSING;
this.data = this.xhrLoader.responseText;
this.onProcessComplete();
}
});
FileTypesManager.register("html", function(key, url, xhrSettings) {
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
this.addFile(new HTMLFile(this, key[i]));
}
} else {
this.addFile(new HTMLFile(this, key, url, xhrSettings));
}
return this;
});
module2.exports = HTMLFile;
}
),
/***/
14643: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(23906);
var File = __webpack_require__2(41299);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var IsPlainObject = __webpack_require__2(41212);
var HTMLTextureFile = new Class({
Extends: File,
initialize: function HTMLTextureFile2(loader, key, url, width, height, xhrSettings) {
if (width === void 0) {
width = 512;
}
if (height === void 0) {
height = 512;
}
var extension = "html";
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
url = GetFastValue(config, "url");
xhrSettings = GetFastValue(config, "xhrSettings");
extension = GetFastValue(config, "extension", extension);
width = GetFastValue(config, "width", width);
height = GetFastValue(config, "height", height);
}
var fileConfig = {
type: "html",
cache: loader.textureManager,
extension,
responseType: "text",
key,
url,
xhrSettings,
config: {
width,
height
}
};
File.call(this, loader, fileConfig);
},
/**
* Called automatically by Loader.nextFile.
* This method controls what extra work this File does with its loaded data.
*
* @method Phaser.Loader.FileTypes.HTMLTextureFile#onProcess
* @since 3.7.0
*/
onProcess: function() {
this.state = CONST.FILE_PROCESSING;
var w = this.config.width;
var h = this.config.height;
var data = [];
data.push('<svg width="' + w + 'px" height="' + h + 'px" viewBox="0 0 ' + w + " " + h + '" xmlns="http://www.w3.org/2000/svg">');
data.push('<foreignObject width="100%" height="100%">');
data.push('<body xmlns="http://www.w3.org/1999/xhtml">');
data.push(this.xhrLoader.responseText);
data.push("</body>");
data.push("</foreignObject>");
data.push("</svg>");
var svg = [data.join("\n")];
var _this = this;
try {
var blob = new window.Blob(svg, { type: "image/svg+xml;charset=utf-8" });
} catch (e) {
_this.state = CONST.FILE_ERRORED;
_this.onProcessComplete();
return;
}
this.data = new Image();
this.data.crossOrigin = this.crossOrigin;
this.data.onload = function() {
File.revokeObjectURL(_this.data);
_this.onProcessComplete();
};
this.data.onerror = function() {
File.revokeObjectURL(_this.data);
_this.onProcessError();
};
File.createObjectURL(this.data, blob, "image/svg+xml");
},
/**
* Adds this file to its target cache upon successful loading and processing.
*
* @method Phaser.Loader.FileTypes.HTMLTextureFile#addToCache
* @since 3.7.0
*/
addToCache: function() {
this.cache.addImage(this.key, this.data);
}
});
FileTypesManager.register("htmlTexture", function(key, url, width, height, xhrSettings) {
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
this.addFile(new HTMLTextureFile(this, key[i]));
}
} else {
this.addFile(new HTMLTextureFile(this, key, url, width, height, xhrSettings));
}
return this;
});
module2.exports = HTMLTextureFile;
}
),
/***/
19550: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(23906);
var File = __webpack_require__2(41299);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var IsPlainObject = __webpack_require__2(41212);
var GetURL = __webpack_require__2(98356);
var ImageFile = new Class({
Extends: File,
initialize: function ImageFile2(loader, key, url, xhrSettings, frameConfig) {
var extension = "png";
var normalMapURL;
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
url = GetFastValue(config, "url");
normalMapURL = GetFastValue(config, "normalMap");
xhrSettings = GetFastValue(config, "xhrSettings");
extension = GetFastValue(config, "extension", extension);
frameConfig = GetFastValue(config, "frameConfig");
}
if (Array.isArray(url)) {
normalMapURL = url[1];
url = url[0];
}
var fileConfig = {
type: "image",
cache: loader.textureManager,
extension,
responseType: "blob",
key,
url,
xhrSettings,
config: frameConfig
};
File.call(this, loader, fileConfig);
if (normalMapURL) {
var normalMap = new ImageFile2(loader, this.key, normalMapURL, xhrSettings, frameConfig);
normalMap.type = "normalMap";
this.setLink(normalMap);
loader.addFile(normalMap);
}
this.useImageElementLoad = loader.imageLoadType === "HTMLImageElement" || this.base64;
if (this.useImageElementLoad) {
this.load = this.loadImage;
this.onProcess = this.onProcessImage;
}
},
/**
* Called automatically by Loader.nextFile.
* This method controls what extra work this File does with its loaded data.
*
* @method Phaser.Loader.FileTypes.ImageFile#onProcess
* @since 3.7.0
*/
onProcess: function() {
this.state = CONST.FILE_PROCESSING;
this.data = new Image();
this.data.crossOrigin = this.crossOrigin;
var _this = this;
this.data.onload = function() {
File.revokeObjectURL(_this.data);
_this.onProcessComplete();
};
this.data.onerror = function() {
File.revokeObjectURL(_this.data);
_this.onProcessError();
};
File.createObjectURL(this.data, this.xhrLoader.response, "image/png");
},
/**
* Handles image load processing.
*
* @method Phaser.Loader.FileTypes.ImageFile#onProcessImage
* @private
* @since 3.60.0
*/
onProcessImage: function() {
var result = this.state;
this.state = CONST.FILE_PROCESSING;
if (result === CONST.FILE_LOADED) {
this.onProcessComplete();
} else {
this.onProcessError();
}
},
/**
* Loads the image using either XHR or an Image tag.
*
* @method Phaser.Loader.FileTypes.ImageFile#loadImage
* @private
* @since 3.60.0
*/
loadImage: function() {
this.state = CONST.FILE_LOADING;
this.src = GetURL(this, this.loader.baseURL);
this.data = new Image();
this.data.crossOrigin = this.crossOrigin;
var _this = this;
this.data.onload = function() {
_this.state = CONST.FILE_LOADED;
_this.loader.nextFile(_this, true);
};
this.data.onerror = function() {
_this.loader.nextFile(_this, false);
};
this.data.src = this.src;
},
/**
* Adds this file to its target cache upon successful loading and processing.
*
* @method Phaser.Loader.FileTypes.ImageFile#addToCache
* @since 3.7.0
*/
addToCache: function() {
var linkFile = this.linkFile;
if (linkFile) {
if (linkFile.state >= CONST.FILE_COMPLETE) {
if (linkFile.type === "spritesheet") {
linkFile.addToCache();
} else if (this.type === "normalMap") {
this.cache.addImage(this.key, linkFile.data, this.data);
} else {
this.cache.addImage(this.key, this.data, linkFile.data);
}
}
} else {
this.cache.addImage(this.key, this.data);
}
}
});
FileTypesManager.register("image", function(key, url, xhrSettings) {
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
this.addFile(new ImageFile(this, key[i]));
}
} else {
this.addFile(new ImageFile(this, key, url, xhrSettings));
}
return this;
});
module2.exports = ImageFile;
}
),
/***/
518: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(23906);
var File = __webpack_require__2(41299);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var GetValue = __webpack_require__2(35154);
var IsPlainObject = __webpack_require__2(41212);
var JSONFile = new Class({
Extends: File,
initialize: (
// url can either be a string, in which case it is treated like a proper url, or an object, in which case it is treated as a ready-made JS Object
// dataKey allows you to pluck a specific object out of the JSON and put just that into the cache, rather than the whole thing
function JSONFile2(loader, key, url, xhrSettings, dataKey) {
var extension = "json";
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
url = GetFastValue(config, "url");
xhrSettings = GetFastValue(config, "xhrSettings");
extension = GetFastValue(config, "extension", extension);
dataKey = GetFastValue(config, "dataKey", dataKey);
}
var fileConfig = {
type: "json",
cache: loader.cacheManager.json,
extension,
responseType: "text",
key,
url,
xhrSettings,
config: dataKey
};
File.call(this, loader, fileConfig);
if (IsPlainObject(url)) {
if (dataKey) {
this.data = GetValue(url, dataKey);
} else {
this.data = url;
}
this.state = CONST.FILE_POPULATED;
}
}
),
/**
* Called automatically by Loader.nextFile.
* This method controls what extra work this File does with its loaded data.
*
* @method Phaser.Loader.FileTypes.JSONFile#onProcess
* @since 3.7.0
*/
onProcess: function() {
if (this.state !== CONST.FILE_POPULATED) {
this.state = CONST.FILE_PROCESSING;
try {
var json = JSON.parse(this.xhrLoader.responseText);
} catch (e) {
this.onProcessError();
throw e;
}
var key = this.config;
if (typeof key === "string") {
this.data = GetValue(json, key, json);
} else {
this.data = json;
}
}
this.onProcessComplete();
}
});
FileTypesManager.register("json", function(key, url, dataKey, xhrSettings) {
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
this.addFile(new JSONFile(this, key[i]));
}
} else {
this.addFile(new JSONFile(this, key, url, xhrSettings, dataKey));
}
return this;
});
module2.exports = JSONFile;
}
),
/***/
59327: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var ImageFile = __webpack_require__2(19550);
var IsPlainObject = __webpack_require__2(41212);
var JSONFile = __webpack_require__2(518);
var MultiFile = __webpack_require__2(26430);
var MultiAtlasFile = new Class({
Extends: MultiFile,
initialize: function MultiAtlasFile2(loader, key, atlasURL, path, baseURL, atlasXhrSettings, textureXhrSettings) {
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
if (GetFastValue(config, "url", false)) {
atlasURL = GetFastValue(config, "url");
} else {
atlasURL = GetFastValue(config, "atlasURL");
}
atlasXhrSettings = GetFastValue(config, "xhrSettings");
path = GetFastValue(config, "path");
baseURL = GetFastValue(config, "baseURL");
textureXhrSettings = GetFastValue(config, "textureXhrSettings");
}
var data = new JSONFile(loader, key, atlasURL, atlasXhrSettings);
MultiFile.call(this, loader, "multiatlas", key, [data]);
this.config.path = path;
this.config.baseURL = baseURL;
this.config.textureXhrSettings = textureXhrSettings;
},
/**
* Called by each File when it finishes loading.
*
* @method Phaser.Loader.FileTypes.MultiAtlasFile#onFileComplete
* @since 3.7.0
*
* @param {Phaser.Loader.File} file - The File that has completed processing.
*/
onFileComplete: function(file) {
var index = this.files.indexOf(file);
if (index !== -1) {
this.pending--;
if (file.type === "json" && file.data.hasOwnProperty("textures")) {
var textures = file.data.textures;
var config = this.config;
var loader = this.loader;
var currentBaseURL = loader.baseURL;
var currentPath = loader.path;
var currentPrefix = loader.prefix;
var baseURL = GetFastValue(config, "baseURL", this.baseURL);
var path = GetFastValue(config, "path", this.path);
var prefix = GetFastValue(config, "prefix", this.prefix);
var textureXhrSettings = GetFastValue(config, "textureXhrSettings");
loader.setBaseURL(baseURL);
loader.setPath(path);
loader.setPrefix(prefix);
for (var i = 0; i < textures.length; i++) {
var textureURL = textures[i].image;
var key = "MA" + this.multiKeyIndex + "_" + textureURL;
var image = new ImageFile(loader, key, textureURL, textureXhrSettings);
this.addToMultiFile(image);
loader.addFile(image);
if (textures[i].normalMap) {
var normalMap = new ImageFile(loader, key, textures[i].normalMap, textureXhrSettings);
normalMap.type = "normalMap";
image.setLink(normalMap);
this.addToMultiFile(normalMap);
loader.addFile(normalMap);
}
}
loader.setBaseURL(currentBaseURL);
loader.setPath(currentPath);
loader.setPrefix(currentPrefix);
}
}
},
/**
* Adds this file to its target cache upon successful loading and processing.
*
* @method Phaser.Loader.FileTypes.MultiAtlasFile#addToCache
* @since 3.7.0
*/
addToCache: function() {
if (this.isReadyToProcess()) {
var fileJSON = this.files[0];
var data = [];
var images = [];
var normalMaps = [];
for (var i = 1; i < this.files.length; i++) {
var file = this.files[i];
if (file.type === "normalMap") {
continue;
}
var pos = file.key.indexOf("_");
var key = file.key.substr(pos + 1);
var image = file.data;
for (var t = 0; t < fileJSON.data.textures.length; t++) {
var item = fileJSON.data.textures[t];
if (item.image === key) {
images.push(image);
data.push(item);
if (file.linkFile) {
normalMaps.push(file.linkFile.data);
}
break;
}
}
}
if (normalMaps.length === 0) {
normalMaps = void 0;
}
this.loader.textureManager.addAtlasJSONArray(this.key, images, data, normalMaps);
this.complete = true;
}
}
});
FileTypesManager.register("multiatlas", function(key, atlasURL, path, baseURL, atlasXhrSettings) {
var multifile;
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
multifile = new MultiAtlasFile(this, key[i]);
this.addFile(multifile.files);
}
} else {
multifile = new MultiAtlasFile(this, key, atlasURL, path, baseURL, atlasXhrSettings);
this.addFile(multifile.files);
}
return this;
});
module2.exports = MultiAtlasFile;
}
),
/***/
99297: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var IsPlainObject = __webpack_require__2(41212);
var MultiFile = __webpack_require__2(26430);
var ScriptFile = __webpack_require__2(34328);
var MultiScriptFile = new Class({
Extends: MultiFile,
initialize: function MultiScriptFile2(loader, key, url, xhrSettings) {
var extension = "js";
var files = [];
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
url = GetFastValue(config, "url");
xhrSettings = GetFastValue(config, "xhrSettings");
extension = GetFastValue(config, "extension", extension);
}
if (!Array.isArray(url)) {
url = [url];
}
for (var i = 0; i < url.length; i++) {
var scriptFile = new ScriptFile(loader, {
key: key + "_" + i.toString(),
url: url[i],
extension,
xhrSettings
});
scriptFile.onProcess = function() {
this.onProcessComplete();
};
files.push(scriptFile);
}
MultiFile.call(this, loader, "scripts", key, files);
},
/**
* Adds this file to its target cache upon successful loading and processing.
*
* @method Phaser.Loader.FileTypes.MultiScriptFile#addToCache
* @since 3.17.0
*/
addToCache: function() {
if (this.isReadyToProcess()) {
for (var i = 0; i < this.files.length; i++) {
var file = this.files[i];
file.data = document.createElement("script");
file.data.language = "javascript";
file.data.type = "text/javascript";
file.data.defer = false;
file.data.text = file.xhrLoader.responseText;
document.head.appendChild(file.data);
}
this.complete = true;
}
}
});
FileTypesManager.register("scripts", function(key, url, xhrSettings) {
var multifile;
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
multifile = new MultiScriptFile(this, key[i]);
this.addFile(multifile.files);
}
} else {
multifile = new MultiScriptFile(this, key, url, xhrSettings);
this.addFile(multifile.files);
}
return this;
});
module2.exports = MultiScriptFile;
}
),
/***/
41846: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var IsPlainObject = __webpack_require__2(41212);
var MultiFile = __webpack_require__2(26430);
var ParseObj = __webpack_require__2(85048);
var ParseObjMaterial = __webpack_require__2(61485);
var TextFile = __webpack_require__2(78776);
var OBJFile = new Class({
Extends: MultiFile,
initialize: function OBJFile2(loader, key, objURL, matURL, flipUV, xhrSettings) {
var obj;
var mat;
var cache = loader.cacheManager.obj;
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
obj = new TextFile(loader, {
key,
type: "obj",
cache,
url: GetFastValue(config, "url"),
extension: GetFastValue(config, "extension", "obj"),
xhrSettings: GetFastValue(config, "xhrSettings"),
config: {
flipUV: GetFastValue(config, "flipUV", flipUV)
}
});
matURL = GetFastValue(config, "matURL");
if (matURL) {
mat = new TextFile(loader, {
key,
type: "mat",
cache,
url: matURL,
extension: GetFastValue(config, "matExtension", "mat"),
xhrSettings: GetFastValue(config, "xhrSettings")
});
}
} else {
obj = new TextFile(loader, {
key,
url: objURL,
type: "obj",
cache,
extension: "obj",
xhrSettings,
config: {
flipUV
}
});
if (matURL) {
mat = new TextFile(loader, {
key,
url: matURL,
type: "mat",
cache,
extension: "mat",
xhrSettings
});
}
}
MultiFile.call(this, loader, "obj", key, [obj, mat]);
},
/**
* Adds this file to its target cache upon successful loading and processing.
*
* @method Phaser.Loader.FileTypes.OBJFile#addToCache
* @since 3.50.0
*/
addToCache: function() {
if (this.isReadyToProcess()) {
var obj = this.files[0];
var mat = this.files[1];
var objData = ParseObj(obj.data, obj.config.flipUV);
if (mat) {
objData.materials = ParseObjMaterial(mat.data);
}
obj.cache.add(obj.key, objData);
this.complete = true;
}
}
});
FileTypesManager.register("obj", function(key, objURL, matURL, flipUVs, xhrSettings) {
var multifile;
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
multifile = new OBJFile(this, key[i]);
this.addFile(multifile.files);
}
} else {
multifile = new OBJFile(this, key, objURL, matURL, flipUVs, xhrSettings);
this.addFile(multifile.files);
}
return this;
});
module2.exports = OBJFile;
}
),
/***/
58610: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(23906);
var FileTypesManager = __webpack_require__2(74099);
var JSONFile = __webpack_require__2(518);
var PackFile = new Class({
Extends: JSONFile,
initialize: (
// url can either be a string, in which case it is treated like a proper url, or an object, in which case it is treated as a ready-made JS Object
// dataKey allows you to pluck a specific object out of the JSON and put just that into the cache, rather than the whole thing
function PackFile2(loader, key, url, xhrSettings, dataKey) {
JSONFile.call(this, loader, key, url, xhrSettings, dataKey);
this.type = "packfile";
}
),
/**
* Called automatically by Loader.nextFile.
* This method controls what extra work this File does with its loaded data.
*
* @method Phaser.Loader.FileTypes.PackFile#onProcess
* @since 3.7.0
*/
onProcess: function() {
if (this.state !== CONST.FILE_POPULATED) {
this.state = CONST.FILE_PROCESSING;
this.data = JSON.parse(this.xhrLoader.responseText);
}
if (this.data.hasOwnProperty("files") && this.config) {
var newData = {};
newData[this.config] = this.data;
this.data = newData;
}
this.loader.addPack(this.data, this.config);
this.onProcessComplete();
}
});
FileTypesManager.register("pack", function(key, url, dataKey, xhrSettings) {
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
this.addFile(new PackFile(this, key[i]));
}
} else {
this.addFile(new PackFile(this, key, url, xhrSettings, dataKey));
}
return this;
});
module2.exports = PackFile;
}
),
/***/
48988: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(23906);
var File = __webpack_require__2(41299);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var IsPlainObject = __webpack_require__2(41212);
var PluginFile = new Class({
Extends: File,
initialize: function PluginFile2(loader, key, url, start, mapping, xhrSettings) {
var extension = "js";
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
url = GetFastValue(config, "url");
xhrSettings = GetFastValue(config, "xhrSettings");
extension = GetFastValue(config, "extension", extension);
start = GetFastValue(config, "start");
mapping = GetFastValue(config, "mapping");
}
var fileConfig = {
type: "plugin",
cache: false,
extension,
responseType: "text",
key,
url,
xhrSettings,
config: {
start,
mapping
}
};
File.call(this, loader, fileConfig);
if (typeof url === "function") {
this.data = url;
this.state = CONST.FILE_POPULATED;
}
},
/**
* Called automatically by Loader.nextFile.
* This method controls what extra work this File does with its loaded data.
*
* @method Phaser.Loader.FileTypes.PluginFile#onProcess
* @since 3.7.0
*/
onProcess: function() {
var pluginManager = this.loader.systems.plugins;
var config = this.config;
var start = GetFastValue(config, "start", false);
var mapping = GetFastValue(config, "mapping", null);
if (this.state === CONST.FILE_POPULATED) {
pluginManager.install(this.key, this.data, start, mapping);
} else {
this.state = CONST.FILE_PROCESSING;
this.data = document.createElement("script");
this.data.language = "javascript";
this.data.type = "text/javascript";
this.data.defer = false;
this.data.text = this.xhrLoader.responseText;
document.head.appendChild(this.data);
var plugin = pluginManager.install(this.key, window[this.key], start, mapping);
if (start || mapping) {
this.loader.systems[mapping] = plugin;
this.loader.scene[mapping] = plugin;
}
}
this.onProcessComplete();
}
});
FileTypesManager.register("plugin", function(key, url, start, mapping, xhrSettings) {
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
this.addFile(new PluginFile(this, key[i]));
}
} else {
this.addFile(new PluginFile(this, key, url, start, mapping, xhrSettings));
}
return this;
});
module2.exports = PluginFile;
}
),
/***/
67397: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(23906);
var File = __webpack_require__2(41299);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var IsPlainObject = __webpack_require__2(41212);
var SVGFile = new Class({
Extends: File,
initialize: function SVGFile2(loader, key, url, svgConfig, xhrSettings) {
var extension = "svg";
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
url = GetFastValue(config, "url");
svgConfig = GetFastValue(config, "svgConfig", {});
xhrSettings = GetFastValue(config, "xhrSettings");
extension = GetFastValue(config, "extension", extension);
}
var fileConfig = {
type: "svg",
cache: loader.textureManager,
extension,
responseType: "text",
key,
url,
xhrSettings,
config: {
width: GetFastValue(svgConfig, "width"),
height: GetFastValue(svgConfig, "height"),
scale: GetFastValue(svgConfig, "scale")
}
};
File.call(this, loader, fileConfig);
},
/**
* Called automatically by Loader.nextFile.
* This method controls what extra work this File does with its loaded data.
*
* @method Phaser.Loader.FileTypes.SVGFile#onProcess
* @since 3.7.0
*/
onProcess: function() {
this.state = CONST.FILE_PROCESSING;
var text = this.xhrLoader.responseText;
var svg = [text];
var width = this.config.width;
var height = this.config.height;
var scale = this.config.scale;
resize: if (width && height || scale) {
var xml = null;
var parser = new DOMParser();
xml = parser.parseFromString(text, "text/xml");
var svgXML = xml.getElementsByTagName("svg")[0];
var hasViewBox = svgXML.hasAttribute("viewBox");
var svgWidth = parseFloat(svgXML.getAttribute("width"));
var svgHeight = parseFloat(svgXML.getAttribute("height"));
if (!hasViewBox && svgWidth && svgHeight) {
svgXML.setAttribute("viewBox", "0 0 " + svgWidth + " " + svgHeight);
} else if (hasViewBox && !svgWidth && !svgHeight) {
var viewBox = svgXML.getAttribute("viewBox").split(/\s+|,/);
svgWidth = viewBox[2];
svgHeight = viewBox[3];
}
if (scale) {
if (svgWidth && svgHeight) {
width = svgWidth * scale;
height = svgHeight * scale;
} else {
break resize;
}
}
svgXML.setAttribute("width", width.toString() + "px");
svgXML.setAttribute("height", height.toString() + "px");
svg = [new XMLSerializer().serializeToString(svgXML)];
}
try {
var blob = new window.Blob(svg, { type: "image/svg+xml;charset=utf-8" });
} catch (e) {
this.onProcessError();
return;
}
this.data = new Image();
this.data.crossOrigin = this.crossOrigin;
var _this = this;
var retry = false;
this.data.onload = function() {
if (!retry) {
File.revokeObjectURL(_this.data);
}
_this.onProcessComplete();
};
this.data.onerror = function() {
if (!retry) {
retry = true;
File.revokeObjectURL(_this.data);
_this.data.src = "data:image/svg+xml," + encodeURIComponent(svg.join(""));
} else {
_this.onProcessError();
}
};
File.createObjectURL(this.data, blob, "image/svg+xml");
},
/**
* Adds this file to its target cache upon successful loading and processing.
*
* @method Phaser.Loader.FileTypes.SVGFile#addToCache
* @since 3.7.0
*/
addToCache: function() {
this.cache.addImage(this.key, this.data);
}
});
FileTypesManager.register("svg", function(key, url, svgConfig, xhrSettings) {
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
this.addFile(new SVGFile(this, key[i]));
}
} else {
this.addFile(new SVGFile(this, key, url, svgConfig, xhrSettings));
}
return this;
});
module2.exports = SVGFile;
}
),
/***/
88423: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(23906);
var File = __webpack_require__2(41299);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var IsPlainObject = __webpack_require__2(41212);
var SceneFile = new Class({
Extends: File,
initialize: function SceneFile2(loader, key, url, xhrSettings) {
var extension = "js";
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
url = GetFastValue(config, "url");
xhrSettings = GetFastValue(config, "xhrSettings");
extension = GetFastValue(config, "extension", extension);
}
var fileConfig = {
type: "text",
extension,
responseType: "text",
key,
url,
xhrSettings
};
File.call(this, loader, fileConfig);
},
/**
* Called automatically by Loader.nextFile.
* This method controls what extra work this File does with its loaded data.
*
* @method Phaser.Loader.FileTypes.SceneFile#onProcess
* @since 3.16.0
*/
onProcess: function() {
this.state = CONST.FILE_PROCESSING;
this.data = this.xhrLoader.responseText;
this.onProcessComplete();
},
/**
* Adds this file to its target cache upon successful loading and processing.
*
* @method Phaser.Loader.FileTypes.SceneFile#addToCache
* @since 3.16.0
*/
addToCache: function() {
var code = this.data.concat("(function(){\nreturn new " + this.key + "();\n}).call(this);");
var eval2 = eval;
this.loader.sceneManager.add(this.key, eval2(code));
this.complete = true;
}
});
FileTypesManager.register("sceneFile", function(key, url, xhrSettings) {
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
this.addFile(new SceneFile(this, key[i]));
}
} else {
this.addFile(new SceneFile(this, key, url, xhrSettings));
}
return this;
});
module2.exports = SceneFile;
}
),
/***/
56812: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(23906);
var File = __webpack_require__2(41299);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var IsPlainObject = __webpack_require__2(41212);
var ScenePluginFile = new Class({
Extends: File,
initialize: function ScenePluginFile2(loader, key, url, systemKey, sceneKey, xhrSettings) {
var extension = "js";
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
url = GetFastValue(config, "url");
xhrSettings = GetFastValue(config, "xhrSettings");
extension = GetFastValue(config, "extension", extension);
systemKey = GetFastValue(config, "systemKey");
sceneKey = GetFastValue(config, "sceneKey");
}
var fileConfig = {
type: "scenePlugin",
cache: false,
extension,
responseType: "text",
key,
url,
xhrSettings,
config: {
systemKey,
sceneKey
}
};
File.call(this, loader, fileConfig);
if (typeof url === "function") {
this.data = url;
this.state = CONST.FILE_POPULATED;
}
},
/**
* Called automatically by Loader.nextFile.
* This method controls what extra work this File does with its loaded data.
*
* @method Phaser.Loader.FileTypes.ScenePluginFile#onProcess
* @since 3.8.0
*/
onProcess: function() {
var pluginManager = this.loader.systems.plugins;
var config = this.config;
var key = this.key;
var systemKey = GetFastValue(config, "systemKey", key);
var sceneKey = GetFastValue(config, "sceneKey", key);
if (this.state === CONST.FILE_POPULATED) {
pluginManager.installScenePlugin(systemKey, this.data, sceneKey, this.loader.scene, true);
} else {
this.state = CONST.FILE_PROCESSING;
this.data = document.createElement("script");
this.data.language = "javascript";
this.data.type = "text/javascript";
this.data.defer = false;
this.data.text = this.xhrLoader.responseText;
document.head.appendChild(this.data);
pluginManager.installScenePlugin(systemKey, window[this.key], sceneKey, this.loader.scene, true);
}
this.onProcessComplete();
}
});
FileTypesManager.register("scenePlugin", function(key, url, systemKey, sceneKey, xhrSettings) {
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
this.addFile(new ScenePluginFile(this, key[i]));
}
} else {
this.addFile(new ScenePluginFile(this, key, url, systemKey, sceneKey, xhrSettings));
}
return this;
});
module2.exports = ScenePluginFile;
}
),
/***/
34328: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(23906);
var File = __webpack_require__2(41299);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var IsPlainObject = __webpack_require__2(41212);
var ScriptFile = new Class({
Extends: File,
initialize: function ScriptFile2(loader, key, url, type, xhrSettings) {
var extension = "js";
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
url = GetFastValue(config, "url");
type = GetFastValue(config, "type", "script");
xhrSettings = GetFastValue(config, "xhrSettings");
extension = GetFastValue(config, "extension", extension);
} else if (type === void 0) {
type = "script";
}
var fileConfig = {
type,
cache: false,
extension,
responseType: "text",
key,
url,
xhrSettings
};
File.call(this, loader, fileConfig);
},
/**
* Called automatically by Loader.nextFile.
* This method controls what extra work this File does with its loaded data.
*
* @method Phaser.Loader.FileTypes.ScriptFile#onProcess
* @since 3.7.0
*/
onProcess: function() {
this.state = CONST.FILE_PROCESSING;
this.data = document.createElement("script");
this.data.language = "javascript";
this.data.type = "text/javascript";
this.data.defer = false;
this.data.text = this.xhrLoader.responseText;
document.head.appendChild(this.data);
this.onProcessComplete();
}
});
FileTypesManager.register("script", function(key, url, type, xhrSettings) {
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
this.addFile(new ScriptFile(this, key[i]));
}
} else {
this.addFile(new ScriptFile(this, key, url, type, xhrSettings));
}
return this;
});
module2.exports = ScriptFile;
}
),
/***/
85035: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(23906);
var FileTypesManager = __webpack_require__2(74099);
var ImageFile = __webpack_require__2(19550);
var SpriteSheetFile = new Class({
Extends: ImageFile,
initialize: function SpriteSheetFile2(loader, key, url, frameConfig, xhrSettings) {
ImageFile.call(this, loader, key, url, xhrSettings, frameConfig);
this.type = "spritesheet";
},
/**
* Adds this file to its target cache upon successful loading and processing.
*
* @method Phaser.Loader.FileTypes.SpriteSheetFile#addToCache
* @since 3.7.0
*/
addToCache: function() {
var linkFile = this.linkFile;
if (linkFile) {
if (linkFile.state >= CONST.FILE_COMPLETE) {
if (this.type === "normalMap") {
this.cache.addSpriteSheet(this.key, linkFile.data, this.config, this.data);
} else {
this.cache.addSpriteSheet(this.key, this.data, this.config, linkFile.data);
}
}
} else {
this.cache.addSpriteSheet(this.key, this.data, this.config);
}
}
});
FileTypesManager.register("spritesheet", function(key, url, frameConfig, xhrSettings) {
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
this.addFile(new SpriteSheetFile(this, key[i]));
}
} else {
this.addFile(new SpriteSheetFile(this, key, url, frameConfig, xhrSettings));
}
return this;
});
module2.exports = SpriteSheetFile;
}
),
/***/
78776: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(23906);
var File = __webpack_require__2(41299);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var IsPlainObject = __webpack_require__2(41212);
var TextFile = new Class({
Extends: File,
initialize: function TextFile2(loader, key, url, xhrSettings) {
var type = "text";
var extension = "txt";
var cache = loader.cacheManager.text;
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
url = GetFastValue(config, "url");
xhrSettings = GetFastValue(config, "xhrSettings");
extension = GetFastValue(config, "extension", extension);
type = GetFastValue(config, "type", type);
cache = GetFastValue(config, "cache", cache);
}
var fileConfig = {
type,
cache,
extension,
responseType: "text",
key,
url,
xhrSettings
};
File.call(this, loader, fileConfig);
},
/**
* Called automatically by Loader.nextFile.
* This method controls what extra work this File does with its loaded data.
*
* @method Phaser.Loader.FileTypes.TextFile#onProcess
* @since 3.7.0
*/
onProcess: function() {
this.state = CONST.FILE_PROCESSING;
this.data = this.xhrLoader.responseText;
this.onProcessComplete();
}
});
FileTypesManager.register("text", function(key, url, xhrSettings) {
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
this.addFile(new TextFile(this, key[i]));
}
} else {
this.addFile(new TextFile(this, key, url, xhrSettings));
}
return this;
});
module2.exports = TextFile;
}
),
/***/
49477: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(23906);
var File = __webpack_require__2(41299);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var IsPlainObject = __webpack_require__2(41212);
var TILEMAP_FORMATS = __webpack_require__2(80341);
var TilemapCSVFile = new Class({
Extends: File,
initialize: function TilemapCSVFile2(loader, key, url, xhrSettings) {
var extension = "csv";
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
url = GetFastValue(config, "url");
xhrSettings = GetFastValue(config, "xhrSettings");
extension = GetFastValue(config, "extension", extension);
}
var fileConfig = {
type: "tilemapCSV",
cache: loader.cacheManager.tilemap,
extension,
responseType: "text",
key,
url,
xhrSettings
};
File.call(this, loader, fileConfig);
this.tilemapFormat = TILEMAP_FORMATS.CSV;
},
/**
* Called automatically by Loader.nextFile.
* This method controls what extra work this File does with its loaded data.
*
* @method Phaser.Loader.FileTypes.TilemapCSVFile#onProcess
* @since 3.7.0
*/
onProcess: function() {
this.state = CONST.FILE_PROCESSING;
this.data = this.xhrLoader.responseText;
this.onProcessComplete();
},
/**
* Adds this file to its target cache upon successful loading and processing.
*
* @method Phaser.Loader.FileTypes.TilemapCSVFile#addToCache
* @since 3.7.0
*/
addToCache: function() {
var tiledata = { format: this.tilemapFormat, data: this.data };
this.cache.add(this.key, tiledata);
}
});
FileTypesManager.register("tilemapCSV", function(key, url, xhrSettings) {
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
this.addFile(new TilemapCSVFile(this, key[i]));
}
} else {
this.addFile(new TilemapCSVFile(this, key, url, xhrSettings));
}
return this;
});
module2.exports = TilemapCSVFile;
}
),
/***/
40807: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var FileTypesManager = __webpack_require__2(74099);
var JSONFile = __webpack_require__2(518);
var TILEMAP_FORMATS = __webpack_require__2(80341);
var TilemapImpactFile = new Class({
Extends: JSONFile,
initialize: function TilemapImpactFile2(loader, key, url, xhrSettings) {
JSONFile.call(this, loader, key, url, xhrSettings);
this.type = "tilemapJSON";
this.cache = loader.cacheManager.tilemap;
},
/**
* Adds this file to its target cache upon successful loading and processing.
*
* @method Phaser.Loader.FileTypes.TilemapImpactFile#addToCache
* @since 3.7.0
*/
addToCache: function() {
var tiledata = { format: TILEMAP_FORMATS.WELTMEISTER, data: this.data };
this.cache.add(this.key, tiledata);
}
});
FileTypesManager.register("tilemapImpact", function(key, url, xhrSettings) {
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
this.addFile(new TilemapImpactFile(this, key[i]));
}
} else {
this.addFile(new TilemapImpactFile(this, key, url, xhrSettings));
}
return this;
});
module2.exports = TilemapImpactFile;
}
),
/***/
56775: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var FileTypesManager = __webpack_require__2(74099);
var JSONFile = __webpack_require__2(518);
var TILEMAP_FORMATS = __webpack_require__2(80341);
var TilemapJSONFile = new Class({
Extends: JSONFile,
initialize: function TilemapJSONFile2(loader, key, url, xhrSettings) {
JSONFile.call(this, loader, key, url, xhrSettings);
this.type = "tilemapJSON";
this.cache = loader.cacheManager.tilemap;
},
/**
* Adds this file to its target cache upon successful loading and processing.
*
* @method Phaser.Loader.FileTypes.TilemapJSONFile#addToCache
* @since 3.7.0
*/
addToCache: function() {
var tiledata = { format: TILEMAP_FORMATS.TILED_JSON, data: this.data };
this.cache.add(this.key, tiledata);
}
});
FileTypesManager.register("tilemapTiledJSON", function(key, url, xhrSettings) {
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
this.addFile(new TilemapJSONFile(this, key[i]));
}
} else {
this.addFile(new TilemapJSONFile(this, key, url, xhrSettings));
}
return this;
});
module2.exports = TilemapJSONFile;
}
),
/***/
25771: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var ImageFile = __webpack_require__2(19550);
var IsPlainObject = __webpack_require__2(41212);
var MultiFile = __webpack_require__2(26430);
var TextFile = __webpack_require__2(78776);
var UnityAtlasFile = new Class({
Extends: MultiFile,
initialize: function UnityAtlasFile2(loader, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) {
var image;
var data;
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
image = new ImageFile(loader, {
key,
url: GetFastValue(config, "textureURL"),
extension: GetFastValue(config, "textureExtension", "png"),
normalMap: GetFastValue(config, "normalMap"),
xhrSettings: GetFastValue(config, "textureXhrSettings")
});
data = new TextFile(loader, {
key,
url: GetFastValue(config, "atlasURL"),
extension: GetFastValue(config, "atlasExtension", "txt"),
xhrSettings: GetFastValue(config, "atlasXhrSettings")
});
} else {
image = new ImageFile(loader, key, textureURL, textureXhrSettings);
data = new TextFile(loader, key, atlasURL, atlasXhrSettings);
}
if (image.linkFile) {
MultiFile.call(this, loader, "unityatlas", key, [image, data, image.linkFile]);
} else {
MultiFile.call(this, loader, "unityatlas", key, [image, data]);
}
},
/**
* Adds this file to its target cache upon successful loading and processing.
*
* @method Phaser.Loader.FileTypes.UnityAtlasFile#addToCache
* @since 3.7.0
*/
addToCache: function() {
if (this.isReadyToProcess()) {
var image = this.files[0];
var text = this.files[1];
var normalMap = this.files[2] ? this.files[2].data : null;
this.loader.textureManager.addUnityAtlas(image.key, image.data, text.data, normalMap);
this.complete = true;
}
}
});
FileTypesManager.register("unityAtlas", function(key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings) {
var multifile;
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
multifile = new UnityAtlasFile(this, key[i]);
this.addFile(multifile.files);
}
} else {
multifile = new UnityAtlasFile(this, key, textureURL, atlasURL, textureXhrSettings, atlasXhrSettings);
this.addFile(multifile.files);
}
return this;
});
module2.exports = UnityAtlasFile;
}
),
/***/
33720: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(23906);
var File = __webpack_require__2(41299);
var FileTypesManager = __webpack_require__2(74099);
var GetURL = __webpack_require__2(98356);
var GetFastValue = __webpack_require__2(95540);
var IsPlainObject = __webpack_require__2(41212);
var VideoFile = new Class({
Extends: File,
initialize: function VideoFile2(loader, key, url, noAudio) {
if (noAudio === void 0) {
noAudio = false;
}
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
url = GetFastValue(config, "url", []);
noAudio = GetFastValue(config, "noAudio", false);
}
var urlConfig = loader.systems.game.device.video.getVideoURL(url);
if (!urlConfig) {
console.warn("VideoFile: No supported format for " + key);
}
var fileConfig = {
type: "video",
cache: loader.cacheManager.video,
extension: urlConfig.type,
key,
url: urlConfig.url,
config: {
noAudio
}
};
File.call(this, loader, fileConfig);
},
/**
* Called automatically by Loader.nextFile.
* This method controls what extra work this File does with its loaded data.
*
* @method Phaser.Loader.FileTypes.VideoFile#onProcess
* @since 3.20.0
*/
onProcess: function() {
this.data = {
url: this.src,
noAudio: this.config.noAudio,
crossOrigin: this.crossOrigin
};
this.onProcessComplete();
},
/**
* Called by the Loader, starts the actual file downloading.
* During the load the methods onLoad, onError and onProgress are called, based on the XHR events.
* You shouldn't normally call this method directly, it's meant to be invoked by the Loader.
*
* @method Phaser.Loader.FileTypes.VideoFile#load
* @since 3.20.0
*/
load: function() {
this.src = GetURL(this, this.loader.baseURL);
this.state = CONST.FILE_LOADED;
this.loader.nextFile(this, true);
}
});
FileTypesManager.register("video", function(key, urls, noAudio) {
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
this.addFile(new VideoFile(this, key[i]));
}
} else {
this.addFile(new VideoFile(this, key, urls, noAudio));
}
return this;
});
module2.exports = VideoFile;
}
),
/***/
57318: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(23906);
var File = __webpack_require__2(41299);
var FileTypesManager = __webpack_require__2(74099);
var GetFastValue = __webpack_require__2(95540);
var IsPlainObject = __webpack_require__2(41212);
var ParseXML = __webpack_require__2(56836);
var XMLFile = new Class({
Extends: File,
initialize: function XMLFile2(loader, key, url, xhrSettings) {
var extension = "xml";
if (IsPlainObject(key)) {
var config = key;
key = GetFastValue(config, "key");
url = GetFastValue(config, "url");
xhrSettings = GetFastValue(config, "xhrSettings");
extension = GetFastValue(config, "extension", extension);
}
var fileConfig = {
type: "xml",
cache: loader.cacheManager.xml,
extension,
responseType: "text",
key,
url,
xhrSettings
};
File.call(this, loader, fileConfig);
},
/**
* Called automatically by Loader.nextFile.
* This method controls what extra work this File does with its loaded data.
*
* @method Phaser.Loader.FileTypes.XMLFile#onProcess
* @since 3.7.0
*/
onProcess: function() {
this.state = CONST.FILE_PROCESSING;
this.data = ParseXML(this.xhrLoader.responseText);
if (this.data) {
this.onProcessComplete();
} else {
this.onProcessError();
}
}
});
FileTypesManager.register("xml", function(key, url, xhrSettings) {
if (Array.isArray(key)) {
for (var i = 0; i < key.length; i++) {
this.addFile(new XMLFile(this, key[i]));
}
} else {
this.addFile(new XMLFile(this, key, url, xhrSettings));
}
return this;
});
module2.exports = XMLFile;
}
),
/***/
64589: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
AnimationJSONFile: __webpack_require__2(14135),
AsepriteFile: __webpack_require__2(76272),
AtlasJSONFile: __webpack_require__2(38734),
AtlasXMLFile: __webpack_require__2(74599),
AudioFile: __webpack_require__2(21097),
AudioSpriteFile: __webpack_require__2(89524),
BinaryFile: __webpack_require__2(85722),
BitmapFontFile: __webpack_require__2(97025),
CompressedTextureFile: __webpack_require__2(69559),
CSSFile: __webpack_require__2(16024),
GLSLFile: __webpack_require__2(47931),
HTML5AudioFile: __webpack_require__2(89749),
HTMLFile: __webpack_require__2(88470),
HTMLTextureFile: __webpack_require__2(14643),
ImageFile: __webpack_require__2(19550),
JSONFile: __webpack_require__2(518),
MultiAtlasFile: __webpack_require__2(59327),
MultiScriptFile: __webpack_require__2(99297),
OBJFile: __webpack_require__2(41846),
PackFile: __webpack_require__2(58610),
PluginFile: __webpack_require__2(48988),
SceneFile: __webpack_require__2(88423),
ScenePluginFile: __webpack_require__2(56812),
ScriptFile: __webpack_require__2(34328),
SpriteSheetFile: __webpack_require__2(85035),
SVGFile: __webpack_require__2(67397),
TextFile: __webpack_require__2(78776),
TilemapCSVFile: __webpack_require__2(49477),
TilemapImpactFile: __webpack_require__2(40807),
TilemapJSONFile: __webpack_require__2(56775),
UnityAtlasFile: __webpack_require__2(25771),
VideoFile: __webpack_require__2(33720),
XMLFile: __webpack_require__2(57318)
};
}
),
/***/
57777: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(23906);
var Extend = __webpack_require__2(79291);
var Loader = {
Events: __webpack_require__2(54899),
FileTypes: __webpack_require__2(64589),
File: __webpack_require__2(41299),
FileTypesManager: __webpack_require__2(74099),
GetURL: __webpack_require__2(98356),
LoaderPlugin: __webpack_require__2(74261),
MergeXHRSettings: __webpack_require__2(3374),
MultiFile: __webpack_require__2(26430),
XHRLoader: __webpack_require__2(84376),
XHRSettings: __webpack_require__2(92638)
};
Loader = Extend(false, Loader, CONST);
module2.exports = Loader;
}
),
/***/
53307: (
/***/
(module2) => {
var Average = function(values) {
var sum = 0;
for (var i = 0; i < values.length; i++) {
sum += +values[i];
}
return sum / values.length;
};
module2.exports = Average;
}
),
/***/
85710: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Factorial = __webpack_require__2(6411);
var Bernstein = function(n, i) {
return Factorial(n) / Factorial(i) / Factorial(n - i);
};
module2.exports = Bernstein;
}
),
/***/
30976: (
/***/
(module2) => {
var Between = function(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
};
module2.exports = Between;
}
),
/***/
87842: (
/***/
(module2) => {
var CatmullRom = function(t, p0, p1, p2, p3) {
var v0 = (p2 - p0) * 0.5;
var v1 = (p3 - p1) * 0.5;
var t2 = t * t;
var t3 = t * t2;
return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1;
};
module2.exports = CatmullRom;
}
),
/***/
26302: (
/***/
(module2) => {
var CeilTo = function(value, place, base) {
if (place === void 0) {
place = 0;
}
if (base === void 0) {
base = 10;
}
var p = Math.pow(base, -place);
return Math.ceil(value * p) / p;
};
module2.exports = CeilTo;
}
),
/***/
45319: (
/***/
(module2) => {
var Clamp = function(value, min, max) {
return Math.max(min, Math.min(max, value));
};
module2.exports = Clamp;
}
),
/***/
39506: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(36383);
var DegToRad = function(degrees) {
return degrees * CONST.DEG_TO_RAD;
};
module2.exports = DegToRad;
}
),
/***/
61241: (
/***/
(module2) => {
var Difference = function(a, b) {
return Math.abs(a - b);
};
module2.exports = Difference;
}
),
/***/
38857: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Clamp = __webpack_require__2(45319);
var Class = __webpack_require__2(83419);
var Matrix4 = __webpack_require__2(37867);
var NOOP = __webpack_require__2(29747);
var tempMatrix = new Matrix4();
var Euler = new Class({
initialize: function Euler2(x, y, z, order) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (z === void 0) {
z = 0;
}
if (order === void 0) {
order = Euler2.DefaultOrder;
}
this._x = x;
this._y = y;
this._z = z;
this._order = order;
this.onChangeCallback = NOOP;
},
x: {
get: function() {
return this._x;
},
set: function(value) {
this._x = value;
this.onChangeCallback(this);
}
},
y: {
get: function() {
return this._y;
},
set: function(value) {
this._y = value;
this.onChangeCallback(this);
}
},
z: {
get: function() {
return this._z;
},
set: function(value) {
this._z = value;
this.onChangeCallback(this);
}
},
order: {
get: function() {
return this._order;
},
set: function(value) {
this._order = value;
this.onChangeCallback(this);
}
},
set: function(x, y, z, order) {
if (order === void 0) {
order = this._order;
}
this._x = x;
this._y = y;
this._z = z;
this._order = order;
this.onChangeCallback(this);
return this;
},
copy: function(euler) {
return this.set(euler.x, euler.y, euler.z, euler.order);
},
setFromQuaternion: function(quaternion, order, update) {
if (order === void 0) {
order = this._order;
}
if (update === void 0) {
update = false;
}
tempMatrix.fromQuat(quaternion);
return this.setFromRotationMatrix(tempMatrix, order, update);
},
setFromRotationMatrix: function(matrix, order, update) {
if (order === void 0) {
order = this._order;
}
if (update === void 0) {
update = false;
}
var elements = matrix.val;
var m11 = elements[0];
var m12 = elements[4];
var m13 = elements[8];
var m21 = elements[1];
var m22 = elements[5];
var m23 = elements[9];
var m31 = elements[2];
var m32 = elements[6];
var m33 = elements[10];
var x = 0;
var y = 0;
var z = 0;
var epsilon = 0.99999;
switch (order) {
case "XYZ": {
y = Math.asin(Clamp(m13, -1, 1));
if (Math.abs(m13) < epsilon) {
x = Math.atan2(-m23, m33);
z = Math.atan2(-m12, m11);
} else {
x = Math.atan2(m32, m22);
}
break;
}
case "YXZ": {
x = Math.asin(-Clamp(m23, -1, 1));
if (Math.abs(m23) < epsilon) {
y = Math.atan2(m13, m33);
z = Math.atan2(m21, m22);
} else {
y = Math.atan2(-m31, m11);
}
break;
}
case "ZXY": {
x = Math.asin(Clamp(m32, -1, 1));
if (Math.abs(m32) < epsilon) {
y = Math.atan2(-m31, m33);
z = Math.atan2(-m12, m22);
} else {
z = Math.atan2(m21, m11);
}
break;
}
case "ZYX": {
y = Math.asin(-Clamp(m31, -1, 1));
if (Math.abs(m31) < epsilon) {
x = Math.atan2(m32, m33);
z = Math.atan2(m21, m11);
} else {
z = Math.atan2(-m12, m22);
}
break;
}
case "YZX": {
z = Math.asin(Clamp(m21, -1, 1));
if (Math.abs(m21) < epsilon) {
x = Math.atan2(-m23, m22);
y = Math.atan2(-m31, m11);
} else {
y = Math.atan2(m13, m33);
}
break;
}
case "XZY": {
z = Math.asin(-Clamp(m12, -1, 1));
if (Math.abs(m12) < epsilon) {
x = Math.atan2(m32, m22);
y = Math.atan2(m13, m11);
} else {
x = Math.atan2(-m23, m33);
}
break;
}
}
this._x = x;
this._y = y;
this._z = z;
this._order = order;
if (update) {
this.onChangeCallback(this);
}
return this;
}
});
Euler.RotationOrders = ["XYZ", "YXZ", "ZXY", "ZYX", "YZX", "XZY"];
Euler.DefaultOrder = "XYZ";
module2.exports = Euler;
}
),
/***/
6411: (
/***/
(module2) => {
var Factorial = function(value) {
if (value === 0) {
return 1;
}
var res = value;
while (--value) {
res *= value;
}
return res;
};
module2.exports = Factorial;
}
),
/***/
99472: (
/***/
(module2) => {
var FloatBetween = function(min, max) {
return Math.random() * (max - min) + min;
};
module2.exports = FloatBetween;
}
),
/***/
77623: (
/***/
(module2) => {
var FloorTo = function(value, place, base) {
if (place === void 0) {
place = 0;
}
if (base === void 0) {
base = 10;
}
var p = Math.pow(base, -place);
return Math.floor(value * p) / p;
};
module2.exports = FloorTo;
}
),
/***/
62945: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Clamp = __webpack_require__2(45319);
var FromPercent = function(percent, min, max) {
percent = Clamp(percent, 0, 1);
return (max - min) * percent + min;
};
module2.exports = FromPercent;
}
),
/***/
38265: (
/***/
(module2) => {
var GetSpeed = function(distance, time) {
return distance / time / 1e3;
};
module2.exports = GetSpeed;
}
),
/***/
78702: (
/***/
(module2) => {
var IsEven = function(value) {
return value == parseFloat(value) ? !(value % 2) : void 0;
};
module2.exports = IsEven;
}
),
/***/
94883: (
/***/
(module2) => {
var IsEvenStrict = function(value) {
return value === parseFloat(value) ? !(value % 2) : void 0;
};
module2.exports = IsEvenStrict;
}
),
/***/
28915: (
/***/
(module2) => {
var Linear = function(p0, p1, t) {
return (p1 - p0) * t + p0;
};
module2.exports = Linear;
}
),
/***/
94908: (
/***/
(module2) => {
var LinearXY = function(vector1, vector2, t) {
if (t === void 0) {
t = 0;
}
return vector1.clone().lerp(vector2, t);
};
module2.exports = LinearXY;
}
),
/***/
94434: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Matrix3 = new Class({
initialize: function Matrix32(m) {
this.val = new Float32Array(9);
if (m) {
this.copy(m);
} else {
this.identity();
}
},
/**
* Make a clone of this Matrix3.
*
* @method Phaser.Math.Matrix3#clone
* @since 3.0.0
*
* @return {Phaser.Math.Matrix3} A clone of this Matrix3.
*/
clone: function() {
return new Matrix3(this);
},
/**
* This method is an alias for `Matrix3.copy`.
*
* @method Phaser.Math.Matrix3#set
* @since 3.0.0
*
* @param {Phaser.Math.Matrix3} src - The Matrix to set the values of this Matrix's from.
*
* @return {Phaser.Math.Matrix3} This Matrix3.
*/
set: function(src) {
return this.copy(src);
},
/**
* Copy the values of a given Matrix into this Matrix.
*
* @method Phaser.Math.Matrix3#copy
* @since 3.0.0
*
* @param {Phaser.Math.Matrix3} src - The Matrix to copy the values from.
*
* @return {Phaser.Math.Matrix3} This Matrix3.
*/
copy: function(src) {
var out = this.val;
var a = src.val;
out[0] = a[0];
out[1] = a[1];
out[2] = a[2];
out[3] = a[3];
out[4] = a[4];
out[5] = a[5];
out[6] = a[6];
out[7] = a[7];
out[8] = a[8];
return this;
},
/**
* Copy the values of a given Matrix4 into this Matrix3.
*
* @method Phaser.Math.Matrix3#fromMat4
* @since 3.0.0
*
* @param {Phaser.Math.Matrix4} m - The Matrix4 to copy the values from.
*
* @return {Phaser.Math.Matrix3} This Matrix3.
*/
fromMat4: function(m) {
var a = m.val;
var out = this.val;
out[0] = a[0];
out[1] = a[1];
out[2] = a[2];
out[3] = a[4];
out[4] = a[5];
out[5] = a[6];
out[6] = a[8];
out[7] = a[9];
out[8] = a[10];
return this;
},
/**
* Set the values of this Matrix from the given array.
*
* @method Phaser.Math.Matrix3#fromArray
* @since 3.0.0
*
* @param {array} a - The array to copy the values from.
*
* @return {Phaser.Math.Matrix3} This Matrix3.
*/
fromArray: function(a) {
var out = this.val;
out[0] = a[0];
out[1] = a[1];
out[2] = a[2];
out[3] = a[3];
out[4] = a[4];
out[5] = a[5];
out[6] = a[6];
out[7] = a[7];
out[8] = a[8];
return this;
},
/**
* Reset this Matrix to an identity (default) matrix.
*
* @method Phaser.Math.Matrix3#identity
* @since 3.0.0
*
* @return {Phaser.Math.Matrix3} This Matrix3.
*/
identity: function() {
var out = this.val;
out[0] = 1;
out[1] = 0;
out[2] = 0;
out[3] = 0;
out[4] = 1;
out[5] = 0;
out[6] = 0;
out[7] = 0;
out[8] = 1;
return this;
},
/**
* Transpose this Matrix.
*
* @method Phaser.Math.Matrix3#transpose
* @since 3.0.0
*
* @return {Phaser.Math.Matrix3} This Matrix3.
*/
transpose: function() {
var a = this.val;
var a01 = a[1];
var a02 = a[2];
var a12 = a[5];
a[1] = a[3];
a[2] = a[6];
a[3] = a01;
a[5] = a[7];
a[6] = a02;
a[7] = a12;
return this;
},
/**
* Invert this Matrix.
*
* @method Phaser.Math.Matrix3#invert
* @since 3.0.0
*
* @return {Phaser.Math.Matrix3} This Matrix3.
*/
invert: function() {
var a = this.val;
var a00 = a[0];
var a01 = a[1];
var a02 = a[2];
var a10 = a[3];
var a11 = a[4];
var a12 = a[5];
var a20 = a[6];
var a21 = a[7];
var a22 = a[8];
var b01 = a22 * a11 - a12 * a21;
var b11 = -a22 * a10 + a12 * a20;
var b21 = a21 * a10 - a11 * a20;
var det = a00 * b01 + a01 * b11 + a02 * b21;
if (!det) {
return null;
}
det = 1 / det;
a[0] = b01 * det;
a[1] = (-a22 * a01 + a02 * a21) * det;
a[2] = (a12 * a01 - a02 * a11) * det;
a[3] = b11 * det;
a[4] = (a22 * a00 - a02 * a20) * det;
a[5] = (-a12 * a00 + a02 * a10) * det;
a[6] = b21 * det;
a[7] = (-a21 * a00 + a01 * a20) * det;
a[8] = (a11 * a00 - a01 * a10) * det;
return this;
},
/**
* Calculate the adjoint, or adjugate, of this Matrix.
*
* @method Phaser.Math.Matrix3#adjoint
* @since 3.0.0
*
* @return {Phaser.Math.Matrix3} This Matrix3.
*/
adjoint: function() {
var a = this.val;
var a00 = a[0];
var a01 = a[1];
var a02 = a[2];
var a10 = a[3];
var a11 = a[4];
var a12 = a[5];
var a20 = a[6];
var a21 = a[7];
var a22 = a[8];
a[0] = a11 * a22 - a12 * a21;
a[1] = a02 * a21 - a01 * a22;
a[2] = a01 * a12 - a02 * a11;
a[3] = a12 * a20 - a10 * a22;
a[4] = a00 * a22 - a02 * a20;
a[5] = a02 * a10 - a00 * a12;
a[6] = a10 * a21 - a11 * a20;
a[7] = a01 * a20 - a00 * a21;
a[8] = a00 * a11 - a01 * a10;
return this;
},
/**
* Calculate the determinant of this Matrix.
*
* @method Phaser.Math.Matrix3#determinant
* @since 3.0.0
*
* @return {number} The determinant of this Matrix.
*/
determinant: function() {
var a = this.val;
var a00 = a[0];
var a01 = a[1];
var a02 = a[2];
var a10 = a[3];
var a11 = a[4];
var a12 = a[5];
var a20 = a[6];
var a21 = a[7];
var a22 = a[8];
return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20);
},
/**
* Multiply this Matrix by the given Matrix.
*
* @method Phaser.Math.Matrix3#multiply
* @since 3.0.0
*
* @param {Phaser.Math.Matrix3} src - The Matrix to multiply this Matrix by.
*
* @return {Phaser.Math.Matrix3} This Matrix3.
*/
multiply: function(src) {
var a = this.val;
var a00 = a[0];
var a01 = a[1];
var a02 = a[2];
var a10 = a[3];
var a11 = a[4];
var a12 = a[5];
var a20 = a[6];
var a21 = a[7];
var a22 = a[8];
var b = src.val;
var b00 = b[0];
var b01 = b[1];
var b02 = b[2];
var b10 = b[3];
var b11 = b[4];
var b12 = b[5];
var b20 = b[6];
var b21 = b[7];
var b22 = b[8];
a[0] = b00 * a00 + b01 * a10 + b02 * a20;
a[1] = b00 * a01 + b01 * a11 + b02 * a21;
a[2] = b00 * a02 + b01 * a12 + b02 * a22;
a[3] = b10 * a00 + b11 * a10 + b12 * a20;
a[4] = b10 * a01 + b11 * a11 + b12 * a21;
a[5] = b10 * a02 + b11 * a12 + b12 * a22;
a[6] = b20 * a00 + b21 * a10 + b22 * a20;
a[7] = b20 * a01 + b21 * a11 + b22 * a21;
a[8] = b20 * a02 + b21 * a12 + b22 * a22;
return this;
},
/**
* Translate this Matrix using the given Vector.
*
* @method Phaser.Math.Matrix3#translate
* @since 3.0.0
*
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to translate this Matrix with.
*
* @return {Phaser.Math.Matrix3} This Matrix3.
*/
translate: function(v) {
var a = this.val;
var x = v.x;
var y = v.y;
a[6] = x * a[0] + y * a[3] + a[6];
a[7] = x * a[1] + y * a[4] + a[7];
a[8] = x * a[2] + y * a[5] + a[8];
return this;
},
/**
* Apply a rotation transformation to this Matrix.
*
* @method Phaser.Math.Matrix3#rotate
* @since 3.0.0
*
* @param {number} rad - The angle in radians to rotate by.
*
* @return {Phaser.Math.Matrix3} This Matrix3.
*/
rotate: function(rad) {
var a = this.val;
var a00 = a[0];
var a01 = a[1];
var a02 = a[2];
var a10 = a[3];
var a11 = a[4];
var a12 = a[5];
var s = Math.sin(rad);
var c = Math.cos(rad);
a[0] = c * a00 + s * a10;
a[1] = c * a01 + s * a11;
a[2] = c * a02 + s * a12;
a[3] = c * a10 - s * a00;
a[4] = c * a11 - s * a01;
a[5] = c * a12 - s * a02;
return this;
},
/**
* Apply a scale transformation to this Matrix.
*
* Uses the `x` and `y` components of the given Vector to scale the Matrix.
*
* @method Phaser.Math.Matrix3#scale
* @since 3.0.0
*
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to scale this Matrix with.
*
* @return {Phaser.Math.Matrix3} This Matrix3.
*/
scale: function(v) {
var a = this.val;
var x = v.x;
var y = v.y;
a[0] = x * a[0];
a[1] = x * a[1];
a[2] = x * a[2];
a[3] = y * a[3];
a[4] = y * a[4];
a[5] = y * a[5];
return this;
},
/**
* Set the values of this Matrix from the given Quaternion.
*
* @method Phaser.Math.Matrix3#fromQuat
* @since 3.0.0
*
* @param {Phaser.Math.Quaternion} q - The Quaternion to set the values of this Matrix from.
*
* @return {Phaser.Math.Matrix3} This Matrix3.
*/
fromQuat: function(q) {
var x = q.x;
var y = q.y;
var z = q.z;
var w = q.w;
var x2 = x + x;
var y2 = y + y;
var z2 = z + z;
var xx = x * x2;
var xy = x * y2;
var xz = x * z2;
var yy = y * y2;
var yz = y * z2;
var zz = z * z2;
var wx = w * x2;
var wy = w * y2;
var wz = w * z2;
var out = this.val;
out[0] = 1 - (yy + zz);
out[3] = xy + wz;
out[6] = xz - wy;
out[1] = xy - wz;
out[4] = 1 - (xx + zz);
out[7] = yz + wx;
out[2] = xz + wy;
out[5] = yz - wx;
out[8] = 1 - (xx + yy);
return this;
},
/**
* Set the values of this Matrix3 to be normalized from the given Matrix4.
*
* @method Phaser.Math.Matrix3#normalFromMat4
* @since 3.0.0
*
* @param {Phaser.Math.Matrix4} m - The Matrix4 to normalize the values from.
*
* @return {Phaser.Math.Matrix3} This Matrix3.
*/
normalFromMat4: function(m) {
var a = m.val;
var out = this.val;
var a00 = a[0];
var a01 = a[1];
var a02 = a[2];
var a03 = a[3];
var a10 = a[4];
var a11 = a[5];
var a12 = a[6];
var a13 = a[7];
var a20 = a[8];
var a21 = a[9];
var a22 = a[10];
var a23 = a[11];
var a30 = a[12];
var a31 = a[13];
var a32 = a[14];
var a33 = a[15];
var b00 = a00 * a11 - a01 * a10;
var b01 = a00 * a12 - a02 * a10;
var b02 = a00 * a13 - a03 * a10;
var b03 = a01 * a12 - a02 * a11;
var b04 = a01 * a13 - a03 * a11;
var b05 = a02 * a13 - a03 * a12;
var b06 = a20 * a31 - a21 * a30;
var b07 = a20 * a32 - a22 * a30;
var b08 = a20 * a33 - a23 * a30;
var b09 = a21 * a32 - a22 * a31;
var b10 = a21 * a33 - a23 * a31;
var b11 = a22 * a33 - a23 * a32;
var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
if (!det) {
return null;
}
det = 1 / det;
out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
return this;
}
});
module2.exports = Matrix3;
}
),
/***/
37867: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Vector3 = __webpack_require__2(25836);
var EPSILON = 1e-6;
var Matrix4 = new Class({
initialize: function Matrix42(m) {
this.val = new Float32Array(16);
if (m) {
this.copy(m);
} else {
this.identity();
}
},
/**
* Make a clone of this Matrix4.
*
* @method Phaser.Math.Matrix4#clone
* @since 3.0.0
*
* @return {Phaser.Math.Matrix4} A clone of this Matrix4.
*/
clone: function() {
return new Matrix4(this);
},
/**
* This method is an alias for `Matrix4.copy`.
*
* @method Phaser.Math.Matrix4#set
* @since 3.0.0
*
* @param {Phaser.Math.Matrix4} src - The Matrix to set the values of this Matrix's from.
*
* @return {this} This Matrix4.
*/
set: function(src) {
return this.copy(src);
},
/**
* Sets all values of this Matrix4.
*
* @method Phaser.Math.Matrix4#setValues
* @since 3.50.0
*
* @param {number} m00 - The m00 value.
* @param {number} m01 - The m01 value.
* @param {number} m02 - The m02 value.
* @param {number} m03 - The m03 value.
* @param {number} m10 - The m10 value.
* @param {number} m11 - The m11 value.
* @param {number} m12 - The m12 value.
* @param {number} m13 - The m13 value.
* @param {number} m20 - The m20 value.
* @param {number} m21 - The m21 value.
* @param {number} m22 - The m22 value.
* @param {number} m23 - The m23 value.
* @param {number} m30 - The m30 value.
* @param {number} m31 - The m31 value.
* @param {number} m32 - The m32 value.
* @param {number} m33 - The m33 value.
*
* @return {this} This Matrix4 instance.
*/
setValues: function(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {
var out = this.val;
out[0] = m00;
out[1] = m01;
out[2] = m02;
out[3] = m03;
out[4] = m10;
out[5] = m11;
out[6] = m12;
out[7] = m13;
out[8] = m20;
out[9] = m21;
out[10] = m22;
out[11] = m23;
out[12] = m30;
out[13] = m31;
out[14] = m32;
out[15] = m33;
return this;
},
/**
* Copy the values of a given Matrix into this Matrix.
*
* @method Phaser.Math.Matrix4#copy
* @since 3.0.0
*
* @param {Phaser.Math.Matrix4} src - The Matrix to copy the values from.
*
* @return {this} This Matrix4.
*/
copy: function(src) {
var a = src.val;
return this.setValues(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]);
},
/**
* Set the values of this Matrix from the given array.
*
* @method Phaser.Math.Matrix4#fromArray
* @since 3.0.0
*
* @param {number[]} a - The array to copy the values from. Must have at least 16 elements.
*
* @return {this} This Matrix4.
*/
fromArray: function(a) {
return this.setValues(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]);
},
/**
* Reset this Matrix.
*
* Sets all values to `0`.
*
* @method Phaser.Math.Matrix4#zero
* @since 3.0.0
*
* @return {Phaser.Math.Matrix4} This Matrix4.
*/
zero: function() {
return this.setValues(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
},
/**
* Generates a transform matrix based on the given position, scale and rotation.
*
* @method Phaser.Math.Matrix4#transform
* @since 3.50.0
*
* @param {Phaser.Math.Vector3} position - The position vector.
* @param {Phaser.Math.Vector3} scale - The scale vector.
* @param {Phaser.Math.Quaternion} rotation - The rotation quaternion.
*
* @return {this} This Matrix4.
*/
transform: function(position, scale, rotation) {
var rotMatrix = _tempMat1.fromQuat(rotation);
var rm = rotMatrix.val;
var sx = scale.x;
var sy = scale.y;
var sz = scale.z;
return this.setValues(
rm[0] * sx,
rm[1] * sx,
rm[2] * sx,
0,
rm[4] * sy,
rm[5] * sy,
rm[6] * sy,
0,
rm[8] * sz,
rm[9] * sz,
rm[10] * sz,
0,
position.x,
position.y,
position.z,
1
);
},
/**
* Set the `x`, `y` and `z` values of this Matrix.
*
* @method Phaser.Math.Matrix4#xyz
* @since 3.0.0
*
* @param {number} x - The x value.
* @param {number} y - The y value.
* @param {number} z - The z value.
*
* @return {this} This Matrix4.
*/
xyz: function(x, y, z) {
this.identity();
var out = this.val;
out[12] = x;
out[13] = y;
out[14] = z;
return this;
},
/**
* Set the scaling values of this Matrix.
*
* @method Phaser.Math.Matrix4#scaling
* @since 3.0.0
*
* @param {number} x - The x scaling value.
* @param {number} y - The y scaling value.
* @param {number} z - The z scaling value.
*
* @return {this} This Matrix4.
*/
scaling: function(x, y, z) {
this.zero();
var out = this.val;
out[0] = x;
out[5] = y;
out[10] = z;
out[15] = 1;
return this;
},
/**
* Reset this Matrix to an identity (default) matrix.
*
* @method Phaser.Math.Matrix4#identity
* @since 3.0.0
*
* @return {this} This Matrix4.
*/
identity: function() {
return this.setValues(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
},
/**
* Transpose this Matrix.
*
* @method Phaser.Math.Matrix4#transpose
* @since 3.0.0
*
* @return {this} This Matrix4.
*/
transpose: function() {
var a = this.val;
var a01 = a[1];
var a02 = a[2];
var a03 = a[3];
var a12 = a[6];
var a13 = a[7];
var a23 = a[11];
a[1] = a[4];
a[2] = a[8];
a[3] = a[12];
a[4] = a01;
a[6] = a[9];
a[7] = a[13];
a[8] = a02;
a[9] = a12;
a[11] = a[14];
a[12] = a03;
a[13] = a13;
a[14] = a23;
return this;
},
/**
* Copies the given Matrix4 into this Matrix and then inverses it.
*
* @method Phaser.Math.Matrix4#getInverse
* @since 3.50.0
*
* @param {Phaser.Math.Matrix4} m - The Matrix4 to invert into this Matrix4.
*
* @return {this} This Matrix4.
*/
getInverse: function(m) {
this.copy(m);
return this.invert();
},
/**
* Invert this Matrix.
*
* @method Phaser.Math.Matrix4#invert
* @since 3.0.0
*
* @return {this} This Matrix4.
*/
invert: function() {
var a = this.val;
var a00 = a[0];
var a01 = a[1];
var a02 = a[2];
var a03 = a[3];
var a10 = a[4];
var a11 = a[5];
var a12 = a[6];
var a13 = a[7];
var a20 = a[8];
var a21 = a[9];
var a22 = a[10];
var a23 = a[11];
var a30 = a[12];
var a31 = a[13];
var a32 = a[14];
var a33 = a[15];
var b00 = a00 * a11 - a01 * a10;
var b01 = a00 * a12 - a02 * a10;
var b02 = a00 * a13 - a03 * a10;
var b03 = a01 * a12 - a02 * a11;
var b04 = a01 * a13 - a03 * a11;
var b05 = a02 * a13 - a03 * a12;
var b06 = a20 * a31 - a21 * a30;
var b07 = a20 * a32 - a22 * a30;
var b08 = a20 * a33 - a23 * a30;
var b09 = a21 * a32 - a22 * a31;
var b10 = a21 * a33 - a23 * a31;
var b11 = a22 * a33 - a23 * a32;
var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
if (!det) {
return this;
}
det = 1 / det;
return this.setValues(
(a11 * b11 - a12 * b10 + a13 * b09) * det,
(a02 * b10 - a01 * b11 - a03 * b09) * det,
(a31 * b05 - a32 * b04 + a33 * b03) * det,
(a22 * b04 - a21 * b05 - a23 * b03) * det,
(a12 * b08 - a10 * b11 - a13 * b07) * det,
(a00 * b11 - a02 * b08 + a03 * b07) * det,
(a32 * b02 - a30 * b05 - a33 * b01) * det,
(a20 * b05 - a22 * b02 + a23 * b01) * det,
(a10 * b10 - a11 * b08 + a13 * b06) * det,
(a01 * b08 - a00 * b10 - a03 * b06) * det,
(a30 * b04 - a31 * b02 + a33 * b00) * det,
(a21 * b02 - a20 * b04 - a23 * b00) * det,
(a11 * b07 - a10 * b09 - a12 * b06) * det,
(a00 * b09 - a01 * b07 + a02 * b06) * det,
(a31 * b01 - a30 * b03 - a32 * b00) * det,
(a20 * b03 - a21 * b01 + a22 * b00) * det
);
},
/**
* Calculate the adjoint, or adjugate, of this Matrix.
*
* @method Phaser.Math.Matrix4#adjoint
* @since 3.0.0
*
* @return {this} This Matrix4.
*/
adjoint: function() {
var a = this.val;
var a00 = a[0];
var a01 = a[1];
var a02 = a[2];
var a03 = a[3];
var a10 = a[4];
var a11 = a[5];
var a12 = a[6];
var a13 = a[7];
var a20 = a[8];
var a21 = a[9];
var a22 = a[10];
var a23 = a[11];
var a30 = a[12];
var a31 = a[13];
var a32 = a[14];
var a33 = a[15];
return this.setValues(
a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22),
-(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22)),
a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12),
-(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12)),
-(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22)),
a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22),
-(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12)),
a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12),
a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21),
-(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21)),
a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11),
-(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11)),
-(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21)),
a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21),
-(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11)),
a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11)
);
},
/**
* Calculate the determinant of this Matrix.
*
* @method Phaser.Math.Matrix4#determinant
* @since 3.0.0
*
* @return {number} The determinant of this Matrix.
*/
determinant: function() {
var a = this.val;
var a00 = a[0];
var a01 = a[1];
var a02 = a[2];
var a03 = a[3];
var a10 = a[4];
var a11 = a[5];
var a12 = a[6];
var a13 = a[7];
var a20 = a[8];
var a21 = a[9];
var a22 = a[10];
var a23 = a[11];
var a30 = a[12];
var a31 = a[13];
var a32 = a[14];
var a33 = a[15];
var b00 = a00 * a11 - a01 * a10;
var b01 = a00 * a12 - a02 * a10;
var b02 = a00 * a13 - a03 * a10;
var b03 = a01 * a12 - a02 * a11;
var b04 = a01 * a13 - a03 * a11;
var b05 = a02 * a13 - a03 * a12;
var b06 = a20 * a31 - a21 * a30;
var b07 = a20 * a32 - a22 * a30;
var b08 = a20 * a33 - a23 * a30;
var b09 = a21 * a32 - a22 * a31;
var b10 = a21 * a33 - a23 * a31;
var b11 = a22 * a33 - a23 * a32;
return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
},
/**
* Multiply this Matrix by the given Matrix.
*
* @method Phaser.Math.Matrix4#multiply
* @since 3.0.0
*
* @param {Phaser.Math.Matrix4} src - The Matrix to multiply this Matrix by.
*
* @return {this} This Matrix4.
*/
multiply: function(src) {
var a = this.val;
var a00 = a[0];
var a01 = a[1];
var a02 = a[2];
var a03 = a[3];
var a10 = a[4];
var a11 = a[5];
var a12 = a[6];
var a13 = a[7];
var a20 = a[8];
var a21 = a[9];
var a22 = a[10];
var a23 = a[11];
var a30 = a[12];
var a31 = a[13];
var a32 = a[14];
var a33 = a[15];
var b = src.val;
var b0 = b[0];
var b1 = b[1];
var b2 = b[2];
var b3 = b[3];
a[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
a[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
a[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
a[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
b0 = b[4];
b1 = b[5];
b2 = b[6];
b3 = b[7];
a[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
a[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
a[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
a[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
b0 = b[8];
b1 = b[9];
b2 = b[10];
b3 = b[11];
a[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
a[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
a[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
a[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
b0 = b[12];
b1 = b[13];
b2 = b[14];
b3 = b[15];
a[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
a[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
a[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
a[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
return this;
},
/**
* Multiply the values of this Matrix4 by those given in the `src` argument.
*
* @method Phaser.Math.Matrix4#multiplyLocal
* @since 3.0.0
*
* @param {Phaser.Math.Matrix4} src - The source Matrix4 that this Matrix4 is multiplied by.
*
* @return {this} This Matrix4.
*/
multiplyLocal: function(src) {
var a = this.val;
var b = src.val;
return this.setValues(
a[0] * b[0] + a[1] * b[4] + a[2] * b[8] + a[3] * b[12],
a[0] * b[1] + a[1] * b[5] + a[2] * b[9] + a[3] * b[13],
a[0] * b[2] + a[1] * b[6] + a[2] * b[10] + a[3] * b[14],
a[0] * b[3] + a[1] * b[7] + a[2] * b[11] + a[3] * b[15],
a[4] * b[0] + a[5] * b[4] + a[6] * b[8] + a[7] * b[12],
a[4] * b[1] + a[5] * b[5] + a[6] * b[9] + a[7] * b[13],
a[4] * b[2] + a[5] * b[6] + a[6] * b[10] + a[7] * b[14],
a[4] * b[3] + a[5] * b[7] + a[6] * b[11] + a[7] * b[15],
a[8] * b[0] + a[9] * b[4] + a[10] * b[8] + a[11] * b[12],
a[8] * b[1] + a[9] * b[5] + a[10] * b[9] + a[11] * b[13],
a[8] * b[2] + a[9] * b[6] + a[10] * b[10] + a[11] * b[14],
a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11] * b[15],
a[12] * b[0] + a[13] * b[4] + a[14] * b[8] + a[15] * b[12],
a[12] * b[1] + a[13] * b[5] + a[14] * b[9] + a[15] * b[13],
a[12] * b[2] + a[13] * b[6] + a[14] * b[10] + a[15] * b[14],
a[12] * b[3] + a[13] * b[7] + a[14] * b[11] + a[15] * b[15]
);
},
/**
* Multiplies the given Matrix4 object with this Matrix.
*
* This is the same as calling `multiplyMatrices(m, this)`.
*
* @method Phaser.Math.Matrix4#premultiply
* @since 3.50.0
*
* @param {Phaser.Math.Matrix4} m - The Matrix4 to multiply with this one.
*
* @return {this} This Matrix4.
*/
premultiply: function(m) {
return this.multiplyMatrices(m, this);
},
/**
* Multiplies the two given Matrix4 objects and stores the results in this Matrix.
*
* @method Phaser.Math.Matrix4#multiplyMatrices
* @since 3.50.0
*
* @param {Phaser.Math.Matrix4} a - The first Matrix4 to multiply.
* @param {Phaser.Math.Matrix4} b - The second Matrix4 to multiply.
*
* @return {this} This Matrix4.
*/
multiplyMatrices: function(a, b) {
var am = a.val;
var bm = b.val;
var a11 = am[0];
var a12 = am[4];
var a13 = am[8];
var a14 = am[12];
var a21 = am[1];
var a22 = am[5];
var a23 = am[9];
var a24 = am[13];
var a31 = am[2];
var a32 = am[6];
var a33 = am[10];
var a34 = am[14];
var a41 = am[3];
var a42 = am[7];
var a43 = am[11];
var a44 = am[15];
var b11 = bm[0];
var b12 = bm[4];
var b13 = bm[8];
var b14 = bm[12];
var b21 = bm[1];
var b22 = bm[5];
var b23 = bm[9];
var b24 = bm[13];
var b31 = bm[2];
var b32 = bm[6];
var b33 = bm[10];
var b34 = bm[14];
var b41 = bm[3];
var b42 = bm[7];
var b43 = bm[11];
var b44 = bm[15];
return this.setValues(
a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41,
a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41,
a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41,
a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41,
a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42,
a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42,
a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42,
a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42,
a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43,
a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43,
a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43,
a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43,
a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44,
a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44,
a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44,
a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44
);
},
/**
* Translate this Matrix using the given Vector.
*
* @method Phaser.Math.Matrix4#translate
* @since 3.0.0
*
* @param {(Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to translate this Matrix with.
*
* @return {this} This Matrix4.
*/
translate: function(v) {
return this.translateXYZ(v.x, v.y, v.z);
},
/**
* Translate this Matrix using the given values.
*
* @method Phaser.Math.Matrix4#translateXYZ
* @since 3.16.0
*
* @param {number} x - The x component.
* @param {number} y - The y component.
* @param {number} z - The z component.
*
* @return {this} This Matrix4.
*/
translateXYZ: function(x, y, z) {
var a = this.val;
a[12] = a[0] * x + a[4] * y + a[8] * z + a[12];
a[13] = a[1] * x + a[5] * y + a[9] * z + a[13];
a[14] = a[2] * x + a[6] * y + a[10] * z + a[14];
a[15] = a[3] * x + a[7] * y + a[11] * z + a[15];
return this;
},
/**
* Apply a scale transformation to this Matrix.
*
* Uses the `x`, `y` and `z` components of the given Vector to scale the Matrix.
*
* @method Phaser.Math.Matrix4#scale
* @since 3.0.0
*
* @param {(Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to scale this Matrix with.
*
* @return {this} This Matrix4.
*/
scale: function(v) {
return this.scaleXYZ(v.x, v.y, v.z);
},
/**
* Apply a scale transformation to this Matrix.
*
* @method Phaser.Math.Matrix4#scaleXYZ
* @since 3.16.0
*
* @param {number} x - The x component.
* @param {number} y - The y component.
* @param {number} z - The z component.
*
* @return {this} This Matrix4.
*/
scaleXYZ: function(x, y, z) {
var a = this.val;
a[0] = a[0] * x;
a[1] = a[1] * x;
a[2] = a[2] * x;
a[3] = a[3] * x;
a[4] = a[4] * y;
a[5] = a[5] * y;
a[6] = a[6] * y;
a[7] = a[7] * y;
a[8] = a[8] * z;
a[9] = a[9] * z;
a[10] = a[10] * z;
a[11] = a[11] * z;
return this;
},
/**
* Derive a rotation matrix around the given axis.
*
* @method Phaser.Math.Matrix4#makeRotationAxis
* @since 3.0.0
*
* @param {(Phaser.Math.Vector3|Phaser.Math.Vector4)} axis - The rotation axis.
* @param {number} angle - The rotation angle in radians.
*
* @return {this} This Matrix4.
*/
makeRotationAxis: function(axis, angle) {
var c = Math.cos(angle);
var s = Math.sin(angle);
var t = 1 - c;
var x = axis.x;
var y = axis.y;
var z = axis.z;
var tx = t * x;
var ty = t * y;
return this.setValues(
tx * x + c,
tx * y - s * z,
tx * z + s * y,
0,
tx * y + s * z,
ty * y + c,
ty * z - s * x,
0,
tx * z - s * y,
ty * z + s * x,
t * z * z + c,
0,
0,
0,
0,
1
);
},
/**
* Apply a rotation transformation to this Matrix.
*
* @method Phaser.Math.Matrix4#rotate
* @since 3.0.0
*
* @param {number} rad - The angle in radians to rotate by.
* @param {Phaser.Math.Vector3} axis - The axis to rotate upon.
*
* @return {this} This Matrix4.
*/
rotate: function(rad, axis) {
var a = this.val;
var x = axis.x;
var y = axis.y;
var z = axis.z;
var len = Math.sqrt(x * x + y * y + z * z);
if (Math.abs(len) < EPSILON) {
return this;
}
len = 1 / len;
x *= len;
y *= len;
z *= len;
var s = Math.sin(rad);
var c = Math.cos(rad);
var t = 1 - c;
var a00 = a[0];
var a01 = a[1];
var a02 = a[2];
var a03 = a[3];
var a10 = a[4];
var a11 = a[5];
var a12 = a[6];
var a13 = a[7];
var a20 = a[8];
var a21 = a[9];
var a22 = a[10];
var a23 = a[11];
var a30 = a[12];
var a31 = a[13];
var a32 = a[14];
var a33 = a[15];
var b00 = x * x * t + c;
var b01 = y * x * t + z * s;
var b02 = z * x * t - y * s;
var b10 = x * y * t - z * s;
var b11 = y * y * t + c;
var b12 = z * y * t + x * s;
var b20 = x * z * t + y * s;
var b21 = y * z * t - x * s;
var b22 = z * z * t + c;
return this.setValues(
a00 * b00 + a10 * b01 + a20 * b02,
a01 * b00 + a11 * b01 + a21 * b02,
a02 * b00 + a12 * b01 + a22 * b02,
a03 * b00 + a13 * b01 + a23 * b02,
a00 * b10 + a10 * b11 + a20 * b12,
a01 * b10 + a11 * b11 + a21 * b12,
a02 * b10 + a12 * b11 + a22 * b12,
a03 * b10 + a13 * b11 + a23 * b12,
a00 * b20 + a10 * b21 + a20 * b22,
a01 * b20 + a11 * b21 + a21 * b22,
a02 * b20 + a12 * b21 + a22 * b22,
a03 * b20 + a13 * b21 + a23 * b22,
a30,
a31,
a32,
a33
);
},
/**
* Rotate this matrix on its X axis.
*
* @method Phaser.Math.Matrix4#rotateX
* @since 3.0.0
*
* @param {number} rad - The angle in radians to rotate by.
*
* @return {this} This Matrix4.
*/
rotateX: function(rad) {
var a = this.val;
var s = Math.sin(rad);
var c = Math.cos(rad);
var a10 = a[4];
var a11 = a[5];
var a12 = a[6];
var a13 = a[7];
var a20 = a[8];
var a21 = a[9];
var a22 = a[10];
var a23 = a[11];
a[4] = a10 * c + a20 * s;
a[5] = a11 * c + a21 * s;
a[6] = a12 * c + a22 * s;
a[7] = a13 * c + a23 * s;
a[8] = a20 * c - a10 * s;
a[9] = a21 * c - a11 * s;
a[10] = a22 * c - a12 * s;
a[11] = a23 * c - a13 * s;
return this;
},
/**
* Rotate this matrix on its Y axis.
*
* @method Phaser.Math.Matrix4#rotateY
* @since 3.0.0
*
* @param {number} rad - The angle to rotate by, in radians.
*
* @return {this} This Matrix4.
*/
rotateY: function(rad) {
var a = this.val;
var s = Math.sin(rad);
var c = Math.cos(rad);
var a00 = a[0];
var a01 = a[1];
var a02 = a[2];
var a03 = a[3];
var a20 = a[8];
var a21 = a[9];
var a22 = a[10];
var a23 = a[11];
a[0] = a00 * c - a20 * s;
a[1] = a01 * c - a21 * s;
a[2] = a02 * c - a22 * s;
a[3] = a03 * c - a23 * s;
a[8] = a00 * s + a20 * c;
a[9] = a01 * s + a21 * c;
a[10] = a02 * s + a22 * c;
a[11] = a03 * s + a23 * c;
return this;
},
/**
* Rotate this matrix on its Z axis.
*
* @method Phaser.Math.Matrix4#rotateZ
* @since 3.0.0
*
* @param {number} rad - The angle to rotate by, in radians.
*
* @return {this} This Matrix4.
*/
rotateZ: function(rad) {
var a = this.val;
var s = Math.sin(rad);
var c = Math.cos(rad);
var a00 = a[0];
var a01 = a[1];
var a02 = a[2];
var a03 = a[3];
var a10 = a[4];
var a11 = a[5];
var a12 = a[6];
var a13 = a[7];
a[0] = a00 * c + a10 * s;
a[1] = a01 * c + a11 * s;
a[2] = a02 * c + a12 * s;
a[3] = a03 * c + a13 * s;
a[4] = a10 * c - a00 * s;
a[5] = a11 * c - a01 * s;
a[6] = a12 * c - a02 * s;
a[7] = a13 * c - a03 * s;
return this;
},
/**
* Set the values of this Matrix from the given rotation Quaternion and translation Vector.
*
* @method Phaser.Math.Matrix4#fromRotationTranslation
* @since 3.0.0
*
* @param {Phaser.Math.Quaternion} q - The Quaternion to set rotation from.
* @param {Phaser.Math.Vector3} v - The Vector to set translation from.
*
* @return {this} This Matrix4.
*/
fromRotationTranslation: function(q, v) {
var x = q.x;
var y = q.y;
var z = q.z;
var w = q.w;
var x2 = x + x;
var y2 = y + y;
var z2 = z + z;
var xx = x * x2;
var xy = x * y2;
var xz = x * z2;
var yy = y * y2;
var yz = y * z2;
var zz = z * z2;
var wx = w * x2;
var wy = w * y2;
var wz = w * z2;
return this.setValues(
1 - (yy + zz),
xy + wz,
xz - wy,
0,
xy - wz,
1 - (xx + zz),
yz + wx,
0,
xz + wy,
yz - wx,
1 - (xx + yy),
0,
v.x,
v.y,
v.z,
1
);
},
/**
* Set the values of this Matrix from the given Quaternion.
*
* @method Phaser.Math.Matrix4#fromQuat
* @since 3.0.0
*
* @param {Phaser.Math.Quaternion} q - The Quaternion to set the values of this Matrix from.
*
* @return {this} This Matrix4.
*/
fromQuat: function(q) {
var x = q.x;
var y = q.y;
var z = q.z;
var w = q.w;
var x2 = x + x;
var y2 = y + y;
var z2 = z + z;
var xx = x * x2;
var xy = x * y2;
var xz = x * z2;
var yy = y * y2;
var yz = y * z2;
var zz = z * z2;
var wx = w * x2;
var wy = w * y2;
var wz = w * z2;
return this.setValues(
1 - (yy + zz),
xy + wz,
xz - wy,
0,
xy - wz,
1 - (xx + zz),
yz + wx,
0,
xz + wy,
yz - wx,
1 - (xx + yy),
0,
0,
0,
0,
1
);
},
/**
* Generate a frustum matrix with the given bounds.
*
* @method Phaser.Math.Matrix4#frustum
* @since 3.0.0
*
* @param {number} left - The left bound of the frustum.
* @param {number} right - The right bound of the frustum.
* @param {number} bottom - The bottom bound of the frustum.
* @param {number} top - The top bound of the frustum.
* @param {number} near - The near bound of the frustum.
* @param {number} far - The far bound of the frustum.
*
* @return {this} This Matrix4.
*/
frustum: function(left, right, bottom, top, near, far) {
var rl = 1 / (right - left);
var tb = 1 / (top - bottom);
var nf = 1 / (near - far);
return this.setValues(
near * 2 * rl,
0,
0,
0,
0,
near * 2 * tb,
0,
0,
(right + left) * rl,
(top + bottom) * tb,
(far + near) * nf,
-1,
0,
0,
far * near * 2 * nf,
0
);
},
/**
* Generate a perspective projection matrix with the given bounds.
*
* @method Phaser.Math.Matrix4#perspective
* @since 3.0.0
*
* @param {number} fovy - Vertical field of view in radians
* @param {number} aspect - Aspect ratio. Typically viewport width /height.
* @param {number} near - Near bound of the frustum.
* @param {number} far - Far bound of the frustum.
*
* @return {this} This Matrix4.
*/
perspective: function(fovy, aspect, near, far) {
var f = 1 / Math.tan(fovy / 2);
var nf = 1 / (near - far);
return this.setValues(
f / aspect,
0,
0,
0,
0,
f,
0,
0,
0,
0,
(far + near) * nf,
-1,
0,
0,
2 * far * near * nf,
0
);
},
/**
* Generate a perspective projection matrix with the given bounds.
*
* @method Phaser.Math.Matrix4#perspectiveLH
* @since 3.0.0
*
* @param {number} width - The width of the frustum.
* @param {number} height - The height of the frustum.
* @param {number} near - Near bound of the frustum.
* @param {number} far - Far bound of the frustum.
*
* @return {this} This Matrix4.
*/
perspectiveLH: function(width, height, near, far) {
return this.setValues(
2 * near / width,
0,
0,
0,
0,
2 * near / height,
0,
0,
0,
0,
-far / (near - far),
1,
0,
0,
near * far / (near - far),
0
);
},
/**
* Generate an orthogonal projection matrix with the given bounds.
*
* @method Phaser.Math.Matrix4#ortho
* @since 3.0.0
*
* @param {number} left - The left bound of the frustum.
* @param {number} right - The right bound of the frustum.
* @param {number} bottom - The bottom bound of the frustum.
* @param {number} top - The top bound of the frustum.
* @param {number} near - The near bound of the frustum.
* @param {number} far - The far bound of the frustum.
*
* @return {this} This Matrix4.
*/
ortho: function(left, right, bottom, top, near, far) {
var lr = left - right;
var bt = bottom - top;
var nf = near - far;
lr = lr === 0 ? lr : 1 / lr;
bt = bt === 0 ? bt : 1 / bt;
nf = nf === 0 ? nf : 1 / nf;
return this.setValues(
-2 * lr,
0,
0,
0,
0,
-2 * bt,
0,
0,
0,
0,
2 * nf,
0,
(left + right) * lr,
(top + bottom) * bt,
(far + near) * nf,
1
);
},
/**
* Generate a right-handed look-at matrix with the given eye position, target and up axis.
*
* @method Phaser.Math.Matrix4#lookAtRH
* @since 3.50.0
*
* @param {Phaser.Math.Vector3} eye - Position of the viewer.
* @param {Phaser.Math.Vector3} target - Point the viewer is looking at.
* @param {Phaser.Math.Vector3} up - vec3 pointing up.
*
* @return {this} This Matrix4.
*/
lookAtRH: function(eye, target, up) {
var m = this.val;
_z.subVectors(eye, target);
if (_z.lengthSq() === 0) {
_z.z = 1;
}
_z.normalize();
_x.crossVectors(up, _z);
if (_x.lengthSq() === 0) {
if (Math.abs(up.z) === 1) {
_z.x += 1e-4;
} else {
_z.z += 1e-4;
}
_z.normalize();
_x.crossVectors(up, _z);
}
_x.normalize();
_y.crossVectors(_z, _x);
m[0] = _x.x;
m[1] = _x.y;
m[2] = _x.z;
m[4] = _y.x;
m[5] = _y.y;
m[6] = _y.z;
m[8] = _z.x;
m[9] = _z.y;
m[10] = _z.z;
return this;
},
/**
* Generate a look-at matrix with the given eye position, focal point, and up axis.
*
* @method Phaser.Math.Matrix4#lookAt
* @since 3.0.0
*
* @param {Phaser.Math.Vector3} eye - Position of the viewer
* @param {Phaser.Math.Vector3} center - Point the viewer is looking at
* @param {Phaser.Math.Vector3} up - vec3 pointing up.
*
* @return {this} This Matrix4.
*/
lookAt: function(eye, center, up) {
var eyex = eye.x;
var eyey = eye.y;
var eyez = eye.z;
var upx = up.x;
var upy = up.y;
var upz = up.z;
var centerx = center.x;
var centery = center.y;
var centerz = center.z;
if (Math.abs(eyex - centerx) < EPSILON && Math.abs(eyey - centery) < EPSILON && Math.abs(eyez - centerz) < EPSILON) {
return this.identity();
}
var z0 = eyex - centerx;
var z1 = eyey - centery;
var z2 = eyez - centerz;
var len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2);
z0 *= len;
z1 *= len;
z2 *= len;
var x0 = upy * z2 - upz * z1;
var x1 = upz * z0 - upx * z2;
var x2 = upx * z1 - upy * z0;
len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2);
if (!len) {
x0 = 0;
x1 = 0;
x2 = 0;
} else {
len = 1 / len;
x0 *= len;
x1 *= len;
x2 *= len;
}
var y0 = z1 * x2 - z2 * x1;
var y1 = z2 * x0 - z0 * x2;
var y2 = z0 * x1 - z1 * x0;
len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2);
if (!len) {
y0 = 0;
y1 = 0;
y2 = 0;
} else {
len = 1 / len;
y0 *= len;
y1 *= len;
y2 *= len;
}
return this.setValues(
x0,
y0,
z0,
0,
x1,
y1,
z1,
0,
x2,
y2,
z2,
0,
-(x0 * eyex + x1 * eyey + x2 * eyez),
-(y0 * eyex + y1 * eyey + y2 * eyez),
-(z0 * eyex + z1 * eyey + z2 * eyez),
1
);
},
/**
* Set the values of this matrix from the given `yaw`, `pitch` and `roll` values.
*
* @method Phaser.Math.Matrix4#yawPitchRoll
* @since 3.0.0
*
* @param {number} yaw - The yaw value.
* @param {number} pitch - The pitch value.
* @param {number} roll - The roll value.
*
* @return {this} This Matrix4.
*/
yawPitchRoll: function(yaw, pitch, roll) {
this.zero();
_tempMat1.zero();
_tempMat2.zero();
var m0 = this.val;
var m1 = _tempMat1.val;
var m2 = _tempMat2.val;
var s = Math.sin(roll);
var c = Math.cos(roll);
m0[10] = 1;
m0[15] = 1;
m0[0] = c;
m0[1] = s;
m0[4] = -s;
m0[5] = c;
s = Math.sin(pitch);
c = Math.cos(pitch);
m1[0] = 1;
m1[15] = 1;
m1[5] = c;
m1[10] = c;
m1[9] = -s;
m1[6] = s;
s = Math.sin(yaw);
c = Math.cos(yaw);
m2[5] = 1;
m2[15] = 1;
m2[0] = c;
m2[2] = -s;
m2[8] = s;
m2[10] = c;
this.multiplyLocal(_tempMat1);
this.multiplyLocal(_tempMat2);
return this;
},
/**
* Generate a world matrix from the given rotation, position, scale, view matrix and projection matrix.
*
* @method Phaser.Math.Matrix4#setWorldMatrix
* @since 3.0.0
*
* @param {Phaser.Math.Vector3} rotation - The rotation of the world matrix.
* @param {Phaser.Math.Vector3} position - The position of the world matrix.
* @param {Phaser.Math.Vector3} scale - The scale of the world matrix.
* @param {Phaser.Math.Matrix4} [viewMatrix] - The view matrix.
* @param {Phaser.Math.Matrix4} [projectionMatrix] - The projection matrix.
*
* @return {this} This Matrix4.
*/
setWorldMatrix: function(rotation, position, scale, viewMatrix, projectionMatrix) {
this.yawPitchRoll(rotation.y, rotation.x, rotation.z);
_tempMat1.scaling(scale.x, scale.y, scale.z);
_tempMat2.xyz(position.x, position.y, position.z);
this.multiplyLocal(_tempMat1);
this.multiplyLocal(_tempMat2);
if (viewMatrix) {
this.multiplyLocal(viewMatrix);
}
if (projectionMatrix) {
this.multiplyLocal(projectionMatrix);
}
return this;
},
/**
* Multiplies this Matrix4 by the given `src` Matrix4 and stores the results in the `out` Matrix4.
*
* @method Phaser.Math.Matrix4#multiplyToMat4
* @since 3.50.0
*
* @param {Phaser.Math.Matrix4} src - The Matrix4 to multiply with this one.
* @param {Phaser.Math.Matrix4} out - The receiving Matrix.
*
* @return {Phaser.Math.Matrix4} This `out` Matrix4.
*/
multiplyToMat4: function(src, out) {
var a = this.val;
var b = src.val;
var a00 = a[0];
var a01 = a[1];
var a02 = a[2];
var a03 = a[3];
var a10 = a[4];
var a11 = a[5];
var a12 = a[6];
var a13 = a[7];
var a20 = a[8];
var a21 = a[9];
var a22 = a[10];
var a23 = a[11];
var a30 = a[12];
var a31 = a[13];
var a32 = a[14];
var a33 = a[15];
var b00 = b[0];
var b01 = b[1];
var b02 = b[2];
var b03 = b[3];
var b10 = b[4];
var b11 = b[5];
var b12 = b[6];
var b13 = b[7];
var b20 = b[8];
var b21 = b[9];
var b22 = b[10];
var b23 = b[11];
var b30 = b[12];
var b31 = b[13];
var b32 = b[14];
var b33 = b[15];
return out.setValues(
b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30,
b01 * a01 + b01 * a11 + b02 * a21 + b03 * a31,
b02 * a02 + b01 * a12 + b02 * a22 + b03 * a32,
b03 * a03 + b01 * a13 + b02 * a23 + b03 * a33,
b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30,
b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31,
b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32,
b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33,
b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30,
b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31,
b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32,
b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33,
b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30,
b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31,
b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32,
b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33
);
},
/**
* Takes the rotation and position vectors and builds this Matrix4 from them.
*
* @method Phaser.Math.Matrix4#fromRotationXYTranslation
* @since 3.50.0
*
* @param {Phaser.Math.Vector3} rotation - The rotation vector.
* @param {Phaser.Math.Vector3} position - The position vector.
* @param {boolean} translateFirst - Should the operation translate then rotate (`true`), or rotate then translate? (`false`)
*
* @return {this} This Matrix4.
*/
fromRotationXYTranslation: function(rotation, position, translateFirst) {
var x = position.x;
var y = position.y;
var z = position.z;
var sx = Math.sin(rotation.x);
var cx = Math.cos(rotation.x);
var sy = Math.sin(rotation.y);
var cy = Math.cos(rotation.y);
var a30 = x;
var a31 = y;
var a32 = z;
var b21 = -sx;
var c01 = 0 - b21 * sy;
var c02 = 0 - cx * sy;
var c21 = b21 * cy;
var c22 = cx * cy;
if (!translateFirst) {
a30 = cy * x + sy * z;
a31 = c01 * x + cx * y + c21 * z;
a32 = c02 * x + sx * y + c22 * z;
}
return this.setValues(
cy,
c01,
c02,
0,
0,
cx,
sx,
0,
sy,
c21,
c22,
0,
a30,
a31,
a32,
1
);
},
/**
* Returns the maximum axis scale from this Matrix4.
*
* @method Phaser.Math.Matrix4#getMaxScaleOnAxis
* @since 3.50.0
*
* @return {number} The maximum axis scale.
*/
getMaxScaleOnAxis: function() {
var m = this.val;
var scaleXSq = m[0] * m[0] + m[1] * m[1] + m[2] * m[2];
var scaleYSq = m[4] * m[4] + m[5] * m[5] + m[6] * m[6];
var scaleZSq = m[8] * m[8] + m[9] * m[9] + m[10] * m[10];
return Math.sqrt(Math.max(scaleXSq, scaleYSq, scaleZSq));
}
});
var _tempMat1 = new Matrix4();
var _tempMat2 = new Matrix4();
var _x = new Vector3();
var _y = new Vector3();
var _z = new Vector3();
module2.exports = Matrix4;
}
),
/***/
86883: (
/***/
(module2) => {
var MaxAdd = function(value, amount, max) {
return Math.min(value + amount, max);
};
module2.exports = MaxAdd;
}
),
/***/
50040: (
/***/
(module2) => {
var Median = function(values) {
var valuesNum = values.length;
if (valuesNum === 0) {
return 0;
}
values.sort(function(a, b) {
return a - b;
});
var halfIndex = Math.floor(valuesNum / 2);
return valuesNum % 2 === 0 ? (values[halfIndex] + values[halfIndex - 1]) / 2 : values[halfIndex];
};
module2.exports = Median;
}
),
/***/
37204: (
/***/
(module2) => {
var MinSub = function(value, amount, min) {
return Math.max(value - amount, min);
};
module2.exports = MinSub;
}
),
/***/
65201: (
/***/
(module2) => {
var Percent = function(value, min, max, upperMax) {
if (max === void 0) {
max = min + 1;
}
var percentage = (value - min) / (max - min);
if (percentage > 1) {
if (upperMax !== void 0) {
percentage = (upperMax - value) / (upperMax - max);
if (percentage < 0) {
percentage = 0;
}
} else {
percentage = 1;
}
} else if (percentage < 0) {
percentage = 0;
}
return percentage;
};
module2.exports = Percent;
}
),
/***/
15746: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Matrix3 = __webpack_require__2(94434);
var NOOP = __webpack_require__2(29747);
var Vector3 = __webpack_require__2(25836);
var EPSILON = 1e-6;
var siNext = new Int8Array([1, 2, 0]);
var tmp = new Float32Array([0, 0, 0]);
var xUnitVec3 = new Vector3(1, 0, 0);
var yUnitVec3 = new Vector3(0, 1, 0);
var tmpvec = new Vector3();
var tmpMat3 = new Matrix3();
var Quaternion = new Class({
initialize: function Quaternion2(x, y, z, w) {
this.onChangeCallback = NOOP;
this.set(x, y, z, w);
},
/**
* The x component of this Quaternion.
*
* @name Phaser.Math.Quaternion#x
* @type {number}
* @default 0
* @since 3.0.0
*/
x: {
get: function() {
return this._x;
},
set: function(value) {
this._x = value;
this.onChangeCallback(this);
}
},
/**
* The y component of this Quaternion.
*
* @name Phaser.Math.Quaternion#y
* @type {number}
* @default 0
* @since 3.0.0
*/
y: {
get: function() {
return this._y;
},
set: function(value) {
this._y = value;
this.onChangeCallback(this);
}
},
/**
* The z component of this Quaternion.
*
* @name Phaser.Math.Quaternion#z
* @type {number}
* @default 0
* @since 3.0.0
*/
z: {
get: function() {
return this._z;
},
set: function(value) {
this._z = value;
this.onChangeCallback(this);
}
},
/**
* The w component of this Quaternion.
*
* @name Phaser.Math.Quaternion#w
* @type {number}
* @default 0
* @since 3.0.0
*/
w: {
get: function() {
return this._w;
},
set: function(value) {
this._w = value;
this.onChangeCallback(this);
}
},
/**
* Copy the components of a given Quaternion or Vector into this Quaternion.
*
* @method Phaser.Math.Quaternion#copy
* @since 3.0.0
*
* @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} src - The Quaternion or Vector to copy the components from.
*
* @return {Phaser.Math.Quaternion} This Quaternion.
*/
copy: function(src) {
return this.set(src);
},
/**
* Set the components of this Quaternion and optionally call the `onChangeCallback`.
*
* @method Phaser.Math.Quaternion#set
* @since 3.0.0
*
* @param {(number|object)} [x=0] - The x component, or an object containing x, y, z, and w components.
* @param {number} [y=0] - The y component.
* @param {number} [z=0] - The z component.
* @param {number} [w=0] - The w component.
* @param {boolean} [update=true] - Call the `onChangeCallback`?
*
* @return {Phaser.Math.Quaternion} This Quaternion.
*/
set: function(x, y, z, w, update) {
if (update === void 0) {
update = true;
}
if (typeof x === "object") {
this._x = x.x || 0;
this._y = x.y || 0;
this._z = x.z || 0;
this._w = x.w || 0;
} else {
this._x = x || 0;
this._y = y || 0;
this._z = z || 0;
this._w = w || 0;
}
if (update) {
this.onChangeCallback(this);
}
return this;
},
/**
* Add a given Quaternion or Vector to this Quaternion. Addition is component-wise.
*
* @method Phaser.Math.Quaternion#add
* @since 3.0.0
*
* @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} v - The Quaternion or Vector to add to this Quaternion.
*
* @return {Phaser.Math.Quaternion} This Quaternion.
*/
add: function(v) {
this._x += v.x;
this._y += v.y;
this._z += v.z;
this._w += v.w;
this.onChangeCallback(this);
return this;
},
/**
* Subtract a given Quaternion or Vector from this Quaternion. Subtraction is component-wise.
*
* @method Phaser.Math.Quaternion#subtract
* @since 3.0.0
*
* @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} v - The Quaternion or Vector to subtract from this Quaternion.
*
* @return {Phaser.Math.Quaternion} This Quaternion.
*/
subtract: function(v) {
this._x -= v.x;
this._y -= v.y;
this._z -= v.z;
this._w -= v.w;
this.onChangeCallback(this);
return this;
},
/**
* Scale this Quaternion by the given value.
*
* @method Phaser.Math.Quaternion#scale
* @since 3.0.0
*
* @param {number} scale - The value to scale this Quaternion by.
*
* @return {Phaser.Math.Quaternion} This Quaternion.
*/
scale: function(scale) {
this._x *= scale;
this._y *= scale;
this._z *= scale;
this._w *= scale;
this.onChangeCallback(this);
return this;
},
/**
* Calculate the length of this Quaternion.
*
* @method Phaser.Math.Quaternion#length
* @since 3.0.0
*
* @return {number} The length of this Quaternion.
*/
length: function() {
var x = this.x;
var y = this.y;
var z = this.z;
var w = this.w;
return Math.sqrt(x * x + y * y + z * z + w * w);
},
/**
* Calculate the length of this Quaternion squared.
*
* @method Phaser.Math.Quaternion#lengthSq
* @since 3.0.0
*
* @return {number} The length of this Quaternion, squared.
*/
lengthSq: function() {
var x = this.x;
var y = this.y;
var z = this.z;
var w = this.w;
return x * x + y * y + z * z + w * w;
},
/**
* Normalize this Quaternion.
*
* @method Phaser.Math.Quaternion#normalize
* @since 3.0.0
*
* @return {Phaser.Math.Quaternion} This Quaternion.
*/
normalize: function() {
var x = this.x;
var y = this.y;
var z = this.z;
var w = this.w;
var len = x * x + y * y + z * z + w * w;
if (len > 0) {
len = 1 / Math.sqrt(len);
this._x = x * len;
this._y = y * len;
this._z = z * len;
this._w = w * len;
}
this.onChangeCallback(this);
return this;
},
/**
* Calculate the dot product of this Quaternion and the given Quaternion or Vector.
*
* @method Phaser.Math.Quaternion#dot
* @since 3.0.0
*
* @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} v - The Quaternion or Vector to dot product with this Quaternion.
*
* @return {number} The dot product of this Quaternion and the given Quaternion or Vector.
*/
dot: function(v) {
return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;
},
/**
* Linearly interpolate this Quaternion towards the given Quaternion or Vector.
*
* @method Phaser.Math.Quaternion#lerp
* @since 3.0.0
*
* @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} v - The Quaternion or Vector to interpolate towards.
* @param {number} [t=0] - The percentage of interpolation.
*
* @return {Phaser.Math.Quaternion} This Quaternion.
*/
lerp: function(v, t) {
if (t === void 0) {
t = 0;
}
var ax = this.x;
var ay = this.y;
var az = this.z;
var aw = this.w;
return this.set(
ax + t * (v.x - ax),
ay + t * (v.y - ay),
az + t * (v.z - az),
aw + t * (v.w - aw)
);
},
/**
* Rotates this Quaternion based on the two given vectors.
*
* @method Phaser.Math.Quaternion#rotationTo
* @since 3.0.0
*
* @param {Phaser.Math.Vector3} a - The transform rotation vector.
* @param {Phaser.Math.Vector3} b - The target rotation vector.
*
* @return {Phaser.Math.Quaternion} This Quaternion.
*/
rotationTo: function(a, b) {
var dot = a.x * b.x + a.y * b.y + a.z * b.z;
if (dot < -0.999999) {
if (tmpvec.copy(xUnitVec3).cross(a).length() < EPSILON) {
tmpvec.copy(yUnitVec3).cross(a);
}
tmpvec.normalize();
return this.setAxisAngle(tmpvec, Math.PI);
} else if (dot > 0.999999) {
return this.set(0, 0, 0, 1);
} else {
tmpvec.copy(a).cross(b);
this._x = tmpvec.x;
this._y = tmpvec.y;
this._z = tmpvec.z;
this._w = 1 + dot;
return this.normalize();
}
},
/**
* Set the axes of this Quaternion.
*
* @method Phaser.Math.Quaternion#setAxes
* @since 3.0.0
*
* @param {Phaser.Math.Vector3} view - The view axis.
* @param {Phaser.Math.Vector3} right - The right axis.
* @param {Phaser.Math.Vector3} up - The upwards axis.
*
* @return {Phaser.Math.Quaternion} This Quaternion.
*/
setAxes: function(view, right, up) {
var m = tmpMat3.val;
m[0] = right.x;
m[3] = right.y;
m[6] = right.z;
m[1] = up.x;
m[4] = up.y;
m[7] = up.z;
m[2] = -view.x;
m[5] = -view.y;
m[8] = -view.z;
return this.fromMat3(tmpMat3).normalize();
},
/**
* Reset this Matrix to an identity (default) Quaternion.
*
* @method Phaser.Math.Quaternion#identity
* @since 3.0.0
*
* @return {Phaser.Math.Quaternion} This Quaternion.
*/
identity: function() {
return this.set(0, 0, 0, 1);
},
/**
* Set the axis angle of this Quaternion.
*
* @method Phaser.Math.Quaternion#setAxisAngle
* @since 3.0.0
*
* @param {Phaser.Math.Vector3} axis - The axis.
* @param {number} rad - The angle in radians.
*
* @return {Phaser.Math.Quaternion} This Quaternion.
*/
setAxisAngle: function(axis, rad) {
rad = rad * 0.5;
var s = Math.sin(rad);
return this.set(
s * axis.x,
s * axis.y,
s * axis.z,
Math.cos(rad)
);
},
/**
* Multiply this Quaternion by the given Quaternion or Vector.
*
* @method Phaser.Math.Quaternion#multiply
* @since 3.0.0
*
* @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} b - The Quaternion or Vector to multiply this Quaternion by.
*
* @return {Phaser.Math.Quaternion} This Quaternion.
*/
multiply: function(b) {
var ax = this.x;
var ay = this.y;
var az = this.z;
var aw = this.w;
var bx = b.x;
var by = b.y;
var bz = b.z;
var bw = b.w;
return this.set(
ax * bw + aw * bx + ay * bz - az * by,
ay * bw + aw * by + az * bx - ax * bz,
az * bw + aw * bz + ax * by - ay * bx,
aw * bw - ax * bx - ay * by - az * bz
);
},
/**
* Smoothly linearly interpolate this Quaternion towards the given Quaternion or Vector.
*
* @method Phaser.Math.Quaternion#slerp
* @since 3.0.0
*
* @param {(Phaser.Math.Quaternion|Phaser.Math.Vector4)} b - The Quaternion or Vector to interpolate towards.
* @param {number} t - The percentage of interpolation.
*
* @return {Phaser.Math.Quaternion} This Quaternion.
*/
slerp: function(b, t) {
var ax = this.x;
var ay = this.y;
var az = this.z;
var aw = this.w;
var bx = b.x;
var by = b.y;
var bz = b.z;
var bw = b.w;
var cosom = ax * bx + ay * by + az * bz + aw * bw;
if (cosom < 0) {
cosom = -cosom;
bx = -bx;
by = -by;
bz = -bz;
bw = -bw;
}
var scale0 = 1 - t;
var scale1 = t;
if (1 - cosom > EPSILON) {
var omega = Math.acos(cosom);
var sinom = Math.sin(omega);
scale0 = Math.sin((1 - t) * omega) / sinom;
scale1 = Math.sin(t * omega) / sinom;
}
return this.set(
scale0 * ax + scale1 * bx,
scale0 * ay + scale1 * by,
scale0 * az + scale1 * bz,
scale0 * aw + scale1 * bw
);
},
/**
* Invert this Quaternion.
*
* @method Phaser.Math.Quaternion#invert
* @since 3.0.0
*
* @return {Phaser.Math.Quaternion} This Quaternion.
*/
invert: function() {
var a0 = this.x;
var a1 = this.y;
var a2 = this.z;
var a3 = this.w;
var dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3;
var invDot = dot ? 1 / dot : 0;
return this.set(
-a0 * invDot,
-a1 * invDot,
-a2 * invDot,
a3 * invDot
);
},
/**
* Convert this Quaternion into its conjugate.
*
* Sets the x, y and z components.
*
* @method Phaser.Math.Quaternion#conjugate
* @since 3.0.0
*
* @return {Phaser.Math.Quaternion} This Quaternion.
*/
conjugate: function() {
this._x = -this.x;
this._y = -this.y;
this._z = -this.z;
this.onChangeCallback(this);
return this;
},
/**
* Rotate this Quaternion on the X axis.
*
* @method Phaser.Math.Quaternion#rotateX
* @since 3.0.0
*
* @param {number} rad - The rotation angle in radians.
*
* @return {Phaser.Math.Quaternion} This Quaternion.
*/
rotateX: function(rad) {
rad *= 0.5;
var ax = this.x;
var ay = this.y;
var az = this.z;
var aw = this.w;
var bx = Math.sin(rad);
var bw = Math.cos(rad);
return this.set(
ax * bw + aw * bx,
ay * bw + az * bx,
az * bw - ay * bx,
aw * bw - ax * bx
);
},
/**
* Rotate this Quaternion on the Y axis.
*
* @method Phaser.Math.Quaternion#rotateY
* @since 3.0.0
*
* @param {number} rad - The rotation angle in radians.
*
* @return {Phaser.Math.Quaternion} This Quaternion.
*/
rotateY: function(rad) {
rad *= 0.5;
var ax = this.x;
var ay = this.y;
var az = this.z;
var aw = this.w;
var by = Math.sin(rad);
var bw = Math.cos(rad);
return this.set(
ax * bw - az * by,
ay * bw + aw * by,
az * bw + ax * by,
aw * bw - ay * by
);
},
/**
* Rotate this Quaternion on the Z axis.
*
* @method Phaser.Math.Quaternion#rotateZ
* @since 3.0.0
*
* @param {number} rad - The rotation angle in radians.
*
* @return {Phaser.Math.Quaternion} This Quaternion.
*/
rotateZ: function(rad) {
rad *= 0.5;
var ax = this.x;
var ay = this.y;
var az = this.z;
var aw = this.w;
var bz = Math.sin(rad);
var bw = Math.cos(rad);
return this.set(
ax * bw + ay * bz,
ay * bw - ax * bz,
az * bw + aw * bz,
aw * bw - az * bz
);
},
/**
* Create a unit (or rotation) Quaternion from its x, y, and z components.
*
* Sets the w component.
*
* @method Phaser.Math.Quaternion#calculateW
* @since 3.0.0
*
* @return {Phaser.Math.Quaternion} This Quaternion.
*/
calculateW: function() {
var x = this.x;
var y = this.y;
var z = this.z;
this.w = -Math.sqrt(1 - x * x - y * y - z * z);
return this;
},
/**
* Set this Quaternion from the given Euler, based on Euler order.
*
* @method Phaser.Math.Quaternion#setFromEuler
* @since 3.50.0
*
* @param {Phaser.Math.Euler} euler - The Euler to convert from.
* @param {boolean} [update=true] - Run the `onChangeCallback`?
*
* @return {Phaser.Math.Quaternion} This Quaternion.
*/
setFromEuler: function(euler, update) {
var x = euler.x / 2;
var y = euler.y / 2;
var z = euler.z / 2;
var c1 = Math.cos(x);
var c2 = Math.cos(y);
var c3 = Math.cos(z);
var s1 = Math.sin(x);
var s2 = Math.sin(y);
var s3 = Math.sin(z);
switch (euler.order) {
case "XYZ": {
this.set(
s1 * c2 * c3 + c1 * s2 * s3,
c1 * s2 * c3 - s1 * c2 * s3,
c1 * c2 * s3 + s1 * s2 * c3,
c1 * c2 * c3 - s1 * s2 * s3,
update
);
break;
}
case "YXZ": {
this.set(
s1 * c2 * c3 + c1 * s2 * s3,
c1 * s2 * c3 - s1 * c2 * s3,
c1 * c2 * s3 - s1 * s2 * c3,
c1 * c2 * c3 + s1 * s2 * s3,
update
);
break;
}
case "ZXY": {
this.set(
s1 * c2 * c3 - c1 * s2 * s3,
c1 * s2 * c3 + s1 * c2 * s3,
c1 * c2 * s3 + s1 * s2 * c3,
c1 * c2 * c3 - s1 * s2 * s3,
update
);
break;
}
case "ZYX": {
this.set(
s1 * c2 * c3 - c1 * s2 * s3,
c1 * s2 * c3 + s1 * c2 * s3,
c1 * c2 * s3 - s1 * s2 * c3,
c1 * c2 * c3 + s1 * s2 * s3,
update
);
break;
}
case "YZX": {
this.set(
s1 * c2 * c3 + c1 * s2 * s3,
c1 * s2 * c3 + s1 * c2 * s3,
c1 * c2 * s3 - s1 * s2 * c3,
c1 * c2 * c3 - s1 * s2 * s3,
update
);
break;
}
case "XZY": {
this.set(
s1 * c2 * c3 - c1 * s2 * s3,
c1 * s2 * c3 - s1 * c2 * s3,
c1 * c2 * s3 + s1 * s2 * c3,
c1 * c2 * c3 + s1 * s2 * s3,
update
);
break;
}
}
return this;
},
/**
* Sets the rotation of this Quaternion from the given Matrix4.
*
* @method Phaser.Math.Quaternion#setFromRotationMatrix
* @since 3.50.0
*
* @param {Phaser.Math.Matrix4} mat4 - The Matrix4 to set the rotation from.
*
* @return {Phaser.Math.Quaternion} This Quaternion.
*/
setFromRotationMatrix: function(mat4) {
var m = mat4.val;
var m11 = m[0];
var m12 = m[4];
var m13 = m[8];
var m21 = m[1];
var m22 = m[5];
var m23 = m[9];
var m31 = m[2];
var m32 = m[6];
var m33 = m[10];
var trace = m11 + m22 + m33;
var s;
if (trace > 0) {
s = 0.5 / Math.sqrt(trace + 1);
this.set(
(m32 - m23) * s,
(m13 - m31) * s,
(m21 - m12) * s,
0.25 / s
);
} else if (m11 > m22 && m11 > m33) {
s = 2 * Math.sqrt(1 + m11 - m22 - m33);
this.set(
0.25 * s,
(m12 + m21) / s,
(m13 + m31) / s,
(m32 - m23) / s
);
} else if (m22 > m33) {
s = 2 * Math.sqrt(1 + m22 - m11 - m33);
this.set(
(m12 + m21) / s,
0.25 * s,
(m23 + m32) / s,
(m13 - m31) / s
);
} else {
s = 2 * Math.sqrt(1 + m33 - m11 - m22);
this.set(
(m13 + m31) / s,
(m23 + m32) / s,
0.25 * s,
(m21 - m12) / s
);
}
return this;
},
/**
* Convert the given Matrix into this Quaternion.
*
* @method Phaser.Math.Quaternion#fromMat3
* @since 3.0.0
*
* @param {Phaser.Math.Matrix3} mat - The Matrix to convert from.
*
* @return {Phaser.Math.Quaternion} This Quaternion.
*/
fromMat3: function(mat) {
var m = mat.val;
var fTrace = m[0] + m[4] + m[8];
var fRoot;
if (fTrace > 0) {
fRoot = Math.sqrt(fTrace + 1);
this.w = 0.5 * fRoot;
fRoot = 0.5 / fRoot;
this._x = (m[7] - m[5]) * fRoot;
this._y = (m[2] - m[6]) * fRoot;
this._z = (m[3] - m[1]) * fRoot;
} else {
var i = 0;
if (m[4] > m[0]) {
i = 1;
}
if (m[8] > m[i * 3 + i]) {
i = 2;
}
var j = siNext[i];
var k = siNext[j];
fRoot = Math.sqrt(m[i * 3 + i] - m[j * 3 + j] - m[k * 3 + k] + 1);
tmp[i] = 0.5 * fRoot;
fRoot = 0.5 / fRoot;
tmp[j] = (m[j * 3 + i] + m[i * 3 + j]) * fRoot;
tmp[k] = (m[k * 3 + i] + m[i * 3 + k]) * fRoot;
this._x = tmp[0];
this._y = tmp[1];
this._z = tmp[2];
this._w = (m[k * 3 + j] - m[j * 3 + k]) * fRoot;
}
this.onChangeCallback(this);
return this;
}
});
module2.exports = Quaternion;
}
),
/***/
43396: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(36383);
var RadToDeg = function(radians) {
return radians * CONST.RAD_TO_DEG;
};
module2.exports = RadToDeg;
}
),
/***/
74362: (
/***/
(module2) => {
var RandomXY = function(vector, scale) {
if (scale === void 0) {
scale = 1;
}
var r = Math.random() * 2 * Math.PI;
vector.x = Math.cos(r) * scale;
vector.y = Math.sin(r) * scale;
return vector;
};
module2.exports = RandomXY;
}
),
/***/
60706: (
/***/
(module2) => {
var RandomXYZ = function(vec3, radius) {
if (radius === void 0) {
radius = 1;
}
var r = Math.random() * 2 * Math.PI;
var z = Math.random() * 2 - 1;
var zScale = Math.sqrt(1 - z * z) * radius;
vec3.x = Math.cos(r) * zScale;
vec3.y = Math.sin(r) * zScale;
vec3.z = z * radius;
return vec3;
};
module2.exports = RandomXYZ;
}
),
/***/
67421: (
/***/
(module2) => {
var RandomXYZW = function(vec4, scale) {
if (scale === void 0) {
scale = 1;
}
vec4.x = (Math.random() * 2 - 1) * scale;
vec4.y = (Math.random() * 2 - 1) * scale;
vec4.z = (Math.random() * 2 - 1) * scale;
vec4.w = (Math.random() * 2 - 1) * scale;
return vec4;
};
module2.exports = RandomXYZW;
}
),
/***/
36305: (
/***/
(module2) => {
var Rotate = function(point, angle) {
var x = point.x;
var y = point.y;
point.x = x * Math.cos(angle) - y * Math.sin(angle);
point.y = x * Math.sin(angle) + y * Math.cos(angle);
return point;
};
module2.exports = Rotate;
}
),
/***/
11520: (
/***/
(module2) => {
var RotateAround = function(point, x, y, angle) {
var c = Math.cos(angle);
var s = Math.sin(angle);
var tx = point.x - x;
var ty = point.y - y;
point.x = tx * c - ty * s + x;
point.y = tx * s + ty * c + y;
return point;
};
module2.exports = RotateAround;
}
),
/***/
1163: (
/***/
(module2) => {
var RotateAroundDistance = function(point, x, y, angle, distance) {
var t = angle + Math.atan2(point.y - y, point.x - x);
point.x = x + distance * Math.cos(t);
point.y = y + distance * Math.sin(t);
return point;
};
module2.exports = RotateAroundDistance;
}
),
/***/
70336: (
/***/
(module2) => {
var RotateTo = function(point, x, y, angle, distance) {
point.x = x + distance * Math.cos(angle);
point.y = y + distance * Math.sin(angle);
return point;
};
module2.exports = RotateTo;
}
),
/***/
72678: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Vector3 = __webpack_require__2(25836);
var Matrix4 = __webpack_require__2(37867);
var Quaternion = __webpack_require__2(15746);
var tmpMat4 = new Matrix4();
var tmpQuat = new Quaternion();
var tmpVec3 = new Vector3();
var RotateVec3 = function(vec, axis, radians) {
tmpQuat.setAxisAngle(axis, radians);
tmpMat4.fromRotationTranslation(tmpQuat, tmpVec3.set(0, 0, 0));
return vec.transformMat4(tmpMat4);
};
module2.exports = RotateVec3;
}
),
/***/
2284: (
/***/
(module2) => {
var RoundAwayFromZero = function(value) {
return value > 0 ? Math.ceil(value) : Math.floor(value);
};
module2.exports = RoundAwayFromZero;
}
),
/***/
41013: (
/***/
(module2) => {
var RoundTo = function(value, place, base) {
if (place === void 0) {
place = 0;
}
if (base === void 0) {
base = 10;
}
var p = Math.pow(base, -place);
return Math.round(value * p) / p;
};
module2.exports = RoundTo;
}
),
/***/
16922: (
/***/
(module2) => {
var SinCosTableGenerator = function(length, sinAmp, cosAmp, frequency) {
if (sinAmp === void 0) {
sinAmp = 1;
}
if (cosAmp === void 0) {
cosAmp = 1;
}
if (frequency === void 0) {
frequency = 1;
}
frequency *= Math.PI / length;
var cos = [];
var sin = [];
for (var c = 0; c < length; c++) {
cosAmp -= sinAmp * frequency;
sinAmp += cosAmp * frequency;
cos[c] = cosAmp;
sin[c] = sinAmp;
}
return {
sin,
cos,
length
};
};
module2.exports = SinCosTableGenerator;
}
),
/***/
7602: (
/***/
(module2) => {
var SmoothStep = function(x, min, max) {
if (x <= min) {
return 0;
}
if (x >= max) {
return 1;
}
x = (x - min) / (max - min);
return x * x * (3 - 2 * x);
};
module2.exports = SmoothStep;
}
),
/***/
54261: (
/***/
(module2) => {
var SmootherStep = function(x, min, max) {
x = Math.max(0, Math.min(1, (x - min) / (max - min)));
return x * x * x * (x * (x * 6 - 15) + 10);
};
module2.exports = SmootherStep;
}
),
/***/
44408: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Vector2 = __webpack_require__2(26099);
var ToXY = function(index, width, height, out) {
if (out === void 0) {
out = new Vector2();
}
var x = 0;
var y = 0;
var total = width * height;
if (index > 0 && index <= total) {
if (index > width - 1) {
y = Math.floor(index / width);
x = index - y * width;
} else {
x = index;
}
}
return out.set(x, y);
};
module2.exports = ToXY;
}
),
/***/
85955: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Vector2 = __webpack_require__2(26099);
var TransformXY = function(x, y, positionX, positionY, rotation, scaleX, scaleY, output) {
if (output === void 0) {
output = new Vector2();
}
var radianSin = Math.sin(rotation);
var radianCos = Math.cos(rotation);
var a = radianCos * scaleX;
var b = radianSin * scaleX;
var c = -radianSin * scaleY;
var d = radianCos * scaleY;
var id = 1 / (a * d + c * -b);
output.x = d * id * x + -c * id * y + (positionY * c - positionX * d) * id;
output.y = a * id * y + -b * id * x + (-positionY * a + positionX * b) * id;
return output;
};
module2.exports = TransformXY;
}
),
/***/
26099: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var FuzzyEqual = __webpack_require__2(43855);
var Vector2 = new Class({
initialize: function Vector22(x, y) {
this.x = 0;
this.y = 0;
if (typeof x === "object") {
this.x = x.x || 0;
this.y = x.y || 0;
} else {
if (y === void 0) {
y = x;
}
this.x = x || 0;
this.y = y || 0;
}
},
/**
* Make a clone of this Vector2.
*
* @method Phaser.Math.Vector2#clone
* @since 3.0.0
*
* @return {Phaser.Math.Vector2} A clone of this Vector2.
*/
clone: function() {
return new Vector2(this.x, this.y);
},
/**
* Copy the components of a given Vector into this Vector.
*
* @method Phaser.Math.Vector2#copy
* @since 3.0.0
*
* @param {Phaser.Types.Math.Vector2Like} src - The Vector to copy the components from.
*
* @return {Phaser.Math.Vector2} This Vector2.
*/
copy: function(src) {
this.x = src.x || 0;
this.y = src.y || 0;
return this;
},
/**
* Set the component values of this Vector from a given Vector2Like object.
*
* @method Phaser.Math.Vector2#setFromObject
* @since 3.0.0
*
* @param {Phaser.Types.Math.Vector2Like} obj - The object containing the component values to set for this Vector.
*
* @return {Phaser.Math.Vector2} This Vector2.
*/
setFromObject: function(obj) {
this.x = obj.x || 0;
this.y = obj.y || 0;
return this;
},
/**
* Set the `x` and `y` components of the this Vector to the given `x` and `y` values.
*
* @method Phaser.Math.Vector2#set
* @since 3.0.0
*
* @param {number} x - The x value to set for this Vector.
* @param {number} [y=x] - The y value to set for this Vector.
*
* @return {Phaser.Math.Vector2} This Vector2.
*/
set: function(x, y) {
if (y === void 0) {
y = x;
}
this.x = x;
this.y = y;
return this;
},
/**
* This method is an alias for `Vector2.set`.
*
* @method Phaser.Math.Vector2#setTo
* @since 3.4.0
*
* @param {number} x - The x value to set for this Vector.
* @param {number} [y=x] - The y value to set for this Vector.
*
* @return {Phaser.Math.Vector2} This Vector2.
*/
setTo: function(x, y) {
return this.set(x, y);
},
/**
* Sets the `x` and `y` values of this object from a given polar coordinate.
*
* @method Phaser.Math.Vector2#setToPolar
* @since 3.0.0
*
* @param {number} azimuth - The angular coordinate, in radians.
* @param {number} [radius=1] - The radial coordinate (length).
*
* @return {Phaser.Math.Vector2} This Vector2.
*/
setToPolar: function(azimuth, radius) {
if (radius == null) {
radius = 1;
}
this.x = Math.cos(azimuth) * radius;
this.y = Math.sin(azimuth) * radius;
return this;
},
/**
* Check whether this Vector is equal to a given Vector.
*
* Performs a strict equality check against each Vector's components.
*
* @method Phaser.Math.Vector2#equals
* @since 3.0.0
*
* @param {Phaser.Types.Math.Vector2Like} v - The vector to compare with this Vector.
*
* @return {boolean} Whether the given Vector is equal to this Vector.
*/
equals: function(v) {
return this.x === v.x && this.y === v.y;
},
/**
* Check whether this Vector is approximately equal to a given Vector.
*
* @method Phaser.Math.Vector2#fuzzyEquals
* @since 3.23.0
*
* @param {Phaser.Types.Math.Vector2Like} v - The vector to compare with this Vector.
* @param {number} [epsilon=0.0001] - The tolerance value.
*
* @return {boolean} Whether both absolute differences of the x and y components are smaller than `epsilon`.
*/
fuzzyEquals: function(v, epsilon) {
return FuzzyEqual(this.x, v.x, epsilon) && FuzzyEqual(this.y, v.y, epsilon);
},
/**
* Calculate the angle between this Vector and the positive x-axis, in radians.
*
* @method Phaser.Math.Vector2#angle
* @since 3.0.0
*
* @return {number} The angle between this Vector, and the positive x-axis, given in radians.
*/
angle: function() {
var angle = Math.atan2(this.y, this.x);
if (angle < 0) {
angle += 2 * Math.PI;
}
return angle;
},
/**
* Set the angle of this Vector.
*
* @method Phaser.Math.Vector2#setAngle
* @since 3.23.0
*
* @param {number} angle - The angle, in radians.
*
* @return {Phaser.Math.Vector2} This Vector2.
*/
setAngle: function(angle) {
return this.setToPolar(angle, this.length());
},
/**
* Add a given Vector to this Vector. Addition is component-wise.
*
* @method Phaser.Math.Vector2#add
* @since 3.0.0
*
* @param {Phaser.Types.Math.Vector2Like} src - The Vector to add to this Vector.
*
* @return {Phaser.Math.Vector2} This Vector2.
*/
add: function(src) {
this.x += src.x;
this.y += src.y;
return this;
},
/**
* Subtract the given Vector from this Vector. Subtraction is component-wise.
*
* @method Phaser.Math.Vector2#subtract
* @since 3.0.0
*
* @param {Phaser.Types.Math.Vector2Like} src - The Vector to subtract from this Vector.
*
* @return {Phaser.Math.Vector2} This Vector2.
*/
subtract: function(src) {
this.x -= src.x;
this.y -= src.y;
return this;
},
/**
* Perform a component-wise multiplication between this Vector and the given Vector.
*
* Multiplies this Vector by the given Vector.
*
* @method Phaser.Math.Vector2#multiply
* @since 3.0.0
*
* @param {Phaser.Types.Math.Vector2Like} src - The Vector to multiply this Vector by.
*
* @return {Phaser.Math.Vector2} This Vector2.
*/
multiply: function(src) {
this.x *= src.x;
this.y *= src.y;
return this;
},
/**
* Scale this Vector by the given value.
*
* @method Phaser.Math.Vector2#scale
* @since 3.0.0
*
* @param {number} value - The value to scale this Vector by.
*
* @return {Phaser.Math.Vector2} This Vector2.
*/
scale: function(value) {
if (isFinite(value)) {
this.x *= value;
this.y *= value;
} else {
this.x = 0;
this.y = 0;
}
return this;
},
/**
* Perform a component-wise division between this Vector and the given Vector.
*
* Divides this Vector by the given Vector.
*
* @method Phaser.Math.Vector2#divide
* @since 3.0.0
*
* @param {Phaser.Types.Math.Vector2Like} src - The Vector to divide this Vector by.
*
* @return {Phaser.Math.Vector2} This Vector2.
*/
divide: function(src) {
this.x /= src.x;
this.y /= src.y;
return this;
},
/**
* Negate the `x` and `y` components of this Vector.
*
* @method Phaser.Math.Vector2#negate
* @since 3.0.0
*
* @return {Phaser.Math.Vector2} This Vector2.
*/
negate: function() {
this.x = -this.x;
this.y = -this.y;
return this;
},
/**
* Calculate the distance between this Vector and the given Vector.
*
* @method Phaser.Math.Vector2#distance
* @since 3.0.0
*
* @param {Phaser.Types.Math.Vector2Like} src - The Vector to calculate the distance to.
*
* @return {number} The distance from this Vector to the given Vector.
*/
distance: function(src) {
var dx = src.x - this.x;
var dy = src.y - this.y;
return Math.sqrt(dx * dx + dy * dy);
},
/**
* Calculate the distance between this Vector and the given Vector, squared.
*
* @method Phaser.Math.Vector2#distanceSq
* @since 3.0.0
*
* @param {Phaser.Types.Math.Vector2Like} src - The Vector to calculate the distance to.
*
* @return {number} The distance from this Vector to the given Vector, squared.
*/
distanceSq: function(src) {
var dx = src.x - this.x;
var dy = src.y - this.y;
return dx * dx + dy * dy;
},
/**
* Calculate the length (or magnitude) of this Vector.
*
* @method Phaser.Math.Vector2#length
* @since 3.0.0
*
* @return {number} The length of this Vector.
*/
length: function() {
var x = this.x;
var y = this.y;
return Math.sqrt(x * x + y * y);
},
/**
* Set the length (or magnitude) of this Vector.
*
* @method Phaser.Math.Vector2#setLength
* @since 3.23.0
*
* @param {number} length
*
* @return {Phaser.Math.Vector2} This Vector2.
*/
setLength: function(length) {
return this.normalize().scale(length);
},
/**
* Calculate the length of this Vector squared.
*
* @method Phaser.Math.Vector2#lengthSq
* @since 3.0.0
*
* @return {number} The length of this Vector, squared.
*/
lengthSq: function() {
var x = this.x;
var y = this.y;
return x * x + y * y;
},
/**
* Normalize this Vector.
*
* Makes the vector a unit length vector (magnitude of 1) in the same direction.
*
* @method Phaser.Math.Vector2#normalize
* @since 3.0.0
*
* @return {Phaser.Math.Vector2} This Vector2.
*/
normalize: function() {
var x = this.x;
var y = this.y;
var len = x * x + y * y;
if (len > 0) {
len = 1 / Math.sqrt(len);
this.x = x * len;
this.y = y * len;
}
return this;
},
/**
* Rotate this Vector to its perpendicular, in the positive direction.
*
* @method Phaser.Math.Vector2#normalizeRightHand
* @since 3.0.0
*
* @return {Phaser.Math.Vector2} This Vector2.
*/
normalizeRightHand: function() {
var x = this.x;
this.x = this.y * -1;
this.y = x;
return this;
},
/**
* Rotate this Vector to its perpendicular, in the negative direction.
*
* @method Phaser.Math.Vector2#normalizeLeftHand
* @since 3.23.0
*
* @return {Phaser.Math.Vector2} This Vector2.
*/
normalizeLeftHand: function() {
var x = this.x;
this.x = this.y;
this.y = x * -1;
return this;
},
/**
* Calculate the dot product of this Vector and the given Vector.
*
* @method Phaser.Math.Vector2#dot
* @since 3.0.0
*
* @param {Phaser.Types.Math.Vector2Like} src - The Vector2 to dot product with this Vector2.
*
* @return {number} The dot product of this Vector and the given Vector.
*/
dot: function(src) {
return this.x * src.x + this.y * src.y;
},
/**
* Calculate the cross product of this Vector and the given Vector.
*
* @method Phaser.Math.Vector2#cross
* @since 3.0.0
*
* @param {Phaser.Types.Math.Vector2Like} src - The Vector2 to cross with this Vector2.
*
* @return {number} The cross product of this Vector and the given Vector.
*/
cross: function(src) {
return this.x * src.y - this.y * src.x;
},
/**
* Linearly interpolate between this Vector and the given Vector.
*
* Interpolates this Vector towards the given Vector.
*
* @method Phaser.Math.Vector2#lerp
* @since 3.0.0
*
* @param {Phaser.Types.Math.Vector2Like} src - The Vector2 to interpolate towards.
* @param {number} [t=0] - The interpolation percentage, between 0 and 1.
*
* @return {Phaser.Math.Vector2} This Vector2.
*/
lerp: function(src, t) {
if (t === void 0) {
t = 0;
}
var ax = this.x;
var ay = this.y;
this.x = ax + t * (src.x - ax);
this.y = ay + t * (src.y - ay);
return this;
},
/**
* Transform this Vector with the given Matrix.
*
* @method Phaser.Math.Vector2#transformMat3
* @since 3.0.0
*
* @param {Phaser.Math.Matrix3} mat - The Matrix3 to transform this Vector2 with.
*
* @return {Phaser.Math.Vector2} This Vector2.
*/
transformMat3: function(mat) {
var x = this.x;
var y = this.y;
var m = mat.val;
this.x = m[0] * x + m[3] * y + m[6];
this.y = m[1] * x + m[4] * y + m[7];
return this;
},
/**
* Transform this Vector with the given Matrix.
*
* @method Phaser.Math.Vector2#transformMat4
* @since 3.0.0
*
* @param {Phaser.Math.Matrix4} mat - The Matrix4 to transform this Vector2 with.
*
* @return {Phaser.Math.Vector2} This Vector2.
*/
transformMat4: function(mat) {
var x = this.x;
var y = this.y;
var m = mat.val;
this.x = m[0] * x + m[4] * y + m[12];
this.y = m[1] * x + m[5] * y + m[13];
return this;
},
/**
* Make this Vector the zero vector (0, 0).
*
* @method Phaser.Math.Vector2#reset
* @since 3.0.0
*
* @return {Phaser.Math.Vector2} This Vector2.
*/
reset: function() {
this.x = 0;
this.y = 0;
return this;
},
/**
* Limit the length (or magnitude) of this Vector.
*
* @method Phaser.Math.Vector2#limit
* @since 3.23.0
*
* @param {number} max - The maximum length.
*
* @return {Phaser.Math.Vector2} This Vector2.
*/
limit: function(max) {
var len = this.length();
if (len && len > max) {
this.scale(max / len);
}
return this;
},
/**
* Reflect this Vector off a line defined by a normal.
*
* @method Phaser.Math.Vector2#reflect
* @since 3.23.0
*
* @param {Phaser.Math.Vector2} normal - A vector perpendicular to the line.
*
* @return {Phaser.Math.Vector2} This Vector2.
*/
reflect: function(normal) {
normal = normal.clone().normalize();
return this.subtract(normal.scale(2 * this.dot(normal)));
},
/**
* Reflect this Vector across another.
*
* @method Phaser.Math.Vector2#mirror
* @since 3.23.0
*
* @param {Phaser.Math.Vector2} axis - A vector to reflect across.
*
* @return {Phaser.Math.Vector2} This Vector2.
*/
mirror: function(axis) {
return this.reflect(axis).negate();
},
/**
* Rotate this Vector by an angle amount.
*
* @method Phaser.Math.Vector2#rotate
* @since 3.23.0
*
* @param {number} delta - The angle to rotate by, in radians.
*
* @return {Phaser.Math.Vector2} This Vector2.
*/
rotate: function(delta) {
var cos = Math.cos(delta);
var sin = Math.sin(delta);
return this.set(cos * this.x - sin * this.y, sin * this.x + cos * this.y);
},
/**
* Project this Vector onto another.
*
* @method Phaser.Math.Vector2#project
* @since 3.60.0
*
* @param {Phaser.Math.Vector2} src - The vector to project onto.
*
* @return {Phaser.Math.Vector2} This Vector2.
*/
project: function(src) {
var scalar = this.dot(src) / src.dot(src);
return this.copy(src).scale(scalar);
}
});
Vector2.ZERO = new Vector2();
Vector2.RIGHT = new Vector2(1, 0);
Vector2.LEFT = new Vector2(-1, 0);
Vector2.UP = new Vector2(0, -1);
Vector2.DOWN = new Vector2(0, 1);
Vector2.ONE = new Vector2(1, 1);
module2.exports = Vector2;
}
),
/***/
25836: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Vector3 = new Class({
initialize: function Vector32(x, y, z) {
this.x = 0;
this.y = 0;
this.z = 0;
if (typeof x === "object") {
this.x = x.x || 0;
this.y = x.y || 0;
this.z = x.z || 0;
} else {
this.x = x || 0;
this.y = y || 0;
this.z = z || 0;
}
},
/**
* Set this Vector to point up.
*
* Sets the y component of the vector to 1, and the others to 0.
*
* @method Phaser.Math.Vector3#up
* @since 3.0.0
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
up: function() {
this.x = 0;
this.y = 1;
this.z = 0;
return this;
},
/**
* Sets the components of this Vector to be the `Math.min` result from the given vector.
*
* @method Phaser.Math.Vector3#min
* @since 3.50.0
*
* @param {Phaser.Math.Vector3} v - The Vector3 to check the minimum values against.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
min: function(v) {
this.x = Math.min(this.x, v.x);
this.y = Math.min(this.y, v.y);
this.z = Math.min(this.z, v.z);
return this;
},
/**
* Sets the components of this Vector to be the `Math.max` result from the given vector.
*
* @method Phaser.Math.Vector3#max
* @since 3.50.0
*
* @param {Phaser.Math.Vector3} v - The Vector3 to check the maximum values against.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
max: function(v) {
this.x = Math.max(this.x, v.x);
this.y = Math.max(this.y, v.y);
this.z = Math.max(this.z, v.z);
return this;
},
/**
* Make a clone of this Vector3.
*
* @method Phaser.Math.Vector3#clone
* @since 3.0.0
*
* @return {Phaser.Math.Vector3} A new Vector3 object containing this Vectors values.
*/
clone: function() {
return new Vector3(this.x, this.y, this.z);
},
/**
* Adds the two given Vector3s and sets the results into this Vector3.
*
* @method Phaser.Math.Vector3#addVectors
* @since 3.50.0
*
* @param {Phaser.Math.Vector3} a - The first Vector to add.
* @param {Phaser.Math.Vector3} b - The second Vector to add.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
addVectors: function(a, b) {
this.x = a.x + b.x;
this.y = a.y + b.y;
this.z = a.z + b.z;
return this;
},
/**
* Subtracts the two given Vector3s and sets the results into this Vector3.
*
* @method Phaser.Math.Vector3#subVectors
* @since 3.85.0
*
* @param {Phaser.Math.Vector3} a - The first Vector to sub.
* @param {Phaser.Math.Vector3} b - The second Vector to sub.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
subVectors: function(a, b) {
this.x = a.x - b.x;
this.y = a.y - b.y;
this.z = a.z - b.z;
return this;
},
/**
* Calculate the cross (vector) product of two given Vectors.
*
* @method Phaser.Math.Vector3#crossVectors
* @since 3.0.0
*
* @param {Phaser.Math.Vector3} a - The first Vector to multiply.
* @param {Phaser.Math.Vector3} b - The second Vector to multiply.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
crossVectors: function(a, b) {
var ax = a.x;
var ay = a.y;
var az = a.z;
var bx = b.x;
var by = b.y;
var bz = b.z;
this.x = ay * bz - az * by;
this.y = az * bx - ax * bz;
this.z = ax * by - ay * bx;
return this;
},
/**
* Check whether this Vector is equal to a given Vector.
*
* Performs a strict equality check against each Vector's components.
*
* @method Phaser.Math.Vector3#equals
* @since 3.0.0
*
* @param {Phaser.Math.Vector3} v - The Vector3 to compare against.
*
* @return {boolean} True if the two vectors strictly match, otherwise false.
*/
equals: function(v) {
return this.x === v.x && this.y === v.y && this.z === v.z;
},
/**
* Copy the components of a given Vector into this Vector.
*
* @method Phaser.Math.Vector3#copy
* @since 3.0.0
*
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} src - The Vector to copy the components from.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
copy: function(src) {
this.x = src.x;
this.y = src.y;
this.z = src.z || 0;
return this;
},
/**
* Set the `x`, `y`, and `z` components of this Vector to the given `x`, `y`, and `z` values.
*
* @method Phaser.Math.Vector3#set
* @since 3.0.0
*
* @param {(number|object)} x - The x value to set for this Vector, or an object containing x, y and z components.
* @param {number} [y] - The y value to set for this Vector.
* @param {number} [z] - The z value to set for this Vector.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
set: function(x, y, z) {
if (typeof x === "object") {
this.x = x.x || 0;
this.y = x.y || 0;
this.z = x.z || 0;
} else {
this.x = x || 0;
this.y = y || 0;
this.z = z || 0;
}
return this;
},
/**
* Sets the components of this Vector3 from the position of the given Matrix4.
*
* @method Phaser.Math.Vector3#setFromMatrixPosition
* @since 3.50.0
*
* @param {Phaser.Math.Matrix4} mat4 - The Matrix4 to get the position from.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
setFromMatrixPosition: function(m) {
return this.fromArray(m.val, 12);
},
/**
* Sets the components of this Vector3 from the Matrix4 column specified.
*
* @method Phaser.Math.Vector3#setFromMatrixColumn
* @since 3.50.0
*
* @param {Phaser.Math.Matrix4} mat4 - The Matrix4 to get the column from.
* @param {number} index - The column index.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
setFromMatrixColumn: function(mat4, index) {
return this.fromArray(mat4.val, index * 4);
},
/**
* Sets the components of this Vector3 from the given array, based on the offset.
*
* Vector3.x = array[offset]
* Vector3.y = array[offset + 1]
* Vector3.z = array[offset + 2]
*
* @method Phaser.Math.Vector3#fromArray
* @since 3.50.0
*
* @param {number[]} array - The array of values to get this Vector from.
* @param {number} [offset=0] - The offset index into the array.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
fromArray: function(array, offset) {
if (offset === void 0) {
offset = 0;
}
this.x = array[offset];
this.y = array[offset + 1];
this.z = array[offset + 2];
return this;
},
/**
* Add a given Vector to this Vector. Addition is component-wise.
*
* @method Phaser.Math.Vector3#add
* @since 3.0.0
*
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to add to this Vector.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
add: function(v) {
this.x += v.x;
this.y += v.y;
this.z += v.z || 0;
return this;
},
/**
* Add the given value to each component of this Vector.
*
* @method Phaser.Math.Vector3#addScalar
* @since 3.50.0
*
* @param {number} s - The amount to add to this Vector.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
addScalar: function(s) {
this.x += s;
this.y += s;
this.z += s;
return this;
},
/**
* Add and scale a given Vector to this Vector. Addition is component-wise.
*
* @method Phaser.Math.Vector3#addScale
* @since 3.50.0
*
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to add to this Vector.
* @param {number} scale - The amount to scale `v` by.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
addScale: function(v, scale) {
this.x += v.x * scale;
this.y += v.y * scale;
this.z += v.z * scale || 0;
return this;
},
/**
* Subtract the given Vector from this Vector. Subtraction is component-wise.
*
* @method Phaser.Math.Vector3#subtract
* @since 3.0.0
*
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to subtract from this Vector.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
subtract: function(v) {
this.x -= v.x;
this.y -= v.y;
this.z -= v.z || 0;
return this;
},
/**
* Perform a component-wise multiplication between this Vector and the given Vector.
*
* Multiplies this Vector by the given Vector.
*
* @method Phaser.Math.Vector3#multiply
* @since 3.0.0
*
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to multiply this Vector by.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
multiply: function(v) {
this.x *= v.x;
this.y *= v.y;
this.z *= v.z || 1;
return this;
},
/**
* Scale this Vector by the given value.
*
* @method Phaser.Math.Vector3#scale
* @since 3.0.0
*
* @param {number} scale - The value to scale this Vector by.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
scale: function(scale) {
if (isFinite(scale)) {
this.x *= scale;
this.y *= scale;
this.z *= scale;
} else {
this.x = 0;
this.y = 0;
this.z = 0;
}
return this;
},
/**
* Perform a component-wise division between this Vector and the given Vector.
*
* Divides this Vector by the given Vector.
*
* @method Phaser.Math.Vector3#divide
* @since 3.0.0
*
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to divide this Vector by.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
divide: function(v) {
this.x /= v.x;
this.y /= v.y;
this.z /= v.z || 1;
return this;
},
/**
* Negate the `x`, `y` and `z` components of this Vector.
*
* @method Phaser.Math.Vector3#negate
* @since 3.0.0
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
negate: function() {
this.x = -this.x;
this.y = -this.y;
this.z = -this.z;
return this;
},
/**
* Calculate the distance between this Vector and the given Vector.
*
* @method Phaser.Math.Vector3#distance
* @since 3.0.0
*
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to calculate the distance to.
*
* @return {number} The distance from this Vector to the given Vector.
*/
distance: function(v) {
var dx = v.x - this.x;
var dy = v.y - this.y;
var dz = v.z - this.z || 0;
return Math.sqrt(dx * dx + dy * dy + dz * dz);
},
/**
* Calculate the distance between this Vector and the given Vector, squared.
*
* @method Phaser.Math.Vector3#distanceSq
* @since 3.0.0
*
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3)} v - The Vector to calculate the distance to.
*
* @return {number} The distance from this Vector to the given Vector, squared.
*/
distanceSq: function(v) {
var dx = v.x - this.x;
var dy = v.y - this.y;
var dz = v.z - this.z || 0;
return dx * dx + dy * dy + dz * dz;
},
/**
* Calculate the length (or magnitude) of this Vector.
*
* @method Phaser.Math.Vector3#length
* @since 3.0.0
*
* @return {number} The length of this Vector.
*/
length: function() {
var x = this.x;
var y = this.y;
var z = this.z;
return Math.sqrt(x * x + y * y + z * z);
},
/**
* Calculate the length of this Vector squared.
*
* @method Phaser.Math.Vector3#lengthSq
* @since 3.0.0
*
* @return {number} The length of this Vector, squared.
*/
lengthSq: function() {
var x = this.x;
var y = this.y;
var z = this.z;
return x * x + y * y + z * z;
},
/**
* Normalize this Vector.
*
* Makes the vector a unit length vector (magnitude of 1) in the same direction.
*
* @method Phaser.Math.Vector3#normalize
* @since 3.0.0
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
normalize: function() {
var x = this.x;
var y = this.y;
var z = this.z;
var len = x * x + y * y + z * z;
if (len > 0) {
len = 1 / Math.sqrt(len);
this.x = x * len;
this.y = y * len;
this.z = z * len;
}
return this;
},
/**
* Calculate the dot product of this Vector and the given Vector.
*
* @method Phaser.Math.Vector3#dot
* @since 3.0.0
*
* @param {Phaser.Math.Vector3} v - The Vector3 to dot product with this Vector3.
*
* @return {number} The dot product of this Vector and `v`.
*/
dot: function(v) {
return this.x * v.x + this.y * v.y + this.z * v.z;
},
/**
* Calculate the cross (vector) product of this Vector (which will be modified) and the given Vector.
*
* @method Phaser.Math.Vector3#cross
* @since 3.0.0
*
* @param {Phaser.Math.Vector3} v - The Vector to cross product with.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
cross: function(v) {
var ax = this.x;
var ay = this.y;
var az = this.z;
var bx = v.x;
var by = v.y;
var bz = v.z;
this.x = ay * bz - az * by;
this.y = az * bx - ax * bz;
this.z = ax * by - ay * bx;
return this;
},
/**
* Linearly interpolate between this Vector and the given Vector.
*
* Interpolates this Vector towards the given Vector.
*
* @method Phaser.Math.Vector3#lerp
* @since 3.0.0
*
* @param {Phaser.Math.Vector3} v - The Vector3 to interpolate towards.
* @param {number} [t=0] - The interpolation percentage, between 0 and 1.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
lerp: function(v, t) {
if (t === void 0) {
t = 0;
}
var ax = this.x;
var ay = this.y;
var az = this.z;
this.x = ax + t * (v.x - ax);
this.y = ay + t * (v.y - ay);
this.z = az + t * (v.z - az);
return this;
},
/**
* Takes a Matrix3 and applies it to this Vector3.
*
* @method Phaser.Math.Vector3#applyMatrix3
* @since 3.50.0
*
* @param {Phaser.Math.Matrix3} mat3 - The Matrix3 to apply to this Vector3.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
applyMatrix3: function(mat3) {
var x = this.x;
var y = this.y;
var z = this.z;
var m = mat3.val;
this.x = m[0] * x + m[3] * y + m[6] * z;
this.y = m[1] * x + m[4] * y + m[7] * z;
this.z = m[2] * x + m[5] * y + m[8] * z;
return this;
},
/**
* Takes a Matrix4 and applies it to this Vector3.
*
* @method Phaser.Math.Vector3#applyMatrix4
* @since 3.50.0
*
* @param {Phaser.Math.Matrix4} mat4 - The Matrix4 to apply to this Vector3.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
applyMatrix4: function(mat4) {
var x = this.x;
var y = this.y;
var z = this.z;
var m = mat4.val;
var w = 1 / (m[3] * x + m[7] * y + m[11] * z + m[15]);
this.x = (m[0] * x + m[4] * y + m[8] * z + m[12]) * w;
this.y = (m[1] * x + m[5] * y + m[9] * z + m[13]) * w;
this.z = (m[2] * x + m[6] * y + m[10] * z + m[14]) * w;
return this;
},
/**
* Transform this Vector with the given Matrix.
*
* @method Phaser.Math.Vector3#transformMat3
* @since 3.0.0
*
* @param {Phaser.Math.Matrix3} mat - The Matrix3 to transform this Vector3 with.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
transformMat3: function(mat) {
var x = this.x;
var y = this.y;
var z = this.z;
var m = mat.val;
this.x = x * m[0] + y * m[3] + z * m[6];
this.y = x * m[1] + y * m[4] + z * m[7];
this.z = x * m[2] + y * m[5] + z * m[8];
return this;
},
/**
* Transform this Vector with the given Matrix4.
*
* @method Phaser.Math.Vector3#transformMat4
* @since 3.0.0
*
* @param {Phaser.Math.Matrix4} mat - The Matrix4 to transform this Vector3 with.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
transformMat4: function(mat) {
var x = this.x;
var y = this.y;
var z = this.z;
var m = mat.val;
this.x = m[0] * x + m[4] * y + m[8] * z + m[12];
this.y = m[1] * x + m[5] * y + m[9] * z + m[13];
this.z = m[2] * x + m[6] * y + m[10] * z + m[14];
return this;
},
/**
* Transforms the coordinates of this Vector3 with the given Matrix4.
*
* @method Phaser.Math.Vector3#transformCoordinates
* @since 3.0.0
*
* @param {Phaser.Math.Matrix4} mat - The Matrix4 to transform this Vector3 with.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
transformCoordinates: function(mat) {
var x = this.x;
var y = this.y;
var z = this.z;
var m = mat.val;
var tx = x * m[0] + y * m[4] + z * m[8] + m[12];
var ty = x * m[1] + y * m[5] + z * m[9] + m[13];
var tz = x * m[2] + y * m[6] + z * m[10] + m[14];
var tw = x * m[3] + y * m[7] + z * m[11] + m[15];
this.x = tx / tw;
this.y = ty / tw;
this.z = tz / tw;
return this;
},
/**
* Transform this Vector with the given Quaternion.
*
* @method Phaser.Math.Vector3#transformQuat
* @since 3.0.0
*
* @param {Phaser.Math.Quaternion} q - The Quaternion to transform this Vector with.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
transformQuat: function(q) {
var x = this.x;
var y = this.y;
var z = this.z;
var qx = q.x;
var qy = q.y;
var qz = q.z;
var qw = q.w;
var ix = qw * x + qy * z - qz * y;
var iy = qw * y + qz * x - qx * z;
var iz = qw * z + qx * y - qy * x;
var iw = -qx * x - qy * y - qz * z;
this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy;
this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz;
this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx;
return this;
},
/**
* Multiplies this Vector3 by the specified matrix, applying a W divide. This is useful for projection,
* e.g. unprojecting a 2D point into 3D space.
*
* @method Phaser.Math.Vector3#project
* @since 3.0.0
*
* @param {Phaser.Math.Matrix4} mat - The Matrix4 to multiply this Vector3 with.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
project: function(mat) {
var x = this.x;
var y = this.y;
var z = this.z;
var m = mat.val;
var a00 = m[0];
var a01 = m[1];
var a02 = m[2];
var a03 = m[3];
var a10 = m[4];
var a11 = m[5];
var a12 = m[6];
var a13 = m[7];
var a20 = m[8];
var a21 = m[9];
var a22 = m[10];
var a23 = m[11];
var a30 = m[12];
var a31 = m[13];
var a32 = m[14];
var a33 = m[15];
var lw = 1 / (x * a03 + y * a13 + z * a23 + a33);
this.x = (x * a00 + y * a10 + z * a20 + a30) * lw;
this.y = (x * a01 + y * a11 + z * a21 + a31) * lw;
this.z = (x * a02 + y * a12 + z * a22 + a32) * lw;
return this;
},
/**
* Multiplies this Vector3 by the given view and projection matrices.
*
* @method Phaser.Math.Vector3#projectViewMatrix
* @since 3.50.0
*
* @param {Phaser.Math.Matrix4} viewMatrix - A View Matrix.
* @param {Phaser.Math.Matrix4} projectionMatrix - A Projection Matrix.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
projectViewMatrix: function(viewMatrix, projectionMatrix) {
return this.applyMatrix4(viewMatrix).applyMatrix4(projectionMatrix);
},
/**
* Multiplies this Vector3 by the given inversed projection matrix and world matrix.
*
* @method Phaser.Math.Vector3#unprojectViewMatrix
* @since 3.50.0
*
* @param {Phaser.Math.Matrix4} projectionMatrix - An inversed Projection Matrix.
* @param {Phaser.Math.Matrix4} worldMatrix - A World View Matrix.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
unprojectViewMatrix: function(projectionMatrix, worldMatrix) {
return this.applyMatrix4(projectionMatrix).applyMatrix4(worldMatrix);
},
/**
* Unproject this point from 2D space to 3D space.
* The point should have its x and y properties set to
* 2D screen space, and the z either at 0 (near plane)
* or 1 (far plane). The provided matrix is assumed to already
* be combined, i.e. projection * view * model.
*
* After this operation, this vector's (x, y, z) components will
* represent the unprojected 3D coordinate.
*
* @method Phaser.Math.Vector3#unproject
* @since 3.0.0
*
* @param {Phaser.Math.Vector4} viewport - Screen x, y, width and height in pixels.
* @param {Phaser.Math.Matrix4} invProjectionView - Combined projection and view matrix.
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
unproject: function(viewport, invProjectionView) {
var viewX = viewport.x;
var viewY = viewport.y;
var viewWidth = viewport.z;
var viewHeight = viewport.w;
var x = this.x - viewX;
var y = viewHeight - this.y - 1 - viewY;
var z = this.z;
this.x = 2 * x / viewWidth - 1;
this.y = 2 * y / viewHeight - 1;
this.z = 2 * z - 1;
return this.project(invProjectionView);
},
/**
* Make this Vector the zero vector (0, 0, 0).
*
* @method Phaser.Math.Vector3#reset
* @since 3.0.0
*
* @return {Phaser.Math.Vector3} This Vector3.
*/
reset: function() {
this.x = 0;
this.y = 0;
this.z = 0;
return this;
}
});
Vector3.ZERO = new Vector3();
Vector3.RIGHT = new Vector3(1, 0, 0);
Vector3.LEFT = new Vector3(-1, 0, 0);
Vector3.UP = new Vector3(0, -1, 0);
Vector3.DOWN = new Vector3(0, 1, 0);
Vector3.FORWARD = new Vector3(0, 0, 1);
Vector3.BACK = new Vector3(0, 0, -1);
Vector3.ONE = new Vector3(1, 1, 1);
module2.exports = Vector3;
}
),
/***/
61369: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Vector4 = new Class({
initialize: function Vector42(x, y, z, w) {
this.x = 0;
this.y = 0;
this.z = 0;
this.w = 0;
if (typeof x === "object") {
this.x = x.x || 0;
this.y = x.y || 0;
this.z = x.z || 0;
this.w = x.w || 0;
} else {
this.x = x || 0;
this.y = y || 0;
this.z = z || 0;
this.w = w || 0;
}
},
/**
* Make a clone of this Vector4.
*
* @method Phaser.Math.Vector4#clone
* @since 3.0.0
*
* @return {Phaser.Math.Vector4} A clone of this Vector4.
*/
clone: function() {
return new Vector4(this.x, this.y, this.z, this.w);
},
/**
* Copy the components of a given Vector into this Vector.
*
* @method Phaser.Math.Vector4#copy
* @since 3.0.0
*
* @param {Phaser.Math.Vector4} src - The Vector to copy the components from.
*
* @return {Phaser.Math.Vector4} This Vector4.
*/
copy: function(src) {
this.x = src.x;
this.y = src.y;
this.z = src.z || 0;
this.w = src.w || 0;
return this;
},
/**
* Check whether this Vector is equal to a given Vector.
*
* Performs a strict quality check against each Vector's components.
*
* @method Phaser.Math.Vector4#equals
* @since 3.0.0
*
* @param {Phaser.Math.Vector4} v - The vector to check equality with.
*
* @return {boolean} A boolean indicating whether the two Vectors are equal or not.
*/
equals: function(v) {
return this.x === v.x && this.y === v.y && this.z === v.z && this.w === v.w;
},
/**
* Set the `x`, `y`, `z` and `w` components of the this Vector to the given `x`, `y`, `z` and `w` values.
*
* @method Phaser.Math.Vector4#set
* @since 3.0.0
*
* @param {(number|object)} x - The x value to set for this Vector, or an object containing x, y, z and w components.
* @param {number} y - The y value to set for this Vector.
* @param {number} z - The z value to set for this Vector.
* @param {number} w - The z value to set for this Vector.
*
* @return {Phaser.Math.Vector4} This Vector4.
*/
set: function(x, y, z, w) {
if (typeof x === "object") {
this.x = x.x || 0;
this.y = x.y || 0;
this.z = x.z || 0;
this.w = x.w || 0;
} else {
this.x = x || 0;
this.y = y || 0;
this.z = z || 0;
this.w = w || 0;
}
return this;
},
/**
* Add a given Vector to this Vector. Addition is component-wise.
*
* @method Phaser.Math.Vector4#add
* @since 3.0.0
*
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to add to this Vector.
*
* @return {Phaser.Math.Vector4} This Vector4.
*/
add: function(v) {
this.x += v.x;
this.y += v.y;
this.z += v.z || 0;
this.w += v.w || 0;
return this;
},
/**
* Subtract the given Vector from this Vector. Subtraction is component-wise.
*
* @method Phaser.Math.Vector4#subtract
* @since 3.0.0
*
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to subtract from this Vector.
*
* @return {Phaser.Math.Vector4} This Vector4.
*/
subtract: function(v) {
this.x -= v.x;
this.y -= v.y;
this.z -= v.z || 0;
this.w -= v.w || 0;
return this;
},
/**
* Scale this Vector by the given value.
*
* @method Phaser.Math.Vector4#scale
* @since 3.0.0
*
* @param {number} scale - The value to scale this Vector by.
*
* @return {Phaser.Math.Vector4} This Vector4.
*/
scale: function(scale) {
this.x *= scale;
this.y *= scale;
this.z *= scale;
this.w *= scale;
return this;
},
/**
* Calculate the length (or magnitude) of this Vector.
*
* @method Phaser.Math.Vector4#length
* @since 3.0.0
*
* @return {number} The length of this Vector.
*/
length: function() {
var x = this.x;
var y = this.y;
var z = this.z;
var w = this.w;
return Math.sqrt(x * x + y * y + z * z + w * w);
},
/**
* Calculate the length of this Vector squared.
*
* @method Phaser.Math.Vector4#lengthSq
* @since 3.0.0
*
* @return {number} The length of this Vector, squared.
*/
lengthSq: function() {
var x = this.x;
var y = this.y;
var z = this.z;
var w = this.w;
return x * x + y * y + z * z + w * w;
},
/**
* Normalize this Vector.
*
* Makes the vector a unit length vector (magnitude of 1) in the same direction.
*
* @method Phaser.Math.Vector4#normalize
* @since 3.0.0
*
* @return {Phaser.Math.Vector4} This Vector4.
*/
normalize: function() {
var x = this.x;
var y = this.y;
var z = this.z;
var w = this.w;
var len = x * x + y * y + z * z + w * w;
if (len > 0) {
len = 1 / Math.sqrt(len);
this.x = x * len;
this.y = y * len;
this.z = z * len;
this.w = w * len;
}
return this;
},
/**
* Calculate the dot product of this Vector and the given Vector.
*
* @method Phaser.Math.Vector4#dot
* @since 3.0.0
*
* @param {Phaser.Math.Vector4} v - The Vector4 to dot product with this Vector4.
*
* @return {number} The dot product of this Vector and the given Vector.
*/
dot: function(v) {
return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;
},
/**
* Linearly interpolate between this Vector and the given Vector.
*
* Interpolates this Vector towards the given Vector.
*
* @method Phaser.Math.Vector4#lerp
* @since 3.0.0
*
* @param {Phaser.Math.Vector4} v - The Vector4 to interpolate towards.
* @param {number} [t=0] - The interpolation percentage, between 0 and 1.
*
* @return {Phaser.Math.Vector4} This Vector4.
*/
lerp: function(v, t) {
if (t === void 0) {
t = 0;
}
var ax = this.x;
var ay = this.y;
var az = this.z;
var aw = this.w;
this.x = ax + t * (v.x - ax);
this.y = ay + t * (v.y - ay);
this.z = az + t * (v.z - az);
this.w = aw + t * (v.w - aw);
return this;
},
/**
* Perform a component-wise multiplication between this Vector and the given Vector.
*
* Multiplies this Vector by the given Vector.
*
* @method Phaser.Math.Vector4#multiply
* @since 3.0.0
*
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to multiply this Vector by.
*
* @return {Phaser.Math.Vector4} This Vector4.
*/
multiply: function(v) {
this.x *= v.x;
this.y *= v.y;
this.z *= v.z || 1;
this.w *= v.w || 1;
return this;
},
/**
* Perform a component-wise division between this Vector and the given Vector.
*
* Divides this Vector by the given Vector.
*
* @method Phaser.Math.Vector4#divide
* @since 3.0.0
*
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to divide this Vector by.
*
* @return {Phaser.Math.Vector4} This Vector4.
*/
divide: function(v) {
this.x /= v.x;
this.y /= v.y;
this.z /= v.z || 1;
this.w /= v.w || 1;
return this;
},
/**
* Calculate the distance between this Vector and the given Vector.
*
* @method Phaser.Math.Vector4#distance
* @since 3.0.0
*
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to calculate the distance to.
*
* @return {number} The distance from this Vector to the given Vector.
*/
distance: function(v) {
var dx = v.x - this.x;
var dy = v.y - this.y;
var dz = v.z - this.z || 0;
var dw = v.w - this.w || 0;
return Math.sqrt(dx * dx + dy * dy + dz * dz + dw * dw);
},
/**
* Calculate the distance between this Vector and the given Vector, squared.
*
* @method Phaser.Math.Vector4#distanceSq
* @since 3.0.0
*
* @param {(Phaser.Math.Vector2|Phaser.Math.Vector3|Phaser.Math.Vector4)} v - The Vector to calculate the distance to.
*
* @return {number} The distance from this Vector to the given Vector, squared.
*/
distanceSq: function(v) {
var dx = v.x - this.x;
var dy = v.y - this.y;
var dz = v.z - this.z || 0;
var dw = v.w - this.w || 0;
return dx * dx + dy * dy + dz * dz + dw * dw;
},
/**
* Negate the `x`, `y`, `z` and `w` components of this Vector.
*
* @method Phaser.Math.Vector4#negate
* @since 3.0.0
*
* @return {Phaser.Math.Vector4} This Vector4.
*/
negate: function() {
this.x = -this.x;
this.y = -this.y;
this.z = -this.z;
this.w = -this.w;
return this;
},
/**
* Transform this Vector with the given Matrix.
*
* @method Phaser.Math.Vector4#transformMat4
* @since 3.0.0
*
* @param {Phaser.Math.Matrix4} mat - The Matrix4 to transform this Vector4 with.
*
* @return {Phaser.Math.Vector4} This Vector4.
*/
transformMat4: function(mat) {
var x = this.x;
var y = this.y;
var z = this.z;
var w = this.w;
var m = mat.val;
this.x = m[0] * x + m[4] * y + m[8] * z + m[12] * w;
this.y = m[1] * x + m[5] * y + m[9] * z + m[13] * w;
this.z = m[2] * x + m[6] * y + m[10] * z + m[14] * w;
this.w = m[3] * x + m[7] * y + m[11] * z + m[15] * w;
return this;
},
/**
* Transform this Vector with the given Quaternion.
*
* @method Phaser.Math.Vector4#transformQuat
* @since 3.0.0
*
* @param {Phaser.Math.Quaternion} q - The Quaternion to transform this Vector with.
*
* @return {Phaser.Math.Vector4} This Vector4.
*/
transformQuat: function(q) {
var x = this.x;
var y = this.y;
var z = this.z;
var qx = q.x;
var qy = q.y;
var qz = q.z;
var qw = q.w;
var ix = qw * x + qy * z - qz * y;
var iy = qw * y + qz * x - qx * z;
var iz = qw * z + qx * y - qy * x;
var iw = -qx * x - qy * y - qz * z;
this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy;
this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz;
this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx;
return this;
},
/**
* Make this Vector the zero vector (0, 0, 0, 0).
*
* @method Phaser.Math.Vector4#reset
* @since 3.0.0
*
* @return {Phaser.Math.Vector4} This Vector4.
*/
reset: function() {
this.x = 0;
this.y = 0;
this.z = 0;
this.w = 0;
return this;
}
});
Vector4.prototype.sub = Vector4.prototype.subtract;
Vector4.prototype.mul = Vector4.prototype.multiply;
Vector4.prototype.div = Vector4.prototype.divide;
Vector4.prototype.dist = Vector4.prototype.distance;
Vector4.prototype.distSq = Vector4.prototype.distanceSq;
Vector4.prototype.len = Vector4.prototype.length;
Vector4.prototype.lenSq = Vector4.prototype.lengthSq;
module2.exports = Vector4;
}
),
/***/
60417: (
/***/
(module2) => {
var Within = function(a, b, tolerance) {
return Math.abs(a - b) <= tolerance;
};
module2.exports = Within;
}
),
/***/
15994: (
/***/
(module2) => {
var Wrap = function(value, min, max) {
var range = max - min;
return min + ((value - min) % range + range) % range;
};
module2.exports = Wrap;
}
),
/***/
31040: (
/***/
(module2) => {
var Between = function(x1, y1, x2, y2) {
return Math.atan2(y2 - y1, x2 - x1);
};
module2.exports = Between;
}
),
/***/
55495: (
/***/
(module2) => {
var BetweenPoints = function(point1, point2) {
return Math.atan2(point2.y - point1.y, point2.x - point1.x);
};
module2.exports = BetweenPoints;
}
),
/***/
128: (
/***/
(module2) => {
var BetweenPointsY = function(point1, point2) {
return Math.atan2(point2.x - point1.x, point2.y - point1.y);
};
module2.exports = BetweenPointsY;
}
),
/***/
41273: (
/***/
(module2) => {
var BetweenY = function(x1, y1, x2, y2) {
return Math.atan2(x2 - x1, y2 - y1);
};
module2.exports = BetweenY;
}
),
/***/
1432: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(36383);
var CounterClockwise = function(angle) {
if (angle > Math.PI) {
angle -= CONST.PI2;
}
return Math.abs(((angle + CONST.TAU) % CONST.PI2 - CONST.PI2) % CONST.PI2);
};
module2.exports = CounterClockwise;
}
),
/***/
12407: (
/***/
(module2) => {
var Normalize = function(angle) {
angle = angle % (2 * Math.PI);
if (angle >= 0) {
return angle;
} else {
return angle + 2 * Math.PI;
}
};
module2.exports = Normalize;
}
),
/***/
53993: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var FloatBetween = __webpack_require__2(99472);
var Random = function() {
return FloatBetween(-Math.PI, Math.PI);
};
module2.exports = Random;
}
),
/***/
86564: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var FloatBetween = __webpack_require__2(99472);
var RandomDegrees = function() {
return FloatBetween(-180, 180);
};
module2.exports = RandomDegrees;
}
),
/***/
90154: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Normalize = __webpack_require__2(12407);
var Reverse = function(angle) {
return Normalize(angle + Math.PI);
};
module2.exports = Reverse;
}
),
/***/
48736: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var MATH_CONST = __webpack_require__2(36383);
var RotateTo = function(currentAngle, targetAngle, lerp) {
if (lerp === void 0) {
lerp = 0.05;
}
if (currentAngle === targetAngle) {
return currentAngle;
}
if (Math.abs(targetAngle - currentAngle) <= lerp || Math.abs(targetAngle - currentAngle) >= MATH_CONST.PI2 - lerp) {
currentAngle = targetAngle;
} else {
if (Math.abs(targetAngle - currentAngle) > Math.PI) {
if (targetAngle < currentAngle) {
targetAngle += MATH_CONST.PI2;
} else {
targetAngle -= MATH_CONST.PI2;
}
}
if (targetAngle > currentAngle) {
currentAngle += lerp;
} else if (targetAngle < currentAngle) {
currentAngle -= lerp;
}
}
return currentAngle;
};
module2.exports = RotateTo;
}
),
/***/
61430: (
/***/
(module2) => {
var ShortestBetween = function(angle1, angle2) {
var difference = angle2 - angle1;
if (difference === 0) {
return 0;
}
var times = Math.floor((difference - -180) / 360);
return difference - times * 360;
};
module2.exports = ShortestBetween;
}
),
/***/
86554: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var MathWrap = __webpack_require__2(15994);
var Wrap = function(angle) {
return MathWrap(angle, -Math.PI, Math.PI);
};
module2.exports = Wrap;
}
),
/***/
30954: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Wrap = __webpack_require__2(15994);
var WrapDegrees = function(angle) {
return Wrap(angle, -180, 180);
};
module2.exports = WrapDegrees;
}
),
/***/
25588: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Between: __webpack_require__2(31040),
BetweenPoints: __webpack_require__2(55495),
BetweenPointsY: __webpack_require__2(128),
BetweenY: __webpack_require__2(41273),
CounterClockwise: __webpack_require__2(1432),
Normalize: __webpack_require__2(12407),
Random: __webpack_require__2(53993),
RandomDegrees: __webpack_require__2(86564),
Reverse: __webpack_require__2(90154),
RotateTo: __webpack_require__2(48736),
ShortestBetween: __webpack_require__2(61430),
Wrap: __webpack_require__2(86554),
WrapDegrees: __webpack_require__2(30954)
};
}
),
/***/
36383: (
/***/
(module2) => {
var MATH_CONST = {
/**
* The value of PI * 2.
*
* @name Phaser.Math.PI2
* @type {number}
* @since 3.0.0
*/
PI2: Math.PI * 2,
/**
* The value of PI * 0.5.
*
* Yes, we understand that this should actually be PI * 2, but
* it has been like this for so long we can't change it now.
* If you need PI * 2, use the PI2 constant instead.
*
* @name Phaser.Math.TAU
* @type {number}
* @since 3.0.0
*/
TAU: Math.PI * 0.5,
/**
* An epsilon value (1.0e-6)
*
* @name Phaser.Math.EPSILON
* @type {number}
* @since 3.0.0
*/
EPSILON: 1e-6,
/**
* For converting degrees to radians (PI / 180)
*
* @name Phaser.Math.DEG_TO_RAD
* @type {number}
* @since 3.0.0
*/
DEG_TO_RAD: Math.PI / 180,
/**
* For converting radians to degrees (180 / PI)
*
* @name Phaser.Math.RAD_TO_DEG
* @type {number}
* @since 3.0.0
*/
RAD_TO_DEG: 180 / Math.PI,
/**
* An instance of the Random Number Generator.
* This is not set until the Game boots.
*
* @name Phaser.Math.RND
* @type {Phaser.Math.RandomDataGenerator}
* @since 3.0.0
*/
RND: null,
/**
* The minimum safe integer this browser supports.
* We use a const for backward compatibility with Internet Explorer.
*
* @name Phaser.Math.MIN_SAFE_INTEGER
* @type {number}
* @since 3.21.0
*/
MIN_SAFE_INTEGER: Number.MIN_SAFE_INTEGER || -9007199254740991,
/**
* The maximum safe integer this browser supports.
* We use a const for backward compatibility with Internet Explorer.
*
* @name Phaser.Math.MAX_SAFE_INTEGER
* @type {number}
* @since 3.21.0
*/
MAX_SAFE_INTEGER: Number.MAX_SAFE_INTEGER || 9007199254740991
};
module2.exports = MATH_CONST;
}
),
/***/
20339: (
/***/
(module2) => {
var DistanceBetween = function(x1, y1, x2, y2) {
var dx = x1 - x2;
var dy = y1 - y2;
return Math.sqrt(dx * dx + dy * dy);
};
module2.exports = DistanceBetween;
}
),
/***/
52816: (
/***/
(module2) => {
var DistanceBetweenPoints = function(a, b) {
var dx = a.x - b.x;
var dy = a.y - b.y;
return Math.sqrt(dx * dx + dy * dy);
};
module2.exports = DistanceBetweenPoints;
}
),
/***/
64559: (
/***/
(module2) => {
var DistanceBetweenPointsSquared = function(a, b) {
var dx = a.x - b.x;
var dy = a.y - b.y;
return dx * dx + dy * dy;
};
module2.exports = DistanceBetweenPointsSquared;
}
),
/***/
82340: (
/***/
(module2) => {
var ChebyshevDistance = function(x1, y1, x2, y2) {
return Math.max(Math.abs(x1 - x2), Math.abs(y1 - y2));
};
module2.exports = ChebyshevDistance;
}
),
/***/
14390: (
/***/
(module2) => {
var DistancePower = function(x1, y1, x2, y2, pow) {
if (pow === void 0) {
pow = 2;
}
return Math.sqrt(Math.pow(x2 - x1, pow) + Math.pow(y2 - y1, pow));
};
module2.exports = DistancePower;
}
),
/***/
2243: (
/***/
(module2) => {
var SnakeDistance = function(x1, y1, x2, y2) {
return Math.abs(x1 - x2) + Math.abs(y1 - y2);
};
module2.exports = SnakeDistance;
}
),
/***/
89774: (
/***/
(module2) => {
var DistanceSquared = function(x1, y1, x2, y2) {
var dx = x1 - x2;
var dy = y1 - y2;
return dx * dx + dy * dy;
};
module2.exports = DistanceSquared;
}
),
/***/
50994: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Between: __webpack_require__2(20339),
BetweenPoints: __webpack_require__2(52816),
BetweenPointsSquared: __webpack_require__2(64559),
Chebyshev: __webpack_require__2(82340),
Power: __webpack_require__2(14390),
Snake: __webpack_require__2(2243),
Squared: __webpack_require__2(89774)
};
}
),
/***/
62640: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Back = __webpack_require__2(54178);
var Bounce = __webpack_require__2(41521);
var Circular = __webpack_require__2(79980);
var Cubic = __webpack_require__2(85433);
var Elastic = __webpack_require__2(99140);
var Expo = __webpack_require__2(48857);
var Linear = __webpack_require__2(81596);
var Quadratic = __webpack_require__2(59133);
var Quartic = __webpack_require__2(98516);
var Quintic = __webpack_require__2(35248);
var Sine = __webpack_require__2(82500);
var Stepped = __webpack_require__2(49752);
module2.exports = {
Power0: Linear,
Power1: Quadratic.Out,
Power2: Cubic.Out,
Power3: Quartic.Out,
Power4: Quintic.Out,
Linear,
Quad: Quadratic.Out,
Cubic: Cubic.Out,
Quart: Quartic.Out,
Quint: Quintic.Out,
Sine: Sine.Out,
Expo: Expo.Out,
Circ: Circular.Out,
Elastic: Elastic.Out,
Back: Back.Out,
Bounce: Bounce.Out,
Stepped,
"Quad.easeIn": Quadratic.In,
"Cubic.easeIn": Cubic.In,
"Quart.easeIn": Quartic.In,
"Quint.easeIn": Quintic.In,
"Sine.easeIn": Sine.In,
"Expo.easeIn": Expo.In,
"Circ.easeIn": Circular.In,
"Elastic.easeIn": Elastic.In,
"Back.easeIn": Back.In,
"Bounce.easeIn": Bounce.In,
"Quad.easeOut": Quadratic.Out,
"Cubic.easeOut": Cubic.Out,
"Quart.easeOut": Quartic.Out,
"Quint.easeOut": Quintic.Out,
"Sine.easeOut": Sine.Out,
"Expo.easeOut": Expo.Out,
"Circ.easeOut": Circular.Out,
"Elastic.easeOut": Elastic.Out,
"Back.easeOut": Back.Out,
"Bounce.easeOut": Bounce.Out,
"Quad.easeInOut": Quadratic.InOut,
"Cubic.easeInOut": Cubic.InOut,
"Quart.easeInOut": Quartic.InOut,
"Quint.easeInOut": Quintic.InOut,
"Sine.easeInOut": Sine.InOut,
"Expo.easeInOut": Expo.InOut,
"Circ.easeInOut": Circular.InOut,
"Elastic.easeInOut": Elastic.InOut,
"Back.easeInOut": Back.InOut,
"Bounce.easeInOut": Bounce.InOut
};
}
),
/***/
1639: (
/***/
(module2) => {
var In = function(v, overshoot) {
if (overshoot === void 0) {
overshoot = 1.70158;
}
return v * v * ((overshoot + 1) * v - overshoot);
};
module2.exports = In;
}
),
/***/
50099: (
/***/
(module2) => {
var InOut = function(v, overshoot) {
if (overshoot === void 0) {
overshoot = 1.70158;
}
var s = overshoot * 1.525;
if ((v *= 2) < 1) {
return 0.5 * (v * v * ((s + 1) * v - s));
} else {
return 0.5 * ((v -= 2) * v * ((s + 1) * v + s) + 2);
}
};
module2.exports = InOut;
}
),
/***/
41286: (
/***/
(module2) => {
var Out = function(v, overshoot) {
if (overshoot === void 0) {
overshoot = 1.70158;
}
return --v * v * ((overshoot + 1) * v + overshoot) + 1;
};
module2.exports = Out;
}
),
/***/
54178: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
In: __webpack_require__2(1639),
Out: __webpack_require__2(41286),
InOut: __webpack_require__2(50099)
};
}
),
/***/
59590: (
/***/
(module2) => {
var In = function(v) {
v = 1 - v;
if (v < 1 / 2.75) {
return 1 - 7.5625 * v * v;
} else if (v < 2 / 2.75) {
return 1 - (7.5625 * (v -= 1.5 / 2.75) * v + 0.75);
} else if (v < 2.5 / 2.75) {
return 1 - (7.5625 * (v -= 2.25 / 2.75) * v + 0.9375);
} else {
return 1 - (7.5625 * (v -= 2.625 / 2.75) * v + 0.984375);
}
};
module2.exports = In;
}
),
/***/
41788: (
/***/
(module2) => {
var InOut = function(v) {
var reverse = false;
if (v < 0.5) {
v = 1 - v * 2;
reverse = true;
} else {
v = v * 2 - 1;
}
if (v < 1 / 2.75) {
v = 7.5625 * v * v;
} else if (v < 2 / 2.75) {
v = 7.5625 * (v -= 1.5 / 2.75) * v + 0.75;
} else if (v < 2.5 / 2.75) {
v = 7.5625 * (v -= 2.25 / 2.75) * v + 0.9375;
} else {
v = 7.5625 * (v -= 2.625 / 2.75) * v + 0.984375;
}
if (reverse) {
return (1 - v) * 0.5;
} else {
return v * 0.5 + 0.5;
}
};
module2.exports = InOut;
}
),
/***/
69905: (
/***/
(module2) => {
var Out = function(v) {
if (v < 1 / 2.75) {
return 7.5625 * v * v;
} else if (v < 2 / 2.75) {
return 7.5625 * (v -= 1.5 / 2.75) * v + 0.75;
} else if (v < 2.5 / 2.75) {
return 7.5625 * (v -= 2.25 / 2.75) * v + 0.9375;
} else {
return 7.5625 * (v -= 2.625 / 2.75) * v + 0.984375;
}
};
module2.exports = Out;
}
),
/***/
41521: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
In: __webpack_require__2(59590),
Out: __webpack_require__2(69905),
InOut: __webpack_require__2(41788)
};
}
),
/***/
91861: (
/***/
(module2) => {
var In = function(v) {
return 1 - Math.sqrt(1 - v * v);
};
module2.exports = In;
}
),
/***/
4177: (
/***/
(module2) => {
var InOut = function(v) {
if ((v *= 2) < 1) {
return -0.5 * (Math.sqrt(1 - v * v) - 1);
} else {
return 0.5 * (Math.sqrt(1 - (v -= 2) * v) + 1);
}
};
module2.exports = InOut;
}
),
/***/
57512: (
/***/
(module2) => {
var Out = function(v) {
return Math.sqrt(1 - --v * v);
};
module2.exports = Out;
}
),
/***/
79980: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
In: __webpack_require__2(91861),
Out: __webpack_require__2(57512),
InOut: __webpack_require__2(4177)
};
}
),
/***/
51150: (
/***/
(module2) => {
var In = function(v) {
return v * v * v;
};
module2.exports = In;
}
),
/***/
82820: (
/***/
(module2) => {
var InOut = function(v) {
if ((v *= 2) < 1) {
return 0.5 * v * v * v;
} else {
return 0.5 * ((v -= 2) * v * v + 2);
}
};
module2.exports = InOut;
}
),
/***/
35033: (
/***/
(module2) => {
var Out = function(v) {
return --v * v * v + 1;
};
module2.exports = Out;
}
),
/***/
85433: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
In: __webpack_require__2(51150),
Out: __webpack_require__2(35033),
InOut: __webpack_require__2(82820)
};
}
),
/***/
69965: (
/***/
(module2) => {
var In = function(v, amplitude, period) {
if (amplitude === void 0) {
amplitude = 0.1;
}
if (period === void 0) {
period = 0.1;
}
if (v === 0) {
return 0;
} else if (v === 1) {
return 1;
} else {
var s = period / 4;
if (amplitude < 1) {
amplitude = 1;
} else {
s = period * Math.asin(1 / amplitude) / (2 * Math.PI);
}
return -(amplitude * Math.pow(2, 10 * (v -= 1)) * Math.sin((v - s) * (2 * Math.PI) / period));
}
};
module2.exports = In;
}
),
/***/
50665: (
/***/
(module2) => {
var InOut = function(v, amplitude, period) {
if (amplitude === void 0) {
amplitude = 0.1;
}
if (period === void 0) {
period = 0.1;
}
if (v === 0) {
return 0;
} else if (v === 1) {
return 1;
} else {
var s = period / 4;
if (amplitude < 1) {
amplitude = 1;
} else {
s = period * Math.asin(1 / amplitude) / (2 * Math.PI);
}
if ((v *= 2) < 1) {
return -0.5 * (amplitude * Math.pow(2, 10 * (v -= 1)) * Math.sin((v - s) * (2 * Math.PI) / period));
} else {
return amplitude * Math.pow(2, -10 * (v -= 1)) * Math.sin((v - s) * (2 * Math.PI) / period) * 0.5 + 1;
}
}
};
module2.exports = InOut;
}
),
/***/
7744: (
/***/
(module2) => {
var Out = function(v, amplitude, period) {
if (amplitude === void 0) {
amplitude = 0.1;
}
if (period === void 0) {
period = 0.1;
}
if (v === 0) {
return 0;
} else if (v === 1) {
return 1;
} else {
var s = period / 4;
if (amplitude < 1) {
amplitude = 1;
} else {
s = period * Math.asin(1 / amplitude) / (2 * Math.PI);
}
return amplitude * Math.pow(2, -10 * v) * Math.sin((v - s) * (2 * Math.PI) / period) + 1;
}
};
module2.exports = Out;
}
),
/***/
99140: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
In: __webpack_require__2(69965),
Out: __webpack_require__2(7744),
InOut: __webpack_require__2(50665)
};
}
),
/***/
24590: (
/***/
(module2) => {
var In = function(v) {
return Math.pow(2, 10 * (v - 1)) - 1e-3;
};
module2.exports = In;
}
),
/***/
87844: (
/***/
(module2) => {
var InOut = function(v) {
if ((v *= 2) < 1) {
return 0.5 * Math.pow(2, 10 * (v - 1));
} else {
return 0.5 * (2 - Math.pow(2, -10 * (v - 1)));
}
};
module2.exports = InOut;
}
),
/***/
89433: (
/***/
(module2) => {
var Out = function(v) {
return 1 - Math.pow(2, -10 * v);
};
module2.exports = Out;
}
),
/***/
48857: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
In: __webpack_require__2(24590),
Out: __webpack_require__2(89433),
InOut: __webpack_require__2(87844)
};
}
),
/***/
48820: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Back: __webpack_require__2(54178),
Bounce: __webpack_require__2(41521),
Circular: __webpack_require__2(79980),
Cubic: __webpack_require__2(85433),
Elastic: __webpack_require__2(99140),
Expo: __webpack_require__2(48857),
Linear: __webpack_require__2(81596),
Quadratic: __webpack_require__2(59133),
Quartic: __webpack_require__2(98516),
Quintic: __webpack_require__2(35248),
Sine: __webpack_require__2(82500),
Stepped: __webpack_require__2(49752)
};
}
),
/***/
7147: (
/***/
(module2) => {
var Linear = function(v) {
return v;
};
module2.exports = Linear;
}
),
/***/
81596: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = __webpack_require__2(7147);
}
),
/***/
34826: (
/***/
(module2) => {
var In = function(v) {
return v * v;
};
module2.exports = In;
}
),
/***/
20544: (
/***/
(module2) => {
var InOut = function(v) {
if ((v *= 2) < 1) {
return 0.5 * v * v;
} else {
return -0.5 * (--v * (v - 2) - 1);
}
};
module2.exports = InOut;
}
),
/***/
92029: (
/***/
(module2) => {
var Out = function(v) {
return v * (2 - v);
};
module2.exports = Out;
}
),
/***/
59133: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
In: __webpack_require__2(34826),
Out: __webpack_require__2(92029),
InOut: __webpack_require__2(20544)
};
}
),
/***/
64413: (
/***/
(module2) => {
var In = function(v) {
return v * v * v * v;
};
module2.exports = In;
}
),
/***/
78137: (
/***/
(module2) => {
var InOut = function(v) {
if ((v *= 2) < 1) {
return 0.5 * v * v * v * v;
} else {
return -0.5 * ((v -= 2) * v * v * v - 2);
}
};
module2.exports = InOut;
}
),
/***/
45840: (
/***/
(module2) => {
var Out = function(v) {
return 1 - --v * v * v * v;
};
module2.exports = Out;
}
),
/***/
98516: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
In: __webpack_require__2(64413),
Out: __webpack_require__2(45840),
InOut: __webpack_require__2(78137)
};
}
),
/***/
87745: (
/***/
(module2) => {
var In = function(v) {
return v * v * v * v * v;
};
module2.exports = In;
}
),
/***/
16509: (
/***/
(module2) => {
var InOut = function(v) {
if ((v *= 2) < 1) {
return 0.5 * v * v * v * v * v;
} else {
return 0.5 * ((v -= 2) * v * v * v * v + 2);
}
};
module2.exports = InOut;
}
),
/***/
17868: (
/***/
(module2) => {
var Out = function(v) {
return --v * v * v * v * v + 1;
};
module2.exports = Out;
}
),
/***/
35248: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
In: __webpack_require__2(87745),
Out: __webpack_require__2(17868),
InOut: __webpack_require__2(16509)
};
}
),
/***/
80461: (
/***/
(module2) => {
var In = function(v) {
if (v === 0) {
return 0;
} else if (v === 1) {
return 1;
} else {
return 1 - Math.cos(v * Math.PI / 2);
}
};
module2.exports = In;
}
),
/***/
34025: (
/***/
(module2) => {
var InOut = function(v) {
if (v === 0) {
return 0;
} else if (v === 1) {
return 1;
} else {
return 0.5 * (1 - Math.cos(Math.PI * v));
}
};
module2.exports = InOut;
}
),
/***/
52768: (
/***/
(module2) => {
var Out = function(v) {
if (v === 0) {
return 0;
} else if (v === 1) {
return 1;
} else {
return Math.sin(v * Math.PI / 2);
}
};
module2.exports = Out;
}
),
/***/
82500: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
In: __webpack_require__2(80461),
Out: __webpack_require__2(52768),
InOut: __webpack_require__2(34025)
};
}
),
/***/
72251: (
/***/
(module2) => {
var Stepped = function(v, steps) {
if (steps === void 0) {
steps = 1;
}
if (v <= 0) {
return 0;
} else if (v >= 1) {
return 1;
} else {
return ((steps * v | 0) + 1) * (1 / steps);
}
};
module2.exports = Stepped;
}
),
/***/
49752: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = __webpack_require__2(72251);
}
),
/***/
75698: (
/***/
(module2) => {
var Ceil = function(value, epsilon) {
if (epsilon === void 0) {
epsilon = 1e-4;
}
return Math.ceil(value - epsilon);
};
module2.exports = Ceil;
}
),
/***/
43855: (
/***/
(module2) => {
var Equal = function(a, b, epsilon) {
if (epsilon === void 0) {
epsilon = 1e-4;
}
return Math.abs(a - b) < epsilon;
};
module2.exports = Equal;
}
),
/***/
25777: (
/***/
(module2) => {
var Floor = function(value, epsilon) {
if (epsilon === void 0) {
epsilon = 1e-4;
}
return Math.floor(value + epsilon);
};
module2.exports = Floor;
}
),
/***/
5470: (
/***/
(module2) => {
var GreaterThan = function(a, b, epsilon) {
if (epsilon === void 0) {
epsilon = 1e-4;
}
return a > b - epsilon;
};
module2.exports = GreaterThan;
}
),
/***/
94977: (
/***/
(module2) => {
var LessThan = function(a, b, epsilon) {
if (epsilon === void 0) {
epsilon = 1e-4;
}
return a < b + epsilon;
};
module2.exports = LessThan;
}
),
/***/
48379: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Ceil: __webpack_require__2(75698),
Equal: __webpack_require__2(43855),
Floor: __webpack_require__2(25777),
GreaterThan: __webpack_require__2(5470),
LessThan: __webpack_require__2(94977)
};
}
),
/***/
75508: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(36383);
var Extend = __webpack_require__2(79291);
var PhaserMath = {
// Collections of functions
Angle: __webpack_require__2(25588),
Distance: __webpack_require__2(50994),
Easing: __webpack_require__2(48820),
Fuzzy: __webpack_require__2(48379),
Interpolation: __webpack_require__2(38289),
Pow2: __webpack_require__2(49001),
Snap: __webpack_require__2(73697),
// Expose the RNG Class
RandomDataGenerator: __webpack_require__2(28453),
// Single functions
Average: __webpack_require__2(53307),
Bernstein: __webpack_require__2(85710),
Between: __webpack_require__2(30976),
CatmullRom: __webpack_require__2(87842),
CeilTo: __webpack_require__2(26302),
Clamp: __webpack_require__2(45319),
DegToRad: __webpack_require__2(39506),
Difference: __webpack_require__2(61241),
Euler: __webpack_require__2(38857),
Factorial: __webpack_require__2(6411),
FloatBetween: __webpack_require__2(99472),
FloorTo: __webpack_require__2(77623),
FromPercent: __webpack_require__2(62945),
GetSpeed: __webpack_require__2(38265),
IsEven: __webpack_require__2(78702),
IsEvenStrict: __webpack_require__2(94883),
Linear: __webpack_require__2(28915),
LinearXY: __webpack_require__2(94908),
MaxAdd: __webpack_require__2(86883),
Median: __webpack_require__2(50040),
MinSub: __webpack_require__2(37204),
Percent: __webpack_require__2(65201),
RadToDeg: __webpack_require__2(43396),
RandomXY: __webpack_require__2(74362),
RandomXYZ: __webpack_require__2(60706),
RandomXYZW: __webpack_require__2(67421),
Rotate: __webpack_require__2(36305),
RotateAround: __webpack_require__2(11520),
RotateAroundDistance: __webpack_require__2(1163),
RotateTo: __webpack_require__2(70336),
RoundAwayFromZero: __webpack_require__2(2284),
RoundTo: __webpack_require__2(41013),
SinCosTableGenerator: __webpack_require__2(16922),
SmootherStep: __webpack_require__2(54261),
SmoothStep: __webpack_require__2(7602),
ToXY: __webpack_require__2(44408),
TransformXY: __webpack_require__2(85955),
Within: __webpack_require__2(60417),
Wrap: __webpack_require__2(15994),
// Vector classes
Vector2: __webpack_require__2(26099),
Vector3: __webpack_require__2(25836),
Vector4: __webpack_require__2(61369),
Matrix3: __webpack_require__2(94434),
Matrix4: __webpack_require__2(37867),
Quaternion: __webpack_require__2(15746),
RotateVec3: __webpack_require__2(72678)
};
PhaserMath = Extend(false, PhaserMath, CONST);
module2.exports = PhaserMath;
}
),
/***/
89318: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Bernstein = __webpack_require__2(85710);
var BezierInterpolation = function(v, k) {
var b = 0;
var n = v.length - 1;
for (var i = 0; i <= n; i++) {
b += Math.pow(1 - k, n - i) * Math.pow(k, i) * v[i] * Bernstein(n, i);
}
return b;
};
module2.exports = BezierInterpolation;
}
),
/***/
77259: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CatmullRom = __webpack_require__2(87842);
var CatmullRomInterpolation = function(v, k) {
var m = v.length - 1;
var f = m * k;
var i = Math.floor(f);
if (v[0] === v[m]) {
if (k < 0) {
i = Math.floor(f = m * (1 + k));
}
return CatmullRom(f - i, v[(i - 1 + m) % m], v[i], v[(i + 1) % m], v[(i + 2) % m]);
} else {
if (k < 0) {
return v[0] - (CatmullRom(-f, v[0], v[0], v[1], v[1]) - v[0]);
}
if (k > 1) {
return v[m] - (CatmullRom(f - m, v[m], v[m], v[m - 1], v[m - 1]) - v[m]);
}
return CatmullRom(f - i, v[i ? i - 1 : 0], v[i], v[m < i + 1 ? m : i + 1], v[m < i + 2 ? m : i + 2]);
}
};
module2.exports = CatmullRomInterpolation;
}
),
/***/
36316: (
/***/
(module2) => {
function P0(t, p) {
var k = 1 - t;
return k * k * k * p;
}
function P1(t, p) {
var k = 1 - t;
return 3 * k * k * t * p;
}
function P2(t, p) {
return 3 * (1 - t) * t * t * p;
}
function P3(t, p) {
return t * t * t * p;
}
var CubicBezierInterpolation = function(t, p0, p1, p2, p3) {
return P0(t, p0) + P1(t, p1) + P2(t, p2) + P3(t, p3);
};
module2.exports = CubicBezierInterpolation;
}
),
/***/
28392: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Linear = __webpack_require__2(28915);
var LinearInterpolation = function(v, k) {
var m = v.length - 1;
var f = m * k;
var i = Math.floor(f);
if (k < 0) {
return Linear(v[0], v[1], f);
} else if (k > 1) {
return Linear(v[m], v[m - 1], m - f);
} else {
return Linear(v[i], v[i + 1 > m ? m : i + 1], f - i);
}
};
module2.exports = LinearInterpolation;
}
),
/***/
32112: (
/***/
(module2) => {
function P0(t, p) {
var k = 1 - t;
return k * k * p;
}
function P1(t, p) {
return 2 * (1 - t) * t * p;
}
function P2(t, p) {
return t * t * p;
}
var QuadraticBezierInterpolation = function(t, p0, p1, p2) {
return P0(t, p0) + P1(t, p1) + P2(t, p2);
};
module2.exports = QuadraticBezierInterpolation;
}
),
/***/
47235: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var SmoothStep = __webpack_require__2(7602);
var SmoothStepInterpolation = function(t, min, max) {
return min + (max - min) * SmoothStep(t, 0, 1);
};
module2.exports = SmoothStepInterpolation;
}
),
/***/
50178: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var SmootherStep = __webpack_require__2(54261);
var SmootherStepInterpolation = function(t, min, max) {
return min + (max - min) * SmootherStep(t, 0, 1);
};
module2.exports = SmootherStepInterpolation;
}
),
/***/
38289: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Bezier: __webpack_require__2(89318),
CatmullRom: __webpack_require__2(77259),
CubicBezier: __webpack_require__2(36316),
Linear: __webpack_require__2(28392),
QuadraticBezier: __webpack_require__2(32112),
SmoothStep: __webpack_require__2(47235),
SmootherStep: __webpack_require__2(50178)
};
}
),
/***/
98439: (
/***/
(module2) => {
var GetPowerOfTwo = function(value) {
var index = Math.log(value) / 0.6931471805599453;
return 1 << Math.ceil(index);
};
module2.exports = GetPowerOfTwo;
}
),
/***/
50030: (
/***/
(module2) => {
var IsSizePowerOfTwo = function(width, height) {
return width > 0 && (width & width - 1) === 0 && height > 0 && (height & height - 1) === 0;
};
module2.exports = IsSizePowerOfTwo;
}
),
/***/
81230: (
/***/
(module2) => {
var IsValuePowerOfTwo = function(value) {
return value > 0 && (value & value - 1) === 0;
};
module2.exports = IsValuePowerOfTwo;
}
),
/***/
49001: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
GetNext: __webpack_require__2(98439),
IsSize: __webpack_require__2(50030),
IsValue: __webpack_require__2(81230)
};
}
),
/***/
28453: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var RandomDataGenerator = new Class({
initialize: function RandomDataGenerator2(seeds) {
if (seeds === void 0) {
seeds = [(Date.now() * Math.random()).toString()];
}
this.c = 1;
this.s0 = 0;
this.s1 = 0;
this.s2 = 0;
this.n = 0;
this.signs = [-1, 1];
if (seeds) {
this.init(seeds);
}
},
/**
* Private random helper.
*
* @method Phaser.Math.RandomDataGenerator#rnd
* @since 3.0.0
* @private
*
* @return {number} A random number.
*/
rnd: function() {
var t = 2091639 * this.s0 + this.c * 23283064365386963e-26;
this.c = t | 0;
this.s0 = this.s1;
this.s1 = this.s2;
this.s2 = t - this.c;
return this.s2;
},
/**
* Internal method that creates a seed hash.
*
* @method Phaser.Math.RandomDataGenerator#hash
* @since 3.0.0
* @private
*
* @param {string} data - The value to hash.
*
* @return {number} The hashed value.
*/
hash: function(data) {
var h;
var n = this.n;
data = data.toString();
for (var i = 0; i < data.length; i++) {
n += data.charCodeAt(i);
h = 0.02519603282416938 * n;
n = h >>> 0;
h -= n;
h *= n;
n = h >>> 0;
h -= n;
n += h * 4294967296;
}
this.n = n;
return (n >>> 0) * 23283064365386963e-26;
},
/**
* Initialize the state of the random data generator.
*
* @method Phaser.Math.RandomDataGenerator#init
* @since 3.0.0
*
* @param {(string|string[])} seeds - The seeds to initialize the random data generator with.
*/
init: function(seeds) {
if (typeof seeds === "string") {
this.state(seeds);
} else {
this.sow(seeds);
}
},
/**
* Reset the seed of the random data generator.
*
* _Note_: the seed array is only processed up to the first `undefined` (or `null`) value, should such be present.
*
* @method Phaser.Math.RandomDataGenerator#sow
* @since 3.0.0
*
* @param {string[]} seeds - The array of seeds: the `toString()` of each value is used.
*/
sow: function(seeds) {
this.n = 4022871197;
this.s0 = this.hash(" ");
this.s1 = this.hash(" ");
this.s2 = this.hash(" ");
this.c = 1;
if (!seeds) {
return;
}
for (var i = 0; i < seeds.length && seeds[i] != null; i++) {
var seed = seeds[i];
this.s0 -= this.hash(seed);
this.s0 += ~~(this.s0 < 0);
this.s1 -= this.hash(seed);
this.s1 += ~~(this.s1 < 0);
this.s2 -= this.hash(seed);
this.s2 += ~~(this.s2 < 0);
}
},
/**
* Returns a random integer between 0 and 2^32.
*
* @method Phaser.Math.RandomDataGenerator#integer
* @since 3.0.0
*
* @return {number} A random integer between 0 and 2^32.
*/
integer: function() {
return this.rnd() * 4294967296;
},
/**
* Returns a random real number between 0 and 1.
*
* @method Phaser.Math.RandomDataGenerator#frac
* @since 3.0.0
*
* @return {number} A random real number between 0 and 1.
*/
frac: function() {
return this.rnd() + (this.rnd() * 2097152 | 0) * 11102230246251565e-32;
},
/**
* Returns a random real number between 0 and 2^32.
*
* @method Phaser.Math.RandomDataGenerator#real
* @since 3.0.0
*
* @return {number} A random real number between 0 and 2^32.
*/
real: function() {
return this.integer() + this.frac();
},
/**
* Returns a random integer between and including min and max.
*
* @method Phaser.Math.RandomDataGenerator#integerInRange
* @since 3.0.0
*
* @param {number} min - The minimum value in the range.
* @param {number} max - The maximum value in the range.
*
* @return {number} A random number between min and max.
*/
integerInRange: function(min, max) {
return Math.floor(this.realInRange(0, max - min + 1) + min);
},
/**
* Returns a random integer between and including min and max.
* This method is an alias for RandomDataGenerator.integerInRange.
*
* @method Phaser.Math.RandomDataGenerator#between
* @since 3.0.0
*
* @param {number} min - The minimum value in the range.
* @param {number} max - The maximum value in the range.
*
* @return {number} A random number between min and max.
*/
between: function(min, max) {
return Math.floor(this.realInRange(0, max - min + 1) + min);
},
/**
* Returns a random real number between min and max.
*
* @method Phaser.Math.RandomDataGenerator#realInRange
* @since 3.0.0
*
* @param {number} min - The minimum value in the range.
* @param {number} max - The maximum value in the range.
*
* @return {number} A random number between min and max.
*/
realInRange: function(min, max) {
return this.frac() * (max - min) + min;
},
/**
* Returns a random real number between -1 and 1.
*
* @method Phaser.Math.RandomDataGenerator#normal
* @since 3.0.0
*
* @return {number} A random real number between -1 and 1.
*/
normal: function() {
return 1 - 2 * this.frac();
},
/**
* Returns a valid RFC4122 version4 ID hex string from https://gist.github.com/1308368
*
* @method Phaser.Math.RandomDataGenerator#uuid
* @since 3.0.0
*
* @return {string} A valid RFC4122 version4 ID hex string
*/
uuid: function() {
var a = "";
var b = "";
for (b = a = ""; a++ < 36; b += ~a % 5 | a * 3 & 4 ? (a ^ 15 ? 8 ^ this.frac() * (a ^ 20 ? 16 : 4) : 4).toString(16) : "-") {
}
return b;
},
/**
* Returns a random element from within the given array.
*
* @method Phaser.Math.RandomDataGenerator#pick
* @since 3.0.0
*
* @generic T
* @genericUse {T[]} - [array]
* @genericUse {T} - [$return]
*
* @param {T[]} array - The array to pick a random element from.
*
* @return {T} A random member of the array.
*/
pick: function(array) {
return array[this.integerInRange(0, array.length - 1)];
},
/**
* Returns a sign to be used with multiplication operator.
*
* @method Phaser.Math.RandomDataGenerator#sign
* @since 3.0.0
*
* @return {number} -1 or +1.
*/
sign: function() {
return this.pick(this.signs);
},
/**
* Returns a random element from within the given array, favoring the earlier entries.
*
* @method Phaser.Math.RandomDataGenerator#weightedPick
* @since 3.0.0
*
* @generic T
* @genericUse {T[]} - [array]
* @genericUse {T} - [$return]
*
* @param {T[]} array - The array to pick a random element from.
*
* @return {T} A random member of the array.
*/
weightedPick: function(array) {
return array[~~(Math.pow(this.frac(), 2) * (array.length - 0.5) + 0.5)];
},
/**
* Returns a random timestamp between min and max, or between the beginning of 2000 and the end of 2020 if min and max aren't specified.
*
* @method Phaser.Math.RandomDataGenerator#timestamp
* @since 3.0.0
*
* @param {number} min - The minimum value in the range.
* @param {number} max - The maximum value in the range.
*
* @return {number} A random timestamp between min and max.
*/
timestamp: function(min, max) {
return this.realInRange(min || 9466848e5, max || 1577862e6);
},
/**
* Returns a random angle between -180 and 180.
*
* @method Phaser.Math.RandomDataGenerator#angle
* @since 3.0.0
*
* @return {number} A random number between -180 and 180.
*/
angle: function() {
return this.integerInRange(-180, 180);
},
/**
* Returns a random rotation in radians, between -3.141 and 3.141
*
* @method Phaser.Math.RandomDataGenerator#rotation
* @since 3.0.0
*
* @return {number} A random number between -3.141 and 3.141
*/
rotation: function() {
return this.realInRange(-3.1415926, 3.1415926);
},
/**
* Gets or Sets the state of the generator. This allows you to retain the values
* that the generator is using between games, i.e. in a game save file.
*
* To seed this generator with a previously saved state you can pass it as the
* `seed` value in your game config, or call this method directly after Phaser has booted.
*
* Call this method with no parameters to return the current state.
*
* If providing a state it should match the same format that this method
* returns, which is a string with a header `!rnd` followed by the `c`,
* `s0`, `s1` and `s2` values respectively, each comma-delimited.
*
* @method Phaser.Math.RandomDataGenerator#state
* @since 3.0.0
*
* @param {string} [state] - Generator state to be set.
*
* @return {string} The current state of the generator.
*/
state: function(state) {
if (typeof state === "string" && state.match(/^!rnd/)) {
state = state.split(",");
this.c = parseFloat(state[1]);
this.s0 = parseFloat(state[2]);
this.s1 = parseFloat(state[3]);
this.s2 = parseFloat(state[4]);
}
return ["!rnd", this.c, this.s0, this.s1, this.s2].join(",");
},
/**
* Shuffles the given array, using the current seed.
*
* @method Phaser.Math.RandomDataGenerator#shuffle
* @since 3.7.0
*
* @generic T
* @genericUse {T[]} - [array,$return]
*
* @param {T[]} [array] - The array to be shuffled.
*
* @return {T[]} The shuffled array.
*/
shuffle: function(array) {
var len = array.length - 1;
for (var i = len; i > 0; i--) {
var randomIndex = Math.floor(this.frac() * (i + 1));
var itemAtIndex = array[randomIndex];
array[randomIndex] = array[i];
array[i] = itemAtIndex;
}
return array;
}
});
module2.exports = RandomDataGenerator;
}
),
/***/
63448: (
/***/
(module2) => {
var SnapCeil = function(value, gap, start, divide) {
if (start === void 0) {
start = 0;
}
if (gap === 0) {
return value;
}
value -= start;
value = gap * Math.ceil(value / gap);
return divide ? (start + value) / gap : start + value;
};
module2.exports = SnapCeil;
}
),
/***/
56583: (
/***/
(module2) => {
var SnapFloor = function(value, gap, start, divide) {
if (start === void 0) {
start = 0;
}
if (gap === 0) {
return value;
}
value -= start;
value = gap * Math.floor(value / gap);
return divide ? (start + value) / gap : start + value;
};
module2.exports = SnapFloor;
}
),
/***/
77720: (
/***/
(module2) => {
var SnapTo = function(value, gap, start, divide) {
if (start === void 0) {
start = 0;
}
if (gap === 0) {
return value;
}
value -= start;
value = gap * Math.round(value / gap);
return divide ? (start + value) / gap : start + value;
};
module2.exports = SnapTo;
}
),
/***/
73697: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Ceil: __webpack_require__2(63448),
Floor: __webpack_require__2(56583),
To: __webpack_require__2(77720)
};
}
),
/***/
85454: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
__webpack_require__2(63595);
var CONST = __webpack_require__2(8054);
var Extend = __webpack_require__2(79291);
var Phaser = {
Actions: __webpack_require__2(61061),
Animations: __webpack_require__2(60421),
BlendModes: __webpack_require__2(10312),
Cache: __webpack_require__2(83388),
Cameras: __webpack_require__2(26638),
Core: __webpack_require__2(42857),
Class: __webpack_require__2(83419),
Create: __webpack_require__2(15822),
Curves: __webpack_require__2(25410),
Data: __webpack_require__2(44965),
Display: __webpack_require__2(27460),
DOM: __webpack_require__2(84902),
Events: __webpack_require__2(93055),
FX: __webpack_require__2(66064),
Game: __webpack_require__2(50127),
GameObjects: __webpack_require__2(77856),
Geom: __webpack_require__2(55738),
Input: __webpack_require__2(14350),
Loader: __webpack_require__2(57777),
Math: __webpack_require__2(75508),
Physics: __webpack_require__2(44563),
Plugins: __webpack_require__2(18922),
Renderer: __webpack_require__2(36909),
Scale: __webpack_require__2(93364),
ScaleModes: __webpack_require__2(29795),
Scene: __webpack_require__2(97482),
Scenes: __webpack_require__2(62194),
Structs: __webpack_require__2(41392),
Textures: __webpack_require__2(27458),
Tilemaps: __webpack_require__2(62501),
Time: __webpack_require__2(90291),
Tweens: __webpack_require__2(43066),
Utils: __webpack_require__2(91799)
};
if (true) {
Phaser.Sound = __webpack_require__2(23717);
}
if (false) {
}
if (false) {
}
Phaser = Extend(false, Phaser, CONST);
module2.exports = Phaser;
__webpack_require__2.g.Phaser = Phaser;
}
),
/***/
71289: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(92209);
var Image2 = __webpack_require__2(88571);
var ArcadeImage = new Class({
Extends: Image2,
Mixins: [
Components.Acceleration,
Components.Angular,
Components.Bounce,
Components.Collision,
Components.Debug,
Components.Drag,
Components.Enable,
Components.Friction,
Components.Gravity,
Components.Immovable,
Components.Mass,
Components.Pushable,
Components.Size,
Components.Velocity
],
initialize: function ArcadeImage2(scene, x, y, texture, frame) {
Image2.call(this, scene, x, y, texture, frame);
this.body = null;
}
});
module2.exports = ArcadeImage;
}
),
/***/
86689: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var DegToRad = __webpack_require__2(39506);
var DistanceBetween = __webpack_require__2(20339);
var DistanceSquared = __webpack_require__2(89774);
var Factory = __webpack_require__2(66022);
var GetFastValue = __webpack_require__2(95540);
var Merge = __webpack_require__2(46975);
var OverlapCirc = __webpack_require__2(72441);
var OverlapRect = __webpack_require__2(47956);
var PluginCache = __webpack_require__2(37277);
var SceneEvents = __webpack_require__2(44594);
var Vector2 = __webpack_require__2(26099);
var World = __webpack_require__2(82248);
var ArcadePhysics = new Class({
initialize: function ArcadePhysics2(scene) {
this.scene = scene;
this.systems = scene.sys;
this.config = this.getConfig();
this.world;
this.add;
this._category = 1;
scene.sys.events.once(SceneEvents.BOOT, this.boot, this);
scene.sys.events.on(SceneEvents.START, this.start, this);
},
/**
* This method is called automatically, only once, when the Scene is first created.
* Do not invoke it directly.
*
* @method Phaser.Physics.Arcade.ArcadePhysics#boot
* @private
* @since 3.5.1
*/
boot: function() {
this.world = new World(this.scene, this.config);
this.add = new Factory(this.world);
this.systems.events.once(SceneEvents.DESTROY, this.destroy, this);
},
/**
* This method is called automatically by the Scene when it is starting up.
* It is responsible for creating local systems, properties and listening for Scene events.
* Do not invoke it directly.
*
* @method Phaser.Physics.Arcade.ArcadePhysics#start
* @private
* @since 3.5.0
*/
start: function() {
if (!this.world) {
this.world = new World(this.scene, this.config);
this.add = new Factory(this.world);
}
var eventEmitter = this.systems.events;
if (!GetFastValue(this.config, "customUpdate", false)) {
eventEmitter.on(SceneEvents.UPDATE, this.world.update, this.world);
}
eventEmitter.on(SceneEvents.POST_UPDATE, this.world.postUpdate, this.world);
eventEmitter.once(SceneEvents.SHUTDOWN, this.shutdown, this);
},
/**
* Causes `World.update` to be automatically called each time the Scene
* emits and `UPDATE` event. This is the default setting, so only needs
* calling if you have specifically disabled it.
*
* @method Phaser.Physics.Arcade.ArcadePhysics#enableUpdate
* @since 3.50.0
*/
enableUpdate: function() {
this.systems.events.on(SceneEvents.UPDATE, this.world.update, this.world);
},
/**
* Causes `World.update` to **not** be automatically called each time the Scene
* emits and `UPDATE` event.
*
* If you wish to run the World update at your own rate, or from your own
* component, then you should call this method to disable the built-in link,
* and then call `World.update(delta, time)` accordingly.
*
* Note that `World.postUpdate` is always automatically called when the Scene
* emits a `POST_UPDATE` event, regardless of this setting.
*
* @method Phaser.Physics.Arcade.ArcadePhysics#disableUpdate
* @since 3.50.0
*/
disableUpdate: function() {
this.systems.events.off(SceneEvents.UPDATE, this.world.update, this.world);
},
/**
* Creates the physics configuration for the current Scene.
*
* @method Phaser.Physics.Arcade.ArcadePhysics#getConfig
* @since 3.0.0
*
* @return {Phaser.Types.Physics.Arcade.ArcadeWorldConfig} The physics configuration.
*/
getConfig: function() {
var gameConfig = this.systems.game.config.physics;
var sceneConfig = this.systems.settings.physics;
var config = Merge(
GetFastValue(sceneConfig, "arcade", {}),
GetFastValue(gameConfig, "arcade", {})
);
return config;
},
/**
* Returns the next available collision category.
*
* You can have a maximum of 32 categories.
*
* By default all bodies collide with all other bodies.
*
* Use the `Body.setCollisionCategory()` and
* `Body.setCollidesWith()` methods to change this.
*
* @method Phaser.Physics.Arcade.ArcadePhysics#nextCategory
* @since 3.70.0
*
* @return {number} The next collision category.
*/
nextCategory: function() {
this._category = this._category << 1;
return this._category;
},
/**
* Tests if Game Objects overlap. See {@link Phaser.Physics.Arcade.World#overlap}
*
* @method Phaser.Physics.Arcade.ArcadePhysics#overlap
* @since 3.0.0
*
* @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object or array of objects to check.
* @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} [object2] - The second object or array of objects to check, or `undefined`.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [overlapCallback] - An optional callback function that is called if the objects overlap.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they overlap. If this is set then `collideCallback` will only be called if this callback returns `true`.
* @param {*} [callbackContext] - The context in which to run the callbacks.
*
* @return {boolean} True if at least one Game Object overlaps another.
*
* @see Phaser.Physics.Arcade.World#overlap
*/
overlap: function(object1, object2, overlapCallback, processCallback, callbackContext) {
if (overlapCallback === void 0) {
overlapCallback = null;
}
if (processCallback === void 0) {
processCallback = null;
}
if (callbackContext === void 0) {
callbackContext = overlapCallback;
}
return this.world.collideObjects(object1, object2, overlapCallback, processCallback, callbackContext, true);
},
/**
* Performs a collision check and separation between the two physics enabled objects given, which can be single
* Game Objects, arrays of Game Objects, Physics Groups, arrays of Physics Groups or normal Groups.
*
* If you don't require separation then use {@link #overlap} instead.
*
* If two Groups or arrays are passed, each member of one will be tested against each member of the other.
*
* If **only** one Group is passed (as `object1`), each member of the Group will be collided against the other members.
*
* If **only** one Array is passed, the array is iterated and every element in it is tested against the others.
*
* Two callbacks can be provided. The `collideCallback` is invoked if a collision occurs and the two colliding
* objects are passed to it.
*
* Arcade Physics uses the Projection Method of collision resolution and separation. While it's fast and suitable
* for 'arcade' style games it lacks stability when multiple objects are in close proximity or resting upon each other.
* The separation that stops two objects penetrating may create a new penetration against a different object. If you
* require a high level of stability please consider using an alternative physics system, such as Matter.js.
*
* @method Phaser.Physics.Arcade.ArcadePhysics#collide
* @since 3.0.0
*
* @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object or array of objects to check.
* @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} [object2] - The second object or array of objects to check, or `undefined`.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`.
* @param {*} [callbackContext] - The context in which to run the callbacks.
*
* @return {boolean} True if any overlapping Game Objects were separated, otherwise false.
*
* @see Phaser.Physics.Arcade.World#collide
*/
collide: function(object1, object2, collideCallback, processCallback, callbackContext) {
if (collideCallback === void 0) {
collideCallback = null;
}
if (processCallback === void 0) {
processCallback = null;
}
if (callbackContext === void 0) {
callbackContext = collideCallback;
}
return this.world.collideObjects(object1, object2, collideCallback, processCallback, callbackContext, false);
},
/**
* This advanced method is specifically for testing for collision between a single Sprite and an array of Tile objects.
*
* You should generally use the `collide` method instead, with a Sprite vs. a Tilemap Layer, as that will perform
* tile filtering and culling for you, as well as handle the interesting face collision automatically.
*
* This method is offered for those who would like to check for collision with specific Tiles in a layer, without
* having to set any collision attributes on the tiles in question. This allows you to perform quick dynamic collisions
* on small sets of Tiles. As such, no culling or checks are made to the array of Tiles given to this method,
* you should filter them before passing them to this method.
*
* Important: Use of this method skips the `interesting faces` system that Tilemap Layers use. This means if you have
* say a row or column of tiles, and you jump into, or walk over them, it's possible to get stuck on the edges of the
* tiles as the interesting face calculations are skipped. However, for quick-fire small collision set tests on
* dynamic maps, this method can prove very useful.
*
* @method Phaser.Physics.Arcade.ArcadePhysics#collideTiles
* @fires Phaser.Physics.Arcade.Events#TILE_COLLIDE
* @since 3.17.0
*
* @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision.
* @param {Phaser.Tilemaps.Tile[]} tiles - An array of Tiles to check for collision against.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`.
* @param {any} [callbackContext] - The context in which to run the callbacks.
*
* @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated.
*/
collideTiles: function(sprite, tiles, collideCallback, processCallback, callbackContext) {
return this.world.collideTiles(sprite, tiles, collideCallback, processCallback, callbackContext);
},
/**
* This advanced method is specifically for testing for overlaps between a single Sprite and an array of Tile objects.
*
* You should generally use the `overlap` method instead, with a Sprite vs. a Tilemap Layer, as that will perform
* tile filtering and culling for you, as well as handle the interesting face collision automatically.
*
* This method is offered for those who would like to check for overlaps with specific Tiles in a layer, without
* having to set any collision attributes on the tiles in question. This allows you to perform quick dynamic overlap
* tests on small sets of Tiles. As such, no culling or checks are made to the array of Tiles given to this method,
* you should filter them before passing them to this method.
*
* @method Phaser.Physics.Arcade.ArcadePhysics#overlapTiles
* @fires Phaser.Physics.Arcade.Events#TILE_OVERLAP
* @since 3.17.0
*
* @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision.
* @param {Phaser.Tilemaps.Tile[]} tiles - An array of Tiles to check for collision against.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects overlap.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`.
* @param {any} [callbackContext] - The context in which to run the callbacks.
*
* @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated.
*/
overlapTiles: function(sprite, tiles, collideCallback, processCallback, callbackContext) {
return this.world.overlapTiles(sprite, tiles, collideCallback, processCallback, callbackContext);
},
/**
* Pauses the simulation.
*
* @method Phaser.Physics.Arcade.ArcadePhysics#pause
* @since 3.0.0
*
* @return {Phaser.Physics.Arcade.World} The simulation.
*/
pause: function() {
return this.world.pause();
},
/**
* Resumes the simulation (if paused).
*
* @method Phaser.Physics.Arcade.ArcadePhysics#resume
* @since 3.0.0
*
* @return {Phaser.Physics.Arcade.World} The simulation.
*/
resume: function() {
return this.world.resume();
},
/**
* Sets the acceleration.x/y property on the game object so it will move towards the x/y coordinates at the given rate (in pixels per second squared)
*
* You must give a maximum speed value, beyond which the game object won't go any faster.
*
* Note: The game object does not continuously track the target. If the target changes location during transit the game object will not modify its course.
* Note: The game object doesn't stop moving once it reaches the destination coordinates.
*
* @method Phaser.Physics.Arcade.ArcadePhysics#accelerateTo
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - Any Game Object with an Arcade Physics body.
* @param {number} x - The x coordinate to accelerate towards.
* @param {number} y - The y coordinate to accelerate towards.
* @param {number} [speed=60] - The acceleration (change in speed) in pixels per second squared.
* @param {number} [xSpeedMax=500] - The maximum x velocity the game object can reach.
* @param {number} [ySpeedMax=500] - The maximum y velocity the game object can reach.
*
* @return {number} The angle (in radians) that the object should be visually set to in order to match its new velocity.
*/
accelerateTo: function(gameObject, x, y, speed, xSpeedMax, ySpeedMax) {
if (speed === void 0) {
speed = 60;
}
var angle = Math.atan2(y - gameObject.y, x - gameObject.x);
gameObject.body.acceleration.setToPolar(angle, speed);
if (xSpeedMax !== void 0 && ySpeedMax !== void 0) {
gameObject.body.maxVelocity.set(xSpeedMax, ySpeedMax);
}
return angle;
},
/**
* Sets the acceleration.x/y property on the game object so it will move towards the x/y coordinates at the given rate (in pixels per second squared)
*
* You must give a maximum speed value, beyond which the game object won't go any faster.
*
* Note: The game object does not continuously track the target. If the target changes location during transit the game object will not modify its course.
* Note: The game object doesn't stop moving once it reaches the destination coordinates.
*
* @method Phaser.Physics.Arcade.ArcadePhysics#accelerateToObject
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - Any Game Object with an Arcade Physics body.
* @param {Phaser.GameObjects.GameObject} destination - The Game Object to move towards. Can be any object but must have visible x/y properties.
* @param {number} [speed=60] - The acceleration (change in speed) in pixels per second squared.
* @param {number} [xSpeedMax=500] - The maximum x velocity the game object can reach.
* @param {number} [ySpeedMax=500] - The maximum y velocity the game object can reach.
*
* @return {number} The angle (in radians) that the object should be visually set to in order to match its new velocity.
*/
accelerateToObject: function(gameObject, destination, speed, xSpeedMax, ySpeedMax) {
return this.accelerateTo(gameObject, destination.x, destination.y, speed, xSpeedMax, ySpeedMax);
},
/**
* Finds the Body or Game Object closest to a source point or object.
*
* If a `targets` argument is passed, this method finds the closest of those.
* The targets can be Arcade Physics Game Objects, Dynamic Bodies, or Static Bodies.
*
* If no `targets` argument is passed, this method finds the closest Dynamic Body.
*
* If two or more targets are the exact same distance from the source point, only the first target
* is returned.
*
* @method Phaser.Physics.Arcade.ArcadePhysics#closest
* @since 3.0.0
*
* @generic {Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody|Phaser.GameObjects.GameObject} Target
* @param {Phaser.Types.Math.Vector2Like} source - Any object with public `x` and `y` properties, such as a Game Object or Geometry object.
* @param {Target[]} [targets] - The targets.
*
* @return {Target|null} The target closest to the given source point.
*/
closest: function(source, targets) {
if (!targets) {
targets = this.world.bodies.entries;
}
var min = Number.MAX_VALUE;
var closest = null;
var x = source.x;
var y = source.y;
var len = targets.length;
for (var i = 0; i < len; i++) {
var target = targets[i];
var body = target.body || target;
if (source === target || source === body || source === body.gameObject || source === body.center) {
continue;
}
var distance = DistanceSquared(x, y, body.center.x, body.center.y);
if (distance < min) {
closest = target;
min = distance;
}
}
return closest;
},
/**
* Finds the Body or Game Object farthest from a source point or object.
*
* If a `targets` argument is passed, this method finds the farthest of those.
* The targets can be Arcade Physics Game Objects, Dynamic Bodies, or Static Bodies.
*
* If no `targets` argument is passed, this method finds the farthest Dynamic Body.
*
* If two or more targets are the exact same distance from the source point, only the first target
* is returned.
*
* @method Phaser.Physics.Arcade.ArcadePhysics#furthest
* @since 3.0.0
*
* @param {any} source - Any object with public `x` and `y` properties, such as a Game Object or Geometry object.
* @param {(Phaser.Physics.Arcade.Body[]|Phaser.Physics.Arcade.StaticBody[]|Phaser.GameObjects.GameObject[])} [targets] - The targets.
*
* @return {?(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody|Phaser.GameObjects.GameObject)} The target farthest from the given source point.
*/
furthest: function(source, targets) {
if (!targets) {
targets = this.world.bodies.entries;
}
var max = -1;
var farthest = null;
var x = source.x;
var y = source.y;
var len = targets.length;
for (var i = 0; i < len; i++) {
var target = targets[i];
var body = target.body || target;
if (source === target || source === body || source === body.gameObject || source === body.center) {
continue;
}
var distance = DistanceSquared(x, y, body.center.x, body.center.y);
if (distance > max) {
farthest = target;
max = distance;
}
}
return farthest;
},
/**
* Move the given display object towards the x/y coordinates at a steady velocity.
* If you specify a maxTime then it will adjust the speed (over-writing what you set) so it arrives at the destination in that number of seconds.
* Timings are approximate due to the way browser timers work. Allow for a variance of +- 50ms.
* Note: The display object does not continuously track the target. If the target changes location during transit the display object will not modify its course.
* Note: The display object doesn't stop moving once it reaches the destination coordinates.
* Note: Doesn't take into account acceleration, maxVelocity or drag (if you've set drag or acceleration too high this object may not move at all)
*
* @method Phaser.Physics.Arcade.ArcadePhysics#moveTo
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - Any Game Object with an Arcade Physics body.
* @param {number} x - The x coordinate to move towards.
* @param {number} y - The y coordinate to move towards.
* @param {number} [speed=60] - The speed it will move, in pixels per second (default is 60 pixels/sec)
* @param {number} [maxTime=0] - Time given in milliseconds (1000 = 1 sec). If set the speed is adjusted so the object will arrive at destination in the given number of ms.
*
* @return {number} The angle (in radians) that the object should be visually set to in order to match its new velocity.
*/
moveTo: function(gameObject, x, y, speed, maxTime) {
if (speed === void 0) {
speed = 60;
}
if (maxTime === void 0) {
maxTime = 0;
}
var angle = Math.atan2(y - gameObject.y, x - gameObject.x);
if (maxTime > 0) {
speed = DistanceBetween(gameObject.x, gameObject.y, x, y) / (maxTime / 1e3);
}
gameObject.body.velocity.setToPolar(angle, speed);
return angle;
},
/**
* Move the given display object towards the destination object at a steady velocity.
* If you specify a maxTime then it will adjust the speed (overwriting what you set) so it arrives at the destination in that number of seconds.
* Timings are approximate due to the way browser timers work. Allow for a variance of +- 50ms.
* Note: The display object does not continuously track the target. If the target changes location during transit the display object will not modify its course.
* Note: The display object doesn't stop moving once it reaches the destination coordinates.
* Note: Doesn't take into account acceleration, maxVelocity or drag (if you've set drag or acceleration too high this object may not move at all)
*
* @method Phaser.Physics.Arcade.ArcadePhysics#moveToObject
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - Any Game Object with an Arcade Physics body.
* @param {object} destination - Any object with public `x` and `y` properties, such as a Game Object or Geometry object.
* @param {number} [speed=60] - The speed it will move, in pixels per second (default is 60 pixels/sec)
* @param {number} [maxTime=0] - Time given in milliseconds (1000 = 1 sec). If set the speed is adjusted so the object will arrive at destination in the given number of ms.
*
* @return {number} The angle (in radians) that the object should be visually set to in order to match its new velocity.
*/
moveToObject: function(gameObject, destination, speed, maxTime) {
return this.moveTo(gameObject, destination.x, destination.y, speed, maxTime);
},
/**
* Given the angle (in degrees) and speed calculate the velocity and return it as a vector, or set it to the given vector object.
* One way to use this is: velocityFromAngle(angle, 200, sprite.body.velocity) which will set the values directly to the sprite's velocity and not create a new vector object.
*
* @method Phaser.Physics.Arcade.ArcadePhysics#velocityFromAngle
* @since 3.0.0
*
* @param {number} angle - The angle in degrees calculated in clockwise positive direction (down = 90 degrees positive, right = 0 degrees positive, up = 90 degrees negative)
* @param {number} [speed=60] - The speed it will move, in pixels per second squared.
* @param {Phaser.Math.Vector2} [vec2] - The Vector2 in which the x and y properties will be set to the calculated velocity.
*
* @return {Phaser.Math.Vector2} The Vector2 that stores the velocity.
*/
velocityFromAngle: function(angle, speed, vec2) {
if (speed === void 0) {
speed = 60;
}
if (vec2 === void 0) {
vec2 = new Vector2();
}
return vec2.setToPolar(DegToRad(angle), speed);
},
/**
* Given the rotation (in radians) and speed calculate the velocity and return it as a vector, or set it to the given vector object.
* One way to use this is: velocityFromRotation(rotation, 200, sprite.body.velocity) which will set the values directly to the sprite's velocity and not create a new vector object.
*
* @method Phaser.Physics.Arcade.ArcadePhysics#velocityFromRotation
* @since 3.0.0
*
* @param {number} rotation - The angle in radians.
* @param {number} [speed=60] - The speed it will move, in pixels per second squared
* @param {Phaser.Math.Vector2} [vec2] - The Vector2 in which the x and y properties will be set to the calculated velocity.
*
* @return {Phaser.Math.Vector2} The Vector2 that stores the velocity.
*/
velocityFromRotation: function(rotation, speed, vec2) {
if (speed === void 0) {
speed = 60;
}
if (vec2 === void 0) {
vec2 = new Vector2();
}
return vec2.setToPolar(rotation, speed);
},
/**
* This method will search the given rectangular area and return an array of all physics bodies that
* overlap with it. It can return either Dynamic, Static bodies or a mixture of both.
*
* A body only has to intersect with the search area to be considered, it doesn't have to be fully
* contained within it.
*
* If Arcade Physics is set to use the RTree (which it is by default) then the search for is extremely fast,
* otherwise the search is O(N) for Dynamic Bodies.
*
* @method Phaser.Physics.Arcade.ArcadePhysics#overlapRect
* @since 3.17.0
*
* @param {number} x - The top-left x coordinate of the area to search within.
* @param {number} y - The top-left y coordinate of the area to search within.
* @param {number} width - The width of the area to search within.
* @param {number} height - The height of the area to search within.
* @param {boolean} [includeDynamic=true] - Should the search include Dynamic Bodies?
* @param {boolean} [includeStatic=false] - Should the search include Static Bodies?
*
* @return {(Phaser.Physics.Arcade.Body[]|Phaser.Physics.Arcade.StaticBody[])} An array of bodies that overlap with the given area.
*/
overlapRect: function(x, y, width, height, includeDynamic, includeStatic) {
return OverlapRect(this.world, x, y, width, height, includeDynamic, includeStatic);
},
/**
* This method will search the given circular area and return an array of all physics bodies that
* overlap with it. It can return either Dynamic, Static bodies or a mixture of both.
*
* A body only has to intersect with the search area to be considered, it doesn't have to be fully
* contained within it.
*
* If Arcade Physics is set to use the RTree (which it is by default) then the search is rather fast,
* otherwise the search is O(N) for Dynamic Bodies.
*
* @method Phaser.Physics.Arcade.ArcadePhysics#overlapCirc
* @since 3.21.0
*
* @param {number} x - The x coordinate of the center of the area to search within.
* @param {number} y - The y coordinate of the center of the area to search within.
* @param {number} radius - The radius of the area to search within.
* @param {boolean} [includeDynamic=true] - Should the search include Dynamic Bodies?
* @param {boolean} [includeStatic=false] - Should the search include Static Bodies?
*
* @return {(Phaser.Physics.Arcade.Body[]|Phaser.Physics.Arcade.StaticBody[])} An array of bodies that overlap with the given area.
*/
overlapCirc: function(x, y, radius, includeDynamic, includeStatic) {
return OverlapCirc(this.world, x, y, radius, includeDynamic, includeStatic);
},
/**
* The Scene that owns this plugin is shutting down.
* We need to kill and reset all internal properties as well as stop listening to Scene events.
*
* @method Phaser.Physics.Arcade.ArcadePhysics#shutdown
* @since 3.0.0
*/
shutdown: function() {
if (!this.world) {
return;
}
var eventEmitter = this.systems.events;
eventEmitter.off(SceneEvents.UPDATE, this.world.update, this.world);
eventEmitter.off(SceneEvents.POST_UPDATE, this.world.postUpdate, this.world);
eventEmitter.off(SceneEvents.SHUTDOWN, this.shutdown, this);
this.add.destroy();
this.world.destroy();
this.add = null;
this.world = null;
this._category = 1;
},
/**
* The Scene that owns this plugin is being destroyed.
* We need to shutdown and then kill off all external references.
*
* @method Phaser.Physics.Arcade.ArcadePhysics#destroy
* @since 3.0.0
*/
destroy: function() {
this.shutdown();
this.scene.sys.events.off(SceneEvents.START, this.start, this);
this.scene = null;
this.systems = null;
}
});
PluginCache.register("ArcadePhysics", ArcadePhysics, "arcadePhysics");
module2.exports = ArcadePhysics;
}
),
/***/
13759: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(92209);
var Sprite = __webpack_require__2(68287);
var ArcadeSprite = new Class({
Extends: Sprite,
Mixins: [
Components.Acceleration,
Components.Angular,
Components.Bounce,
Components.Collision,
Components.Debug,
Components.Drag,
Components.Enable,
Components.Friction,
Components.Gravity,
Components.Immovable,
Components.Mass,
Components.Pushable,
Components.Size,
Components.Velocity
],
initialize: function ArcadeSprite2(scene, x, y, texture, frame) {
Sprite.call(this, scene, x, y, texture, frame);
this.body = null;
}
});
module2.exports = ArcadeSprite;
}
),
/***/
37742: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CollisionComponent = __webpack_require__2(78389);
var CONST = __webpack_require__2(37747);
var Events = __webpack_require__2(63012);
var RadToDeg = __webpack_require__2(43396);
var Rectangle = __webpack_require__2(87841);
var RectangleContains = __webpack_require__2(37303);
var SetCollisionObject = __webpack_require__2(95829);
var Vector2 = __webpack_require__2(26099);
var Body = new Class({
Mixins: [
CollisionComponent
],
initialize: function Body2(world, gameObject) {
var width = 64;
var height = 64;
var dummyGameObject = {
x: 0,
y: 0,
angle: 0,
rotation: 0,
scaleX: 1,
scaleY: 1,
displayOriginX: 0,
displayOriginY: 0
};
var hasGameObject = gameObject !== void 0;
if (hasGameObject && gameObject.displayWidth) {
width = gameObject.displayWidth;
height = gameObject.displayHeight;
}
if (!hasGameObject) {
gameObject = dummyGameObject;
}
this.world = world;
this.gameObject = hasGameObject ? gameObject : void 0;
this.isBody = true;
this.transform = {
x: gameObject.x,
y: gameObject.y,
rotation: gameObject.angle,
scaleX: gameObject.scaleX,
scaleY: gameObject.scaleY,
displayOriginX: gameObject.displayOriginX,
displayOriginY: gameObject.displayOriginY
};
this.debugShowBody = world.defaults.debugShowBody;
this.debugShowVelocity = world.defaults.debugShowVelocity;
this.debugBodyColor = world.defaults.bodyDebugColor;
this.enable = true;
this.isCircle = false;
this.radius = 0;
this.offset = new Vector2();
this.position = new Vector2(
gameObject.x - gameObject.scaleX * gameObject.displayOriginX,
gameObject.y - gameObject.scaleY * gameObject.displayOriginY
);
this.prev = this.position.clone();
this.prevFrame = this.position.clone();
this.allowRotation = true;
this.rotation = gameObject.angle;
this.preRotation = gameObject.angle;
this.width = width;
this.height = height;
this.sourceWidth = width;
this.sourceHeight = height;
if (gameObject.frame) {
this.sourceWidth = gameObject.frame.realWidth;
this.sourceHeight = gameObject.frame.realHeight;
}
this.halfWidth = Math.abs(width / 2);
this.halfHeight = Math.abs(height / 2);
this.center = new Vector2(this.position.x + this.halfWidth, this.position.y + this.halfHeight);
this.velocity = new Vector2();
this.newVelocity = new Vector2();
this.deltaMax = new Vector2();
this.acceleration = new Vector2();
this.allowDrag = true;
this.drag = new Vector2();
this.allowGravity = true;
this.gravity = new Vector2();
this.bounce = new Vector2();
this.worldBounce = null;
this.customBoundsRectangle = world.bounds;
this.onWorldBounds = false;
this.onCollide = false;
this.onOverlap = false;
this.maxVelocity = new Vector2(1e4, 1e4);
this.maxSpeed = -1;
this.friction = new Vector2(1, 0);
this.useDamping = false;
this.angularVelocity = 0;
this.angularAcceleration = 0;
this.angularDrag = 0;
this.maxAngular = 1e3;
this.mass = 1;
this.angle = 0;
this.speed = 0;
this.facing = CONST.FACING_NONE;
this.immovable = false;
this.pushable = true;
this.slideFactor = new Vector2(1, 1);
this.moves = true;
this.customSeparateX = false;
this.customSeparateY = false;
this.overlapX = 0;
this.overlapY = 0;
this.overlapR = 0;
this.embedded = false;
this.collideWorldBounds = false;
this.checkCollision = SetCollisionObject(false);
this.touching = SetCollisionObject(true);
this.wasTouching = SetCollisionObject(true);
this.blocked = SetCollisionObject(true);
this.syncBounds = false;
this.physicsType = CONST.DYNAMIC_BODY;
this.collisionCategory = 1;
this.collisionMask = 1;
this._sx = gameObject.scaleX;
this._sy = gameObject.scaleY;
this._dx = 0;
this._dy = 0;
this._tx = 0;
this._ty = 0;
this._bounds = new Rectangle();
this.directControl = false;
this.autoFrame = this.position.clone();
},
/**
* Updates the Body's `transform`, `width`, `height`, and `center` from its Game Object.
* The Body's `position` isn't changed.
*
* @method Phaser.Physics.Arcade.Body#updateBounds
* @since 3.0.0
*/
updateBounds: function() {
var sprite = this.gameObject;
var transform = this.transform;
if (sprite.parentContainer) {
var matrix = sprite.getWorldTransformMatrix(this.world._tempMatrix, this.world._tempMatrix2);
transform.x = matrix.tx;
transform.y = matrix.ty;
transform.rotation = RadToDeg(matrix.rotation);
transform.scaleX = matrix.scaleX;
transform.scaleY = matrix.scaleY;
transform.displayOriginX = sprite.displayOriginX;
transform.displayOriginY = sprite.displayOriginY;
} else {
transform.x = sprite.x;
transform.y = sprite.y;
transform.rotation = sprite.angle;
transform.scaleX = sprite.scaleX;
transform.scaleY = sprite.scaleY;
transform.displayOriginX = sprite.displayOriginX;
transform.displayOriginY = sprite.displayOriginY;
}
var recalc = false;
if (this.syncBounds) {
var b = sprite.getBounds(this._bounds);
this.width = b.width;
this.height = b.height;
recalc = true;
} else {
var asx = Math.abs(transform.scaleX);
var asy = Math.abs(transform.scaleY);
if (this._sx !== asx || this._sy !== asy) {
this.width = this.sourceWidth * asx;
this.height = this.sourceHeight * asy;
this._sx = asx;
this._sy = asy;
recalc = true;
}
}
if (recalc) {
this.halfWidth = Math.floor(this.width / 2);
this.halfHeight = Math.floor(this.height / 2);
this.updateCenter();
}
},
/**
* Updates the Body's `center` from its `position`, `width`, and `height`.
*
* @method Phaser.Physics.Arcade.Body#updateCenter
* @since 3.0.0
*/
updateCenter: function() {
this.center.set(this.position.x + this.halfWidth, this.position.y + this.halfHeight);
},
/**
* Updates the Body's `position`, `width`, `height`, and `center` from its Game Object and `offset`.
*
* You don't need to call this for Dynamic Bodies, as it happens automatically during the physics step.
* But you could use it if you have modified the Body offset or Game Object transform and need to immediately
* read the Body's new `position` or `center`.
*
* To resynchronize the Body with its Game Object, use `reset()` instead.
*
* @method Phaser.Physics.Arcade.Body#updateFromGameObject
* @since 3.24.0
*/
updateFromGameObject: function() {
this.updateBounds();
var transform = this.transform;
this.position.x = transform.x + transform.scaleX * (this.offset.x - transform.displayOriginX);
this.position.y = transform.y + transform.scaleY * (this.offset.y - transform.displayOriginY);
this.updateCenter();
},
/**
* Prepares the Body for a physics step by resetting the `wasTouching`, `touching` and `blocked` states.
*
* This method is only called if the physics world is going to run a step this frame.
*
* @method Phaser.Physics.Arcade.Body#resetFlags
* @since 3.18.0
*
* @param {boolean} [clear=false] - Set the `wasTouching` values to their defaults.
*/
resetFlags: function(clear) {
if (clear === void 0) {
clear = false;
}
var wasTouching = this.wasTouching;
var touching = this.touching;
var blocked = this.blocked;
if (clear) {
SetCollisionObject(true, wasTouching);
} else {
wasTouching.none = touching.none;
wasTouching.up = touching.up;
wasTouching.down = touching.down;
wasTouching.left = touching.left;
wasTouching.right = touching.right;
}
SetCollisionObject(true, touching);
SetCollisionObject(true, blocked);
this.overlapR = 0;
this.overlapX = 0;
this.overlapY = 0;
this.embedded = false;
},
/**
* Syncs the position body position with the parent Game Object.
*
* This method is called every game frame, regardless if the world steps or not.
*
* @method Phaser.Physics.Arcade.Body#preUpdate
* @since 3.17.0
*
* @param {boolean} willStep - Will this Body run an update as well?
* @param {number} delta - The delta time, in seconds, elapsed since the last frame.
*/
preUpdate: function(willStep, delta) {
if (willStep) {
this.resetFlags();
}
if (this.gameObject) {
this.updateFromGameObject();
}
this.rotation = this.transform.rotation;
this.preRotation = this.rotation;
if (this.moves) {
var pos = this.position;
this.prev.x = pos.x;
this.prev.y = pos.y;
this.prevFrame.x = pos.x;
this.prevFrame.y = pos.y;
}
if (willStep) {
this.update(delta);
}
},
/**
* Performs a single physics step and updates the body velocity, angle, speed and other properties.
*
* This method can be called multiple times per game frame, depending on the physics step rate.
*
* The results are synced back to the Game Object in `postUpdate`.
*
* @method Phaser.Physics.Arcade.Body#update
* @fires Phaser.Physics.Arcade.Events#WORLD_BOUNDS
* @since 3.0.0
*
* @param {number} delta - The delta time, in seconds, elapsed since the last frame.
*/
update: function(delta) {
var prev = this.prev;
var pos = this.position;
var vel = this.velocity;
prev.set(pos.x, pos.y);
if (!this.moves) {
this._dx = pos.x - prev.x;
this._dy = pos.y - prev.y;
return;
}
if (this.directControl) {
var autoFrame = this.autoFrame;
vel.set(
(pos.x - autoFrame.x) / delta,
(pos.y - autoFrame.y) / delta
);
this.world.updateMotion(this, delta);
this._dx = pos.x - autoFrame.x;
this._dy = pos.y - autoFrame.y;
} else {
this.world.updateMotion(this, delta);
this.newVelocity.set(vel.x * delta, vel.y * delta);
pos.add(this.newVelocity);
this._dx = pos.x - prev.x;
this._dy = pos.y - prev.y;
}
var vx = vel.x;
var vy = vel.y;
this.updateCenter();
this.angle = Math.atan2(vy, vx);
this.speed = Math.sqrt(vx * vx + vy * vy);
if (this.collideWorldBounds && this.checkWorldBounds() && this.onWorldBounds) {
var blocked = this.blocked;
this.world.emit(Events.WORLD_BOUNDS, this, blocked.up, blocked.down, blocked.left, blocked.right);
}
},
/**
* Feeds the Body results back into the parent Game Object.
*
* This method is called every game frame, regardless if the world steps or not.
*
* @method Phaser.Physics.Arcade.Body#postUpdate
* @since 3.0.0
*/
postUpdate: function() {
var pos = this.position;
var dx = pos.x - this.prevFrame.x;
var dy = pos.y - this.prevFrame.y;
var gameObject = this.gameObject;
if (this.moves) {
var mx = this.deltaMax.x;
var my = this.deltaMax.y;
if (mx !== 0 && dx !== 0) {
if (dx < 0 && dx < -mx) {
dx = -mx;
} else if (dx > 0 && dx > mx) {
dx = mx;
}
}
if (my !== 0 && dy !== 0) {
if (dy < 0 && dy < -my) {
dy = -my;
} else if (dy > 0 && dy > my) {
dy = my;
}
}
if (gameObject) {
gameObject.x += dx;
gameObject.y += dy;
}
}
if (dx < 0) {
this.facing = CONST.FACING_LEFT;
} else if (dx > 0) {
this.facing = CONST.FACING_RIGHT;
}
if (dy < 0) {
this.facing = CONST.FACING_UP;
} else if (dy > 0) {
this.facing = CONST.FACING_DOWN;
}
if (this.allowRotation && gameObject) {
gameObject.angle += this.deltaZ();
}
this._tx = dx;
this._ty = dy;
this.autoFrame.set(pos.x, pos.y);
},
/**
* Sets a custom collision boundary rectangle. Use if you want to have a custom
* boundary instead of the world boundaries.
*
* @method Phaser.Physics.Arcade.Body#setBoundsRectangle
* @since 3.20
*
* @param {?Phaser.Geom.Rectangle} [bounds] - The new boundary rectangle. Pass `null` to use the World bounds.
*
* @return {this} This Body object.
*/
setBoundsRectangle: function(bounds) {
this.customBoundsRectangle = !bounds ? this.world.bounds : bounds;
return this;
},
/**
* Checks for collisions between this Body and the world boundary and separates them.
*
* @method Phaser.Physics.Arcade.Body#checkWorldBounds
* @since 3.0.0
*
* @return {boolean} True if this Body is colliding with the world boundary.
*/
checkWorldBounds: function() {
var pos = this.position;
var vel = this.velocity;
var blocked = this.blocked;
var bounds = this.customBoundsRectangle;
var check = this.world.checkCollision;
var bx = this.worldBounce ? -this.worldBounce.x : -this.bounce.x;
var by = this.worldBounce ? -this.worldBounce.y : -this.bounce.y;
var wasSet = false;
if (pos.x < bounds.x && check.left) {
pos.x = bounds.x;
vel.x *= bx;
blocked.left = true;
wasSet = true;
} else if (this.right > bounds.right && check.right) {
pos.x = bounds.right - this.width;
vel.x *= bx;
blocked.right = true;
wasSet = true;
}
if (pos.y < bounds.y && check.up) {
pos.y = bounds.y;
vel.y *= by;
blocked.up = true;
wasSet = true;
} else if (this.bottom > bounds.bottom && check.down) {
pos.y = bounds.bottom - this.height;
vel.y *= by;
blocked.down = true;
wasSet = true;
}
if (wasSet) {
this.blocked.none = false;
this.updateCenter();
}
return wasSet;
},
/**
* Sets the offset of the Body's position from its Game Object's position.
* The Body's `position` isn't changed until the next `preUpdate`.
*
* @method Phaser.Physics.Arcade.Body#setOffset
* @since 3.0.0
*
* @param {number} x - The horizontal offset, in source pixels.
* @param {number} [y=x] - The vertical offset, in source pixels.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setOffset: function(x, y) {
if (y === void 0) {
y = x;
}
this.offset.set(x, y);
return this;
},
/**
* Assign this Body to a new Game Object.
*
* Removes this body from the Physics World, assigns to the new Game Object, calls `setSize` and then
* adds this body back into the World again, setting it enabled, unless the `enable` argument is set to `false`.
*
* If this body already has a Game Object, then it will remove itself from that Game Object first.
*
* Only if the given `gameObject` has a `body` property will this Body be assigned to it.
*
* @method Phaser.Physics.Arcade.Body#setGameObject
* @since 3.60.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object this Body belongs to.
* @param {boolean} [enable=true] - Automatically enable this Body for physics.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setGameObject: function(gameObject, enable) {
if (enable === void 0) {
enable = true;
}
this.world.remove(this);
if (this.gameObject && this.gameObject.body) {
this.gameObject.body = null;
}
this.gameObject = gameObject;
if (gameObject.body) {
gameObject.body = this;
}
this.setSize();
this.world.add(this);
this.enable = enable;
return this;
},
/**
* Sizes and positions this Body, as a rectangle.
* Modifies the Body `offset` if `center` is true (the default).
* Resets the width and height to match current frame, if no width and height provided and a frame is found.
*
* @method Phaser.Physics.Arcade.Body#setSize
* @since 3.0.0
*
* @param {number} [width] - The width of the Body in pixels. Cannot be zero. If not given, and the parent Game Object has a frame, it will use the frame width.
* @param {number} [height] - The height of the Body in pixels. Cannot be zero. If not given, and the parent Game Object has a frame, it will use the frame height.
* @param {boolean} [center=true] - Modify the Body's `offset`, placing the Body's center on its Game Object's center. Only works if the Game Object has the `getCenter` method.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setSize: function(width, height, center) {
if (center === void 0) {
center = true;
}
var gameObject = this.gameObject;
if (gameObject) {
if (!width && gameObject.frame) {
width = gameObject.frame.realWidth;
}
if (!height && gameObject.frame) {
height = gameObject.frame.realHeight;
}
}
this.sourceWidth = width;
this.sourceHeight = height;
this.width = this.sourceWidth * this._sx;
this.height = this.sourceHeight * this._sy;
this.halfWidth = Math.floor(this.width / 2);
this.halfHeight = Math.floor(this.height / 2);
this.updateCenter();
if (center && gameObject && gameObject.getCenter) {
var ox = (gameObject.width - width) / 2;
var oy = (gameObject.height - height) / 2;
this.offset.set(ox, oy);
}
this.isCircle = false;
this.radius = 0;
return this;
},
/**
* Sizes and positions this Body, as a circle.
*
* @method Phaser.Physics.Arcade.Body#setCircle
* @since 3.0.0
*
* @param {number} radius - The radius of the Body, in source pixels.
* @param {number} [offsetX] - The horizontal offset of the Body from its Game Object, in source pixels.
* @param {number} [offsetY] - The vertical offset of the Body from its Game Object, in source pixels.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setCircle: function(radius, offsetX, offsetY) {
if (offsetX === void 0) {
offsetX = this.offset.x;
}
if (offsetY === void 0) {
offsetY = this.offset.y;
}
if (radius > 0) {
this.isCircle = true;
this.radius = radius;
this.sourceWidth = radius * 2;
this.sourceHeight = radius * 2;
this.width = this.sourceWidth * this._sx;
this.height = this.sourceHeight * this._sy;
this.halfWidth = Math.floor(this.width / 2);
this.halfHeight = Math.floor(this.height / 2);
this.offset.set(offsetX, offsetY);
this.updateCenter();
} else {
this.isCircle = false;
}
return this;
},
/**
* Sets this Body's parent Game Object to the given coordinates and resets this Body at the new coordinates.
* If the Body had any velocity or acceleration it is lost as a result of calling this.
*
* @method Phaser.Physics.Arcade.Body#reset
* @since 3.0.0
*
* @param {number} x - The horizontal position to place the Game Object.
* @param {number} y - The vertical position to place the Game Object.
*/
reset: function(x, y) {
this.stop();
var gameObject = this.gameObject;
if (gameObject) {
gameObject.setPosition(x, y);
this.rotation = gameObject.angle;
this.preRotation = gameObject.angle;
}
var pos = this.position;
if (gameObject && gameObject.getTopLeft) {
gameObject.getTopLeft(pos);
} else {
pos.set(x, y);
}
this.prev.copy(pos);
this.prevFrame.copy(pos);
this.autoFrame.copy(pos);
if (gameObject) {
this.updateBounds();
}
this.updateCenter();
if (this.collideWorldBounds) {
this.checkWorldBounds();
}
this.resetFlags(true);
},
/**
* Sets acceleration, velocity, and speed to zero.
*
* @method Phaser.Physics.Arcade.Body#stop
* @since 3.0.0
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
stop: function() {
this.velocity.set(0);
this.acceleration.set(0);
this.speed = 0;
this.angularVelocity = 0;
this.angularAcceleration = 0;
return this;
},
/**
* Copies the coordinates of this Body's edges into an object.
*
* @method Phaser.Physics.Arcade.Body#getBounds
* @since 3.0.0
*
* @param {Phaser.Types.Physics.Arcade.ArcadeBodyBounds} obj - An object to copy the values into.
*
* @return {Phaser.Types.Physics.Arcade.ArcadeBodyBounds} - An object with {x, y, right, bottom}.
*/
getBounds: function(obj) {
obj.x = this.x;
obj.y = this.y;
obj.right = this.right;
obj.bottom = this.bottom;
return obj;
},
/**
* Tests if the coordinates are within this Body.
*
* @method Phaser.Physics.Arcade.Body#hitTest
* @since 3.0.0
*
* @param {number} x - The horizontal coordinate.
* @param {number} y - The vertical coordinate.
*
* @return {boolean} True if (x, y) is within this Body.
*/
hitTest: function(x, y) {
if (!this.isCircle) {
return RectangleContains(this, x, y);
}
if (this.radius > 0 && x >= this.left && x <= this.right && y >= this.top && y <= this.bottom) {
var dx = (this.center.x - x) * (this.center.x - x);
var dy = (this.center.y - y) * (this.center.y - y);
return dx + dy <= this.radius * this.radius;
}
return false;
},
/**
* Whether this Body is touching a tile or the world boundary while moving down.
*
* @method Phaser.Physics.Arcade.Body#onFloor
* @since 3.0.0
* @see Phaser.Physics.Arcade.Body#blocked
*
* @return {boolean} True if touching.
*/
onFloor: function() {
return this.blocked.down;
},
/**
* Whether this Body is touching a tile or the world boundary while moving up.
*
* @method Phaser.Physics.Arcade.Body#onCeiling
* @since 3.0.0
* @see Phaser.Physics.Arcade.Body#blocked
*
* @return {boolean} True if touching.
*/
onCeiling: function() {
return this.blocked.up;
},
/**
* Whether this Body is touching a tile or the world boundary while moving left or right.
*
* @method Phaser.Physics.Arcade.Body#onWall
* @since 3.0.0
* @see Phaser.Physics.Arcade.Body#blocked
*
* @return {boolean} True if touching.
*/
onWall: function() {
return this.blocked.left || this.blocked.right;
},
/**
* The absolute (non-negative) change in this Body's horizontal position from the previous step.
*
* @method Phaser.Physics.Arcade.Body#deltaAbsX
* @since 3.0.0
*
* @return {number} The delta value.
*/
deltaAbsX: function() {
return this._dx > 0 ? this._dx : -this._dx;
},
/**
* The absolute (non-negative) change in this Body's vertical position from the previous step.
*
* @method Phaser.Physics.Arcade.Body#deltaAbsY
* @since 3.0.0
*
* @return {number} The delta value.
*/
deltaAbsY: function() {
return this._dy > 0 ? this._dy : -this._dy;
},
/**
* The change in this Body's horizontal position from the previous step.
* This value is set during the Body's update phase.
*
* As a Body can update multiple times per step this may not hold the final
* delta value for the Body. In this case, please see the `deltaXFinal` method.
*
* @method Phaser.Physics.Arcade.Body#deltaX
* @since 3.0.0
*
* @return {number} The delta value.
*/
deltaX: function() {
return this._dx;
},
/**
* The change in this Body's vertical position from the previous step.
* This value is set during the Body's update phase.
*
* As a Body can update multiple times per step this may not hold the final
* delta value for the Body. In this case, please see the `deltaYFinal` method.
*
* @method Phaser.Physics.Arcade.Body#deltaY
* @since 3.0.0
*
* @return {number} The delta value.
*/
deltaY: function() {
return this._dy;
},
/**
* The change in this Body's horizontal position from the previous game update.
*
* This value is set during the `postUpdate` phase and takes into account the
* `deltaMax` and final position of the Body.
*
* Because this value is not calculated until `postUpdate`, you must listen for it
* during a Scene `POST_UPDATE` or `RENDER` event, and not in `update`, as it will
* not be calculated by that point. If you _do_ use these values in `update` they
* will represent the delta from the _previous_ game frame.
*
* @method Phaser.Physics.Arcade.Body#deltaXFinal
* @since 3.22.0
*
* @return {number} The final delta x value.
*/
deltaXFinal: function() {
return this._tx;
},
/**
* The change in this Body's vertical position from the previous game update.
*
* This value is set during the `postUpdate` phase and takes into account the
* `deltaMax` and final position of the Body.
*
* Because this value is not calculated until `postUpdate`, you must listen for it
* during a Scene `POST_UPDATE` or `RENDER` event, and not in `update`, as it will
* not be calculated by that point. If you _do_ use these values in `update` they
* will represent the delta from the _previous_ game frame.
*
* @method Phaser.Physics.Arcade.Body#deltaYFinal
* @since 3.22.0
*
* @return {number} The final delta y value.
*/
deltaYFinal: function() {
return this._ty;
},
/**
* The change in this Body's rotation from the previous step, in degrees.
*
* @method Phaser.Physics.Arcade.Body#deltaZ
* @since 3.0.0
*
* @return {number} The delta value.
*/
deltaZ: function() {
return this.rotation - this.preRotation;
},
/**
* Disables this Body and marks it for deletion by the simulation.
*
* @method Phaser.Physics.Arcade.Body#destroy
* @since 3.0.0
*/
destroy: function() {
this.enable = false;
if (this.world) {
this.world.pendingDestroy.set(this);
}
},
/**
* Draws this Body and its velocity, if enabled.
*
* @method Phaser.Physics.Arcade.Body#drawDebug
* @since 3.0.0
*
* @param {Phaser.GameObjects.Graphics} graphic - The Graphics object to draw on.
*/
drawDebug: function(graphic) {
var pos = this.position;
var x = pos.x + this.halfWidth;
var y = pos.y + this.halfHeight;
if (this.debugShowBody) {
graphic.lineStyle(graphic.defaultStrokeWidth, this.debugBodyColor);
if (this.isCircle) {
graphic.strokeCircle(x, y, this.width / 2);
} else {
if (this.checkCollision.up) {
graphic.lineBetween(pos.x, pos.y, pos.x + this.width, pos.y);
}
if (this.checkCollision.right) {
graphic.lineBetween(pos.x + this.width, pos.y, pos.x + this.width, pos.y + this.height);
}
if (this.checkCollision.down) {
graphic.lineBetween(pos.x, pos.y + this.height, pos.x + this.width, pos.y + this.height);
}
if (this.checkCollision.left) {
graphic.lineBetween(pos.x, pos.y, pos.x, pos.y + this.height);
}
}
}
if (this.debugShowVelocity) {
graphic.lineStyle(graphic.defaultStrokeWidth, this.world.defaults.velocityDebugColor, 1);
graphic.lineBetween(x, y, x + this.velocity.x / 2, y + this.velocity.y / 2);
}
},
/**
* Whether this Body will be drawn to the debug display.
*
* @method Phaser.Physics.Arcade.Body#willDrawDebug
* @since 3.0.0
*
* @return {boolean} True if either `debugShowBody` or `debugShowVelocity` are enabled.
*/
willDrawDebug: function() {
return this.debugShowBody || this.debugShowVelocity;
},
/**
* Sets whether this Body should calculate its velocity based on its change in
* position every frame. The default, which is to not do this, means that you
* make this Body move by setting the velocity directly. However, if you are
* trying to move this Body via a Tween, or have it follow a Path, then you
* should enable this instead. This will allow it to still collide with other
* bodies, something that isn't possible if you're just changing its position directly.
*
* @method Phaser.Physics.Arcade.Body#setDirectControl
* @since 3.70.0
*
* @param {boolean} [value=true] - `true` if the Body calculate velocity based on changes in position, otherwise `false`.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setDirectControl: function(value) {
if (value === void 0) {
value = true;
}
this.directControl = value;
return this;
},
/**
* Sets whether this Body collides with the world boundary.
*
* Optionally also sets the World Bounce and `onWorldBounds` values.
*
* @method Phaser.Physics.Arcade.Body#setCollideWorldBounds
* @since 3.0.0
*
* @param {boolean} [value=true] - `true` if the Body should collide with the world bounds, otherwise `false`.
* @param {number} [bounceX] - If given this replaces the Body's `worldBounce.x` value.
* @param {number} [bounceY] - If given this replaces the Body's `worldBounce.y` value.
* @param {boolean} [onWorldBounds] - If given this replaces the Body's `onWorldBounds` value.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setCollideWorldBounds: function(value, bounceX, bounceY, onWorldBounds) {
if (value === void 0) {
value = true;
}
this.collideWorldBounds = value;
var setBounceX = bounceX !== void 0;
var setBounceY = bounceY !== void 0;
if (setBounceX || setBounceY) {
if (!this.worldBounce) {
this.worldBounce = new Vector2();
}
if (setBounceX) {
this.worldBounce.x = bounceX;
}
if (setBounceY) {
this.worldBounce.y = bounceY;
}
}
if (onWorldBounds !== void 0) {
this.onWorldBounds = onWorldBounds;
}
return this;
},
/**
* Sets the Body's velocity.
*
* @method Phaser.Physics.Arcade.Body#setVelocity
* @since 3.0.0
*
* @param {number} x - The horizontal velocity, in pixels per second.
* @param {number} [y=x] - The vertical velocity, in pixels per second.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setVelocity: function(x, y) {
this.velocity.set(x, y);
x = this.velocity.x;
y = this.velocity.y;
this.speed = Math.sqrt(x * x + y * y);
return this;
},
/**
* Sets the Body's horizontal velocity.
*
* @method Phaser.Physics.Arcade.Body#setVelocityX
* @since 3.0.0
*
* @param {number} value - The velocity, in pixels per second.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setVelocityX: function(value) {
return this.setVelocity(value, this.velocity.y);
},
/**
* Sets the Body's vertical velocity.
*
* @method Phaser.Physics.Arcade.Body#setVelocityY
* @since 3.0.0
*
* @param {number} value - The velocity, in pixels per second.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setVelocityY: function(value) {
return this.setVelocity(this.velocity.x, value);
},
/**
* Sets the Body's maximum velocity.
*
* @method Phaser.Physics.Arcade.Body#setMaxVelocity
* @since 3.10.0
*
* @param {number} x - The horizontal velocity, in pixels per second.
* @param {number} [y=x] - The vertical velocity, in pixels per second.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setMaxVelocity: function(x, y) {
this.maxVelocity.set(x, y);
return this;
},
/**
* Sets the Body's maximum horizontal velocity.
*
* @method Phaser.Physics.Arcade.Body#setMaxVelocityX
* @since 3.50.0
*
* @param {number} value - The maximum horizontal velocity, in pixels per second.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setMaxVelocityX: function(value) {
this.maxVelocity.x = value;
return this;
},
/**
* Sets the Body's maximum vertical velocity.
*
* @method Phaser.Physics.Arcade.Body#setMaxVelocityY
* @since 3.50.0
*
* @param {number} value - The maximum vertical velocity, in pixels per second.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setMaxVelocityY: function(value) {
this.maxVelocity.y = value;
return this;
},
/**
* Sets the maximum speed the Body can move.
*
* @method Phaser.Physics.Arcade.Body#setMaxSpeed
* @since 3.16.0
*
* @param {number} value - The maximum speed value, in pixels per second. Set to a negative value to disable.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setMaxSpeed: function(value) {
this.maxSpeed = value;
return this;
},
/**
* Sets the Slide Factor of this Body.
*
* The Slide Factor controls how much velocity is preserved when
* this Body is pushed by another Body.
*
* The default value is 1, which means that it will take on all
* velocity given in the push. You can adjust this value to control
* how much velocity is retained by this Body when the push ends.
*
* A value of 0, for example, will allow this Body to be pushed
* but then remain completely still after the push ends, such as
* you see in a game like Sokoban.
*
* Or you can set a mid-point, such as 0.25 which will allow it
* to keep 25% of the original velocity when the push ends. You
* can combine this with the `setDrag()` method to create deceleration.
*
* @method Phaser.Physics.Arcade.Body#setSlideFactor
* @since 3.70.0
*
* @param {number} x - The horizontal slide factor. A value between 0 and 1.
* @param {number} [y=x] - The vertical slide factor. A value between 0 and 1.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setSlideFactor: function(x, y) {
this.slideFactor.set(x, y);
return this;
},
/**
* Sets the Body's bounce.
*
* @method Phaser.Physics.Arcade.Body#setBounce
* @since 3.0.0
*
* @param {number} x - The horizontal bounce, relative to 1.
* @param {number} [y=x] - The vertical bounce, relative to 1.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setBounce: function(x, y) {
this.bounce.set(x, y);
return this;
},
/**
* Sets the Body's horizontal bounce.
*
* @method Phaser.Physics.Arcade.Body#setBounceX
* @since 3.0.0
*
* @param {number} value - The bounce, relative to 1.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setBounceX: function(value) {
this.bounce.x = value;
return this;
},
/**
* Sets the Body's vertical bounce.
*
* @method Phaser.Physics.Arcade.Body#setBounceY
* @since 3.0.0
*
* @param {number} value - The bounce, relative to 1.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setBounceY: function(value) {
this.bounce.y = value;
return this;
},
/**
* Sets the Body's acceleration.
*
* @method Phaser.Physics.Arcade.Body#setAcceleration
* @since 3.0.0
*
* @param {number} x - The horizontal component, in pixels per second squared.
* @param {number} [y=x] - The vertical component, in pixels per second squared.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setAcceleration: function(x, y) {
this.acceleration.set(x, y);
return this;
},
/**
* Sets the Body's horizontal acceleration.
*
* @method Phaser.Physics.Arcade.Body#setAccelerationX
* @since 3.0.0
*
* @param {number} value - The acceleration, in pixels per second squared.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setAccelerationX: function(value) {
this.acceleration.x = value;
return this;
},
/**
* Sets the Body's vertical acceleration.
*
* @method Phaser.Physics.Arcade.Body#setAccelerationY
* @since 3.0.0
*
* @param {number} value - The acceleration, in pixels per second squared.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setAccelerationY: function(value) {
this.acceleration.y = value;
return this;
},
/**
* Enables or disables drag.
*
* @method Phaser.Physics.Arcade.Body#setAllowDrag
* @since 3.9.0
* @see Phaser.Physics.Arcade.Body#allowDrag
*
* @param {boolean} [value=true] - `true` to allow drag on this body, or `false` to disable it.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setAllowDrag: function(value) {
if (value === void 0) {
value = true;
}
this.allowDrag = value;
return this;
},
/**
* Enables or disables gravity's effect on this Body.
*
* @method Phaser.Physics.Arcade.Body#setAllowGravity
* @since 3.9.0
* @see Phaser.Physics.Arcade.Body#allowGravity
*
* @param {boolean} [value=true] - `true` to allow gravity on this body, or `false` to disable it.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setAllowGravity: function(value) {
if (value === void 0) {
value = true;
}
this.allowGravity = value;
return this;
},
/**
* Enables or disables rotation.
*
* @method Phaser.Physics.Arcade.Body#setAllowRotation
* @since 3.9.0
* @see Phaser.Physics.Arcade.Body#allowRotation
*
* @param {boolean} [value=true] - `true` to allow rotation on this body, or `false` to disable it.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setAllowRotation: function(value) {
if (value === void 0) {
value = true;
}
this.allowRotation = value;
return this;
},
/**
* Sets the Body's drag.
*
* @method Phaser.Physics.Arcade.Body#setDrag
* @since 3.0.0
*
* @param {number} x - The horizontal component, in pixels per second squared.
* @param {number} [y=x] - The vertical component, in pixels per second squared.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setDrag: function(x, y) {
this.drag.set(x, y);
return this;
},
/**
* If this Body is using `drag` for deceleration this property controls how the drag is applied.
* If set to `true` drag will use a damping effect rather than a linear approach. If you are
* creating a game where the Body moves freely at any angle (i.e. like the way the ship moves in
* the game Asteroids) then you will get a far smoother and more visually correct deceleration
* by using damping, avoiding the axis-drift that is prone with linear deceleration.
*
* If you enable this property then you should use far smaller `drag` values than with linear, as
* they are used as a multiplier on the velocity. Values such as 0.95 will give a nice slow
* deceleration, where-as smaller values, such as 0.5 will stop an object almost immediately.
*
* @method Phaser.Physics.Arcade.Body#setDamping
* @since 3.50.0
*
* @param {boolean} value - `true` to use damping, or `false` to use drag.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setDamping: function(value) {
this.useDamping = value;
return this;
},
/**
* Sets the Body's horizontal drag.
*
* @method Phaser.Physics.Arcade.Body#setDragX
* @since 3.0.0
*
* @param {number} value - The drag, in pixels per second squared.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setDragX: function(value) {
this.drag.x = value;
return this;
},
/**
* Sets the Body's vertical drag.
*
* @method Phaser.Physics.Arcade.Body#setDragY
* @since 3.0.0
*
* @param {number} value - The drag, in pixels per second squared.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setDragY: function(value) {
this.drag.y = value;
return this;
},
/**
* Sets the Body's gravity.
*
* @method Phaser.Physics.Arcade.Body#setGravity
* @since 3.0.0
*
* @param {number} x - The horizontal component, in pixels per second squared.
* @param {number} [y=x] - The vertical component, in pixels per second squared.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setGravity: function(x, y) {
this.gravity.set(x, y);
return this;
},
/**
* Sets the Body's horizontal gravity.
*
* @method Phaser.Physics.Arcade.Body#setGravityX
* @since 3.0.0
*
* @param {number} value - The gravity, in pixels per second squared.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setGravityX: function(value) {
this.gravity.x = value;
return this;
},
/**
* Sets the Body's vertical gravity.
*
* @method Phaser.Physics.Arcade.Body#setGravityY
* @since 3.0.0
*
* @param {number} value - The gravity, in pixels per second squared.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setGravityY: function(value) {
this.gravity.y = value;
return this;
},
/**
* Sets the Body's friction.
*
* @method Phaser.Physics.Arcade.Body#setFriction
* @since 3.0.0
*
* @param {number} x - The horizontal component, relative to 1.
* @param {number} [y=x] - The vertical component, relative to 1.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setFriction: function(x, y) {
this.friction.set(x, y);
return this;
},
/**
* Sets the Body's horizontal friction.
*
* @method Phaser.Physics.Arcade.Body#setFrictionX
* @since 3.0.0
*
* @param {number} value - The friction value, relative to 1.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setFrictionX: function(value) {
this.friction.x = value;
return this;
},
/**
* Sets the Body's vertical friction.
*
* @method Phaser.Physics.Arcade.Body#setFrictionY
* @since 3.0.0
*
* @param {number} value - The friction value, relative to 1.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setFrictionY: function(value) {
this.friction.y = value;
return this;
},
/**
* Sets the Body's angular velocity.
*
* @method Phaser.Physics.Arcade.Body#setAngularVelocity
* @since 3.0.0
*
* @param {number} value - The velocity, in degrees per second.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setAngularVelocity: function(value) {
this.angularVelocity = value;
return this;
},
/**
* Sets the Body's angular acceleration.
*
* @method Phaser.Physics.Arcade.Body#setAngularAcceleration
* @since 3.0.0
*
* @param {number} value - The acceleration, in degrees per second squared.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setAngularAcceleration: function(value) {
this.angularAcceleration = value;
return this;
},
/**
* Sets the Body's angular drag.
*
* @method Phaser.Physics.Arcade.Body#setAngularDrag
* @since 3.0.0
*
* @param {number} value - The drag, in degrees per second squared.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setAngularDrag: function(value) {
this.angularDrag = value;
return this;
},
/**
* Sets the Body's mass.
*
* @method Phaser.Physics.Arcade.Body#setMass
* @since 3.0.0
*
* @param {number} value - The mass value, relative to 1.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setMass: function(value) {
this.mass = value;
return this;
},
/**
* Sets the Body's `immovable` property.
*
* @method Phaser.Physics.Arcade.Body#setImmovable
* @since 3.0.0
*
* @param {boolean} [value=true] - The value to assign to `immovable`.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setImmovable: function(value) {
if (value === void 0) {
value = true;
}
this.immovable = value;
return this;
},
/**
* Sets the Body's `enable` property.
*
* @method Phaser.Physics.Arcade.Body#setEnable
* @since 3.15.0
*
* @param {boolean} [value=true] - The value to assign to `enable`.
*
* @return {Phaser.Physics.Arcade.Body} This Body object.
*/
setEnable: function(value) {
if (value === void 0) {
value = true;
}
this.enable = value;
return this;
},
/**
* This is an internal handler, called by the `ProcessX` function as part
* of the collision step. You should almost never call this directly.
*
* @method Phaser.Physics.Arcade.Body#processX
* @since 3.50.0
*
* @param {number} x - The amount to add to the Body position.
* @param {number} [vx] - The amount to add to the Body velocity.
* @param {boolean} [left] - Set the blocked.left value?
* @param {boolean} [right] - Set the blocked.right value?
*/
processX: function(x, vx, left, right) {
this.x += x;
this.updateCenter();
if (vx !== null) {
this.velocity.x = vx * this.slideFactor.x;
}
var blocked = this.blocked;
if (left) {
blocked.left = true;
blocked.none = false;
}
if (right) {
blocked.right = true;
blocked.none = false;
}
},
/**
* This is an internal handler, called by the `ProcessY` function as part
* of the collision step. You should almost never call this directly.
*
* @method Phaser.Physics.Arcade.Body#processY
* @since 3.50.0
*
* @param {number} y - The amount to add to the Body position.
* @param {number} [vy] - The amount to add to the Body velocity.
* @param {boolean} [up] - Set the blocked.up value?
* @param {boolean} [down] - Set the blocked.down value?
*/
processY: function(y, vy, up, down) {
this.y += y;
this.updateCenter();
if (vy !== null) {
this.velocity.y = vy * this.slideFactor.y;
}
var blocked = this.blocked;
if (up) {
blocked.up = true;
blocked.none = false;
}
if (down) {
blocked.down = true;
blocked.none = false;
}
},
/**
* The Bodys horizontal position (left edge).
*
* @name Phaser.Physics.Arcade.Body#x
* @type {number}
* @since 3.0.0
*/
x: {
get: function() {
return this.position.x;
},
set: function(value) {
this.position.x = value;
}
},
/**
* The Bodys vertical position (top edge).
*
* @name Phaser.Physics.Arcade.Body#y
* @type {number}
* @since 3.0.0
*/
y: {
get: function() {
return this.position.y;
},
set: function(value) {
this.position.y = value;
}
},
/**
* The left edge of the Body. Identical to x.
*
* @name Phaser.Physics.Arcade.Body#left
* @type {number}
* @readonly
* @since 3.0.0
*/
left: {
get: function() {
return this.position.x;
}
},
/**
* The right edge of the Body.
*
* @name Phaser.Physics.Arcade.Body#right
* @type {number}
* @readonly
* @since 3.0.0
*/
right: {
get: function() {
return this.position.x + this.width;
}
},
/**
* The top edge of the Body. Identical to y.
*
* @name Phaser.Physics.Arcade.Body#top
* @type {number}
* @readonly
* @since 3.0.0
*/
top: {
get: function() {
return this.position.y;
}
},
/**
* The bottom edge of this Body.
*
* @name Phaser.Physics.Arcade.Body#bottom
* @type {number}
* @readonly
* @since 3.0.0
*/
bottom: {
get: function() {
return this.position.y + this.height;
}
}
});
module2.exports = Body;
}
),
/***/
79342: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Collider = new Class({
initialize: function Collider2(world, overlapOnly, object1, object2, collideCallback, processCallback, callbackContext) {
this.world = world;
this.name = "";
this.active = true;
this.overlapOnly = overlapOnly;
this.object1 = object1;
this.object2 = object2;
this.collideCallback = collideCallback;
this.processCallback = processCallback;
this.callbackContext = callbackContext;
},
/**
* A name for the Collider.
*
* Phaser does not use this value, it's for your own reference.
*
* @method Phaser.Physics.Arcade.Collider#setName
* @since 3.1.0
*
* @param {string} name - The name to assign to the Collider.
*
* @return {Phaser.Physics.Arcade.Collider} This Collider instance.
*/
setName: function(name) {
this.name = name;
return this;
},
/**
* Called by World as part of its step processing, initial operation of collision checking.
*
* @method Phaser.Physics.Arcade.Collider#update
* @since 3.0.0
*/
update: function() {
this.world.collideObjects(
this.object1,
this.object2,
this.collideCallback,
this.processCallback,
this.callbackContext,
this.overlapOnly
);
},
/**
* Removes Collider from World and disposes of its resources.
*
* @method Phaser.Physics.Arcade.Collider#destroy
* @since 3.0.0
*/
destroy: function() {
this.world.removeCollider(this);
this.active = false;
this.world = null;
this.object1 = null;
this.object2 = null;
this.collideCallback = null;
this.processCallback = null;
this.callbackContext = null;
}
});
module2.exports = Collider;
}
),
/***/
66022: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var ArcadeImage = __webpack_require__2(71289);
var ArcadeSprite = __webpack_require__2(13759);
var Body = __webpack_require__2(37742);
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(37747);
var PhysicsGroup = __webpack_require__2(60758);
var StaticBody = __webpack_require__2(72624);
var StaticPhysicsGroup = __webpack_require__2(71464);
var Factory = new Class({
initialize: function Factory2(world) {
this.world = world;
this.scene = world.scene;
this.sys = world.scene.sys;
},
/**
* Creates a new Arcade Physics Collider object.
*
* @method Phaser.Physics.Arcade.Factory#collider
* @since 3.0.0
*
* @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object to check for collision.
* @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object2 - The second object to check for collision.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - The callback to invoke when the two objects collide.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [processCallback] - The callback to invoke when the two objects collide. Must return a boolean.
* @param {*} [callbackContext] - The scope in which to call the callbacks.
*
* @return {Phaser.Physics.Arcade.Collider} The Collider that was created.
*/
collider: function(object1, object2, collideCallback, processCallback, callbackContext) {
return this.world.addCollider(object1, object2, collideCallback, processCallback, callbackContext);
},
/**
* Creates a new Arcade Physics Collider Overlap object.
*
* @method Phaser.Physics.Arcade.Factory#overlap
* @since 3.0.0
*
* @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object to check for overlap.
* @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object2 - The second object to check for overlap.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - The callback to invoke when the two objects collide.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [processCallback] - The callback to invoke when the two objects collide. Must return a boolean.
* @param {*} [callbackContext] - The scope in which to call the callbacks.
*
* @return {Phaser.Physics.Arcade.Collider} The Collider that was created.
*/
overlap: function(object1, object2, collideCallback, processCallback, callbackContext) {
return this.world.addOverlap(object1, object2, collideCallback, processCallback, callbackContext);
},
/**
* Adds an Arcade Physics Body to the given Game Object.
*
* @method Phaser.Physics.Arcade.Factory#existing
* @since 3.0.0
*
* @generic {Phaser.GameObjects.GameObject} G - [gameObject,$return]
*
* @param {Phaser.GameObjects.GameObject} gameObject - A Game Object.
* @param {boolean} [isStatic=false] - Create a Static body (true) or Dynamic body (false).
*
* @return {Phaser.Types.Physics.Arcade.GameObjectWithBody} The Game Object.
*/
existing: function(gameObject, isStatic) {
var type = isStatic ? CONST.STATIC_BODY : CONST.DYNAMIC_BODY;
this.world.enableBody(gameObject, type);
return gameObject;
},
/**
* Creates a new Arcade Image object with a Static body.
*
* @method Phaser.Physics.Arcade.Factory#staticImage
* @since 3.0.0
*
* @param {number} x - The horizontal position of this Game Object in the world.
* @param {number} y - The vertical position of this Game Object in the world.
* @param {(string|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with.
*
* @return {Phaser.Types.Physics.Arcade.ImageWithStaticBody} The Image object that was created.
*/
staticImage: function(x, y, key, frame) {
var image = new ArcadeImage(this.scene, x, y, key, frame);
this.sys.displayList.add(image);
this.world.enableBody(image, CONST.STATIC_BODY);
return image;
},
/**
* Creates a new Arcade Image object with a Dynamic body.
*
* @method Phaser.Physics.Arcade.Factory#image
* @since 3.0.0
*
* @param {number} x - The horizontal position of this Game Object in the world.
* @param {number} y - The vertical position of this Game Object in the world.
* @param {(string|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with.
*
* @return {Phaser.Types.Physics.Arcade.ImageWithDynamicBody} The Image object that was created.
*/
image: function(x, y, key, frame) {
var image = new ArcadeImage(this.scene, x, y, key, frame);
this.sys.displayList.add(image);
this.world.enableBody(image, CONST.DYNAMIC_BODY);
return image;
},
/**
* Creates a new Arcade Sprite object with a Static body.
*
* @method Phaser.Physics.Arcade.Factory#staticSprite
* @since 3.0.0
*
* @param {number} x - The horizontal position of this Game Object in the world.
* @param {number} y - The vertical position of this Game Object in the world.
* @param {(string|Phaser.Textures.Texture)} texture - The key, or instance of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with.
*
* @return {Phaser.Types.Physics.Arcade.SpriteWithStaticBody} The Sprite object that was created.
*/
staticSprite: function(x, y, key, frame) {
var sprite = new ArcadeSprite(this.scene, x, y, key, frame);
this.sys.displayList.add(sprite);
this.sys.updateList.add(sprite);
this.world.enableBody(sprite, CONST.STATIC_BODY);
return sprite;
},
/**
* Creates a new Arcade Sprite object with a Dynamic body.
*
* @method Phaser.Physics.Arcade.Factory#sprite
* @since 3.0.0
*
* @param {number} x - The horizontal position of this Game Object in the world.
* @param {number} y - The vertical position of this Game Object in the world.
* @param {string} key - The key of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with.
*
* @return {Phaser.Types.Physics.Arcade.SpriteWithDynamicBody} The Sprite object that was created.
*/
sprite: function(x, y, key, frame) {
var sprite = new ArcadeSprite(this.scene, x, y, key, frame);
this.sys.displayList.add(sprite);
this.sys.updateList.add(sprite);
this.world.enableBody(sprite, CONST.DYNAMIC_BODY);
return sprite;
},
/**
* Creates a Static Physics Group object.
* All Game Objects created by this Group will automatically be static Arcade Physics objects.
*
* @method Phaser.Physics.Arcade.Factory#staticGroup
* @since 3.0.0
*
* @param {(Phaser.GameObjects.GameObject[]|Phaser.Types.GameObjects.Group.GroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig)} [children] - Game Objects to add to this group; or the `config` argument.
* @param {Phaser.Types.GameObjects.Group.GroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig} [config] - Settings for this group.
*
* @return {Phaser.Physics.Arcade.StaticGroup} The Static Group object that was created.
*/
staticGroup: function(children, config) {
return this.sys.updateList.add(new StaticPhysicsGroup(this.world, this.world.scene, children, config));
},
/**
* Creates a Physics Group object.
* All Game Objects created by this Group will automatically be dynamic Arcade Physics objects.
*
* @method Phaser.Physics.Arcade.Factory#group
* @since 3.0.0
*
* @param {(Phaser.GameObjects.GameObject[]|Phaser.Types.Physics.Arcade.PhysicsGroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig)} [children] - Game Objects to add to this group; or the `config` argument.
* @param {Phaser.Types.Physics.Arcade.PhysicsGroupConfig|Phaser.Types.GameObjects.Group.GroupCreateConfig} [config] - Settings for this group.
*
* @return {Phaser.Physics.Arcade.Group} The Group object that was created.
*/
group: function(children, config) {
return this.sys.updateList.add(new PhysicsGroup(this.world, this.world.scene, children, config));
},
/**
* Creates a new physics Body with the given position and size.
*
* This Body is not associated with any Game Object, but still exists within the world
* and can be tested for collision, have velocity, etc.
*
* @method Phaser.Physics.Arcade.Factory#body
* @since 3.60.0
*
* @param {number} x - The horizontal position of this Body in the physics world.
* @param {number} y - The vertical position of this Body in the physics world.
* @param {number} [width=64] - The width of the Body in pixels. Cannot be negative or zero.
* @param {number} [height=64] - The height of the Body in pixels. Cannot be negative or zero.
*
* @return {Phaser.Physics.Arcade.Body} The Body that was created.
*/
body: function(x, y, width, height) {
var body = new Body(this.world);
body.position.set(x, y);
if (width && height) {
body.setSize(width, height);
}
this.world.add(body, CONST.DYNAMIC_BODY);
return body;
},
/**
* Creates a new static physics Body with the given position and size.
*
* This Body is not associated with any Game Object, but still exists within the world
* and can be tested for collision, etc.
*
* @method Phaser.Physics.Arcade.Factory#staticBody
* @since 3.60.0
*
* @param {number} x - The horizontal position of this Body in the physics world.
* @param {number} y - The vertical position of this Body in the physics world.
* @param {number} [width=64] - The width of the Body in pixels. Cannot be negative or zero.
* @param {number} [height=64] - The height of the Body in pixels. Cannot be negative or zero.
*
* @return {Phaser.Physics.Arcade.StaticBody} The Static Body that was created.
*/
staticBody: function(x, y, width, height) {
var body = new StaticBody(this.world);
body.position.set(x, y);
if (width && height) {
body.setSize(width, height);
}
this.world.add(body, CONST.STATIC_BODY);
return body;
},
/**
* Destroys this Factory.
*
* @method Phaser.Physics.Arcade.Factory#destroy
* @since 3.5.0
*/
destroy: function() {
this.world = null;
this.scene = null;
this.sys = null;
}
});
module2.exports = Factory;
}
),
/***/
79599: (
/***/
(module2) => {
var GetCollidesWith = function(categories) {
var flags = 0;
if (!Array.isArray(categories)) {
flags = categories;
} else {
for (var i = 0; i < categories.length; i++) {
flags |= categories[i];
}
}
return flags;
};
module2.exports = GetCollidesWith;
}
),
/***/
64897: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(37747);
var GetOverlapX = function(body1, body2, overlapOnly, bias) {
var overlap = 0;
var maxOverlap = body1.deltaAbsX() + body2.deltaAbsX() + bias;
if (body1._dx === 0 && body2._dx === 0) {
body1.embedded = true;
body2.embedded = true;
} else if (body1._dx > body2._dx) {
overlap = body1.right - body2.x;
if (overlap > maxOverlap && !overlapOnly || body1.checkCollision.right === false || body2.checkCollision.left === false) {
overlap = 0;
} else {
body1.touching.none = false;
body1.touching.right = true;
body2.touching.none = false;
body2.touching.left = true;
if (body2.physicsType === CONST.STATIC_BODY && !overlapOnly) {
body1.blocked.none = false;
body1.blocked.right = true;
}
if (body1.physicsType === CONST.STATIC_BODY && !overlapOnly) {
body2.blocked.none = false;
body2.blocked.left = true;
}
}
} else if (body1._dx < body2._dx) {
overlap = body1.x - body2.width - body2.x;
if (-overlap > maxOverlap && !overlapOnly || body1.checkCollision.left === false || body2.checkCollision.right === false) {
overlap = 0;
} else {
body1.touching.none = false;
body1.touching.left = true;
body2.touching.none = false;
body2.touching.right = true;
if (body2.physicsType === CONST.STATIC_BODY && !overlapOnly) {
body1.blocked.none = false;
body1.blocked.left = true;
}
if (body1.physicsType === CONST.STATIC_BODY && !overlapOnly) {
body2.blocked.none = false;
body2.blocked.right = true;
}
}
}
body1.overlapX = overlap;
body2.overlapX = overlap;
return overlap;
};
module2.exports = GetOverlapX;
}
),
/***/
45170: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(37747);
var GetOverlapY = function(body1, body2, overlapOnly, bias) {
var overlap = 0;
var maxOverlap = body1.deltaAbsY() + body2.deltaAbsY() + bias;
if (body1._dy === 0 && body2._dy === 0) {
body1.embedded = true;
body2.embedded = true;
} else if (body1._dy > body2._dy) {
overlap = body1.bottom - body2.y;
if (overlap > maxOverlap && !overlapOnly || body1.checkCollision.down === false || body2.checkCollision.up === false) {
overlap = 0;
} else {
body1.touching.none = false;
body1.touching.down = true;
body2.touching.none = false;
body2.touching.up = true;
if (body2.physicsType === CONST.STATIC_BODY && !overlapOnly) {
body1.blocked.none = false;
body1.blocked.down = true;
}
if (body1.physicsType === CONST.STATIC_BODY && !overlapOnly) {
body2.blocked.none = false;
body2.blocked.up = true;
}
}
} else if (body1._dy < body2._dy) {
overlap = body1.y - body2.bottom;
if (-overlap > maxOverlap && !overlapOnly || body1.checkCollision.up === false || body2.checkCollision.down === false) {
overlap = 0;
} else {
body1.touching.none = false;
body1.touching.up = true;
body2.touching.none = false;
body2.touching.down = true;
if (body2.physicsType === CONST.STATIC_BODY && !overlapOnly) {
body1.blocked.none = false;
body1.blocked.up = true;
}
if (body1.physicsType === CONST.STATIC_BODY && !overlapOnly) {
body2.blocked.none = false;
body2.blocked.down = true;
}
}
}
body1.overlapY = overlap;
body2.overlapY = overlap;
return overlap;
};
module2.exports = GetOverlapY;
}
),
/***/
60758: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var ArcadeSprite = __webpack_require__2(13759);
var Class = __webpack_require__2(83419);
var CollisionComponent = __webpack_require__2(78389);
var CONST = __webpack_require__2(37747);
var GetFastValue = __webpack_require__2(95540);
var Group = __webpack_require__2(26479);
var IsPlainObject = __webpack_require__2(41212);
var PhysicsGroup = new Class({
Extends: Group,
Mixins: [
CollisionComponent
],
initialize: function PhysicsGroup2(world, scene, children, config) {
if (!children && !config) {
config = {
internalCreateCallback: this.createCallbackHandler,
internalRemoveCallback: this.removeCallbackHandler
};
} else if (IsPlainObject(children)) {
config = children;
children = null;
config.internalCreateCallback = this.createCallbackHandler;
config.internalRemoveCallback = this.removeCallbackHandler;
} else if (Array.isArray(children) && IsPlainObject(children[0])) {
var _this = this;
children.forEach(function(singleConfig) {
singleConfig.internalCreateCallback = _this.createCallbackHandler;
singleConfig.internalRemoveCallback = _this.removeCallbackHandler;
singleConfig.classType = GetFastValue(singleConfig, "classType", ArcadeSprite);
});
config = null;
} else {
config = {
internalCreateCallback: this.createCallbackHandler,
internalRemoveCallback: this.removeCallbackHandler
};
}
this.world = world;
if (config) {
config.classType = GetFastValue(config, "classType", ArcadeSprite);
}
this.physicsType = CONST.DYNAMIC_BODY;
this.collisionCategory = 1;
this.collisionMask = 2147483647;
this.defaults = {
setCollideWorldBounds: GetFastValue(config, "collideWorldBounds", false),
setBoundsRectangle: GetFastValue(config, "customBoundsRectangle", null),
setAccelerationX: GetFastValue(config, "accelerationX", 0),
setAccelerationY: GetFastValue(config, "accelerationY", 0),
setAllowDrag: GetFastValue(config, "allowDrag", true),
setAllowGravity: GetFastValue(config, "allowGravity", true),
setAllowRotation: GetFastValue(config, "allowRotation", true),
setDamping: GetFastValue(config, "useDamping", false),
setBounceX: GetFastValue(config, "bounceX", 0),
setBounceY: GetFastValue(config, "bounceY", 0),
setDragX: GetFastValue(config, "dragX", 0),
setDragY: GetFastValue(config, "dragY", 0),
setEnable: GetFastValue(config, "enable", true),
setGravityX: GetFastValue(config, "gravityX", 0),
setGravityY: GetFastValue(config, "gravityY", 0),
setFrictionX: GetFastValue(config, "frictionX", 0),
setFrictionY: GetFastValue(config, "frictionY", 0),
setMaxSpeed: GetFastValue(config, "maxSpeed", -1),
setMaxVelocityX: GetFastValue(config, "maxVelocityX", 1e4),
setMaxVelocityY: GetFastValue(config, "maxVelocityY", 1e4),
setVelocityX: GetFastValue(config, "velocityX", 0),
setVelocityY: GetFastValue(config, "velocityY", 0),
setAngularVelocity: GetFastValue(config, "angularVelocity", 0),
setAngularAcceleration: GetFastValue(config, "angularAcceleration", 0),
setAngularDrag: GetFastValue(config, "angularDrag", 0),
setMass: GetFastValue(config, "mass", 1),
setImmovable: GetFastValue(config, "immovable", false)
};
Group.call(this, scene, children, config);
this.type = "PhysicsGroup";
},
/**
* Enables a Game Object's Body and assigns `defaults`. Called when a Group member is added or created.
*
* @method Phaser.Physics.Arcade.Group#createCallbackHandler
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} child - The Game Object being added.
*/
createCallbackHandler: function(child) {
if (!child.body) {
this.world.enableBody(child, CONST.DYNAMIC_BODY);
}
var body = child.body;
for (var key in this.defaults) {
body[key](this.defaults[key]);
}
},
/**
* Disables a Game Object's Body. Called when a Group member is removed.
*
* @method Phaser.Physics.Arcade.Group#removeCallbackHandler
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} child - The Game Object being removed.
*/
removeCallbackHandler: function(child) {
if (child.body) {
this.world.disableBody(child);
}
},
/**
* Sets the velocity of each Group member.
*
* @method Phaser.Physics.Arcade.Group#setVelocity
* @since 3.0.0
*
* @param {number} x - The horizontal velocity.
* @param {number} y - The vertical velocity.
* @param {number} [step=0] - The velocity increment. When set, the first member receives velocity (x, y), the second (x + step, y + step), and so on.
*
* @return {Phaser.Physics.Arcade.Group} This Physics Group object.
*/
setVelocity: function(x, y, step) {
if (step === void 0) {
step = 0;
}
var items = this.getChildren();
for (var i = 0; i < items.length; i++) {
items[i].body.velocity.set(x + i * step, y + i * step);
}
return this;
},
/**
* Sets the horizontal velocity of each Group member.
*
* @method Phaser.Physics.Arcade.Group#setVelocityX
* @since 3.0.0
*
* @param {number} value - The velocity value.
* @param {number} [step=0] - The velocity increment. When set, the first member receives velocity (x), the second (x + step), and so on.
*
* @return {Phaser.Physics.Arcade.Group} This Physics Group object.
*/
setVelocityX: function(value, step) {
if (step === void 0) {
step = 0;
}
var items = this.getChildren();
for (var i = 0; i < items.length; i++) {
items[i].body.velocity.x = value + i * step;
}
return this;
},
/**
* Sets the vertical velocity of each Group member.
*
* @method Phaser.Physics.Arcade.Group#setVelocityY
* @since 3.0.0
*
* @param {number} value - The velocity value.
* @param {number} [step=0] - The velocity increment. When set, the first member receives velocity (y), the second (y + step), and so on.
*
* @return {Phaser.Physics.Arcade.Group} This Physics Group object.
*/
setVelocityY: function(value, step) {
if (step === void 0) {
step = 0;
}
var items = this.getChildren();
for (var i = 0; i < items.length; i++) {
items[i].body.velocity.y = value + i * step;
}
return this;
}
});
module2.exports = PhysicsGroup;
}
),
/***/
3017: (
/***/
(module2) => {
var body1;
var body2;
var body1Pushable;
var body2Pushable;
var body1MassImpact;
var body2MassImpact;
var body1FullImpact;
var body2FullImpact;
var body1MovingLeft;
var body1MovingRight;
var body1Stationary;
var body2MovingLeft;
var body2MovingRight;
var body2Stationary;
var body1OnLeft;
var body2OnLeft;
var overlap;
var Set = function(b1, b2, ov) {
body1 = b1;
body2 = b2;
var v1 = body1.velocity.x;
var v2 = body2.velocity.x;
body1Pushable = body1.pushable;
body1MovingLeft = body1._dx < 0;
body1MovingRight = body1._dx > 0;
body1Stationary = body1._dx === 0;
body1OnLeft = Math.abs(body1.right - body2.x) <= Math.abs(body2.right - body1.x);
body1FullImpact = v2 - v1 * body1.bounce.x;
body2Pushable = body2.pushable;
body2MovingLeft = body2._dx < 0;
body2MovingRight = body2._dx > 0;
body2Stationary = body2._dx === 0;
body2OnLeft = !body1OnLeft;
body2FullImpact = v1 - v2 * body2.bounce.x;
overlap = Math.abs(ov);
return BlockCheck();
};
var BlockCheck = function() {
if (body1MovingRight && body1OnLeft && body2.blocked.right) {
body1.processX(-overlap, body1FullImpact, false, true);
return 1;
}
if (body1MovingLeft && body2OnLeft && body2.blocked.left) {
body1.processX(overlap, body1FullImpact, true);
return 1;
}
if (body2MovingRight && body2OnLeft && body1.blocked.right) {
body2.processX(-overlap, body2FullImpact, false, true);
return 2;
}
if (body2MovingLeft && body1OnLeft && body1.blocked.left) {
body2.processX(overlap, body2FullImpact, true);
return 2;
}
return 0;
};
var Check = function() {
var v1 = body1.velocity.x;
var v2 = body2.velocity.x;
var nv1 = Math.sqrt(v2 * v2 * body2.mass / body1.mass) * (v2 > 0 ? 1 : -1);
var nv2 = Math.sqrt(v1 * v1 * body1.mass / body2.mass) * (v1 > 0 ? 1 : -1);
var avg = (nv1 + nv2) * 0.5;
nv1 -= avg;
nv2 -= avg;
body1MassImpact = avg + nv1 * body1.bounce.x;
body2MassImpact = avg + nv2 * body2.bounce.x;
if (body1MovingLeft && body2OnLeft) {
return Run(0);
}
if (body2MovingLeft && body1OnLeft) {
return Run(1);
}
if (body1MovingRight && body1OnLeft) {
return Run(2);
}
if (body2MovingRight && body2OnLeft) {
return Run(3);
}
return false;
};
var Run = function(side) {
if (body1Pushable && body2Pushable) {
overlap *= 0.5;
if (side === 0 || side === 3) {
body1.processX(overlap, body1MassImpact);
body2.processX(-overlap, body2MassImpact);
} else {
body1.processX(-overlap, body1MassImpact);
body2.processX(overlap, body2MassImpact);
}
} else if (body1Pushable && !body2Pushable) {
if (side === 0 || side === 3) {
body1.processX(overlap, body1FullImpact, true);
} else {
body1.processX(-overlap, body1FullImpact, false, true);
}
} else if (!body1Pushable && body2Pushable) {
if (side === 0 || side === 3) {
body2.processX(-overlap, body2FullImpact, false, true);
} else {
body2.processX(overlap, body2FullImpact, true);
}
} else {
var halfOverlap = overlap * 0.5;
if (side === 0) {
if (body2Stationary) {
body1.processX(overlap, 0, true);
body2.processX(0, null, false, true);
} else if (body2MovingRight) {
body1.processX(halfOverlap, 0, true);
body2.processX(-halfOverlap, 0, false, true);
} else {
body1.processX(halfOverlap, body2.velocity.x, true);
body2.processX(-halfOverlap, null, false, true);
}
} else if (side === 1) {
if (body1Stationary) {
body1.processX(0, null, false, true);
body2.processX(overlap, 0, true);
} else if (body1MovingRight) {
body1.processX(-halfOverlap, 0, false, true);
body2.processX(halfOverlap, 0, true);
} else {
body1.processX(-halfOverlap, null, false, true);
body2.processX(halfOverlap, body1.velocity.x, true);
}
} else if (side === 2) {
if (body2Stationary) {
body1.processX(-overlap, 0, false, true);
body2.processX(0, null, true);
} else if (body2MovingLeft) {
body1.processX(-halfOverlap, 0, false, true);
body2.processX(halfOverlap, 0, true);
} else {
body1.processX(-halfOverlap, body2.velocity.x, false, true);
body2.processX(halfOverlap, null, true);
}
} else if (side === 3) {
if (body1Stationary) {
body1.processX(0, null, true);
body2.processX(-overlap, 0, false, true);
} else if (body1MovingLeft) {
body1.processX(halfOverlap, 0, true);
body2.processX(-halfOverlap, 0, false, true);
} else {
body1.processX(halfOverlap, body2.velocity.y, true);
body2.processX(-halfOverlap, null, false, true);
}
}
}
return true;
};
var RunImmovableBody1 = function(blockedState) {
if (blockedState === 1) {
body2.velocity.x = 0;
} else if (body1OnLeft) {
body2.processX(overlap, body2FullImpact, true);
} else {
body2.processX(-overlap, body2FullImpact, false, true);
}
if (body1.moves) {
var body1Distance = body1.directControl ? body1.y - body1.autoFrame.y : body1.y - body1.prev.y;
body2.y += body1Distance * body1.friction.y;
body2._dy = body2.y - body2.prev.y;
}
};
var RunImmovableBody2 = function(blockedState) {
if (blockedState === 2) {
body1.velocity.x = 0;
} else if (body2OnLeft) {
body1.processX(overlap, body1FullImpact, true);
} else {
body1.processX(-overlap, body1FullImpact, false, true);
}
if (body2.moves) {
var body2Distance = body2.directControl ? body2.y - body2.autoFrame.y : body2.y - body2.prev.y;
body1.y += body2Distance * body2.friction.y;
body1._dy = body1.y - body1.prev.y;
}
};
module2.exports = {
BlockCheck,
Check,
Set,
Run,
RunImmovableBody1,
RunImmovableBody2
};
}
),
/***/
47962: (
/***/
(module2) => {
var body1;
var body2;
var body1Pushable;
var body2Pushable;
var body1MassImpact;
var body2MassImpact;
var body1FullImpact;
var body2FullImpact;
var body1MovingUp;
var body1MovingDown;
var body1Stationary;
var body2MovingUp;
var body2MovingDown;
var body2Stationary;
var body1OnTop;
var body2OnTop;
var overlap;
var Set = function(b1, b2, ov) {
body1 = b1;
body2 = b2;
var v1 = body1.velocity.y;
var v2 = body2.velocity.y;
body1Pushable = body1.pushable;
body1MovingUp = body1._dy < 0;
body1MovingDown = body1._dy > 0;
body1Stationary = body1._dy === 0;
body1OnTop = Math.abs(body1.bottom - body2.y) <= Math.abs(body2.bottom - body1.y);
body1FullImpact = v2 - v1 * body1.bounce.y;
body2Pushable = body2.pushable;
body2MovingUp = body2._dy < 0;
body2MovingDown = body2._dy > 0;
body2Stationary = body2._dy === 0;
body2OnTop = !body1OnTop;
body2FullImpact = v1 - v2 * body2.bounce.y;
overlap = Math.abs(ov);
return BlockCheck();
};
var BlockCheck = function() {
if (body1MovingDown && body1OnTop && body2.blocked.down) {
body1.processY(-overlap, body1FullImpact, false, true);
return 1;
}
if (body1MovingUp && body2OnTop && body2.blocked.up) {
body1.processY(overlap, body1FullImpact, true);
return 1;
}
if (body2MovingDown && body2OnTop && body1.blocked.down) {
body2.processY(-overlap, body2FullImpact, false, true);
return 2;
}
if (body2MovingUp && body1OnTop && body1.blocked.up) {
body2.processY(overlap, body2FullImpact, true);
return 2;
}
return 0;
};
var Check = function() {
var v1 = body1.velocity.y;
var v2 = body2.velocity.y;
var nv1 = Math.sqrt(v2 * v2 * body2.mass / body1.mass) * (v2 > 0 ? 1 : -1);
var nv2 = Math.sqrt(v1 * v1 * body1.mass / body2.mass) * (v1 > 0 ? 1 : -1);
var avg = (nv1 + nv2) * 0.5;
nv1 -= avg;
nv2 -= avg;
body1MassImpact = avg + nv1 * body1.bounce.y;
body2MassImpact = avg + nv2 * body2.bounce.y;
if (body1MovingUp && body2OnTop) {
return Run(0);
}
if (body2MovingUp && body1OnTop) {
return Run(1);
}
if (body1MovingDown && body1OnTop) {
return Run(2);
}
if (body2MovingDown && body2OnTop) {
return Run(3);
}
return false;
};
var Run = function(side) {
if (body1Pushable && body2Pushable) {
overlap *= 0.5;
if (side === 0 || side === 3) {
body1.processY(overlap, body1MassImpact);
body2.processY(-overlap, body2MassImpact);
} else {
body1.processY(-overlap, body1MassImpact);
body2.processY(overlap, body2MassImpact);
}
} else if (body1Pushable && !body2Pushable) {
if (side === 0 || side === 3) {
body1.processY(overlap, body1FullImpact, true);
} else {
body1.processY(-overlap, body1FullImpact, false, true);
}
} else if (!body1Pushable && body2Pushable) {
if (side === 0 || side === 3) {
body2.processY(-overlap, body2FullImpact, false, true);
} else {
body2.processY(overlap, body2FullImpact, true);
}
} else {
var halfOverlap = overlap * 0.5;
if (side === 0) {
if (body2Stationary) {
body1.processY(overlap, 0, true);
body2.processY(0, null, false, true);
} else if (body2MovingDown) {
body1.processY(halfOverlap, 0, true);
body2.processY(-halfOverlap, 0, false, true);
} else {
body1.processY(halfOverlap, body2.velocity.y, true);
body2.processY(-halfOverlap, null, false, true);
}
} else if (side === 1) {
if (body1Stationary) {
body1.processY(0, null, false, true);
body2.processY(overlap, 0, true);
} else if (body1MovingDown) {
body1.processY(-halfOverlap, 0, false, true);
body2.processY(halfOverlap, 0, true);
} else {
body1.processY(-halfOverlap, null, false, true);
body2.processY(halfOverlap, body1.velocity.y, true);
}
} else if (side === 2) {
if (body2Stationary) {
body1.processY(-overlap, 0, false, true);
body2.processY(0, null, true);
} else if (body2MovingUp) {
body1.processY(-halfOverlap, 0, false, true);
body2.processY(halfOverlap, 0, true);
} else {
body1.processY(-halfOverlap, body2.velocity.y, false, true);
body2.processY(halfOverlap, null, true);
}
} else if (side === 3) {
if (body1Stationary) {
body1.processY(0, null, true);
body2.processY(-overlap, 0, false, true);
} else if (body1MovingUp) {
body1.processY(halfOverlap, 0, true);
body2.processY(-halfOverlap, 0, false, true);
} else {
body1.processY(halfOverlap, body2.velocity.y, true);
body2.processY(-halfOverlap, null, false, true);
}
}
}
return true;
};
var RunImmovableBody1 = function(blockedState) {
if (blockedState === 1) {
body2.velocity.y = 0;
} else if (body1OnTop) {
body2.processY(overlap, body2FullImpact, true);
} else {
body2.processY(-overlap, body2FullImpact, false, true);
}
if (body1.moves) {
var body1Distance = body1.directControl ? body1.x - body1.autoFrame.x : body1.x - body1.prev.x;
body2.x += body1Distance * body1.friction.x;
body2._dx = body2.x - body2.prev.x;
}
};
var RunImmovableBody2 = function(blockedState) {
if (blockedState === 2) {
body1.velocity.y = 0;
} else if (body2OnTop) {
body1.processY(overlap, body1FullImpact, true);
} else {
body1.processY(-overlap, body1FullImpact, false, true);
}
if (body2.moves) {
var body2Distance = body2.directControl ? body2.x - body2.autoFrame.x : body2.x - body2.prev.x;
body1.x += body2Distance * body2.friction.x;
body1._dx = body1.x - body1.prev.x;
}
};
module2.exports = {
BlockCheck,
Check,
Set,
Run,
RunImmovableBody1,
RunImmovableBody2
};
}
),
/***/
14087: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetOverlapX = __webpack_require__2(64897);
var ProcessX = __webpack_require__2(3017);
var SeparateX = function(body1, body2, overlapOnly, bias, overlap) {
if (overlap === void 0) {
overlap = GetOverlapX(body1, body2, overlapOnly, bias);
}
var body1Immovable = body1.immovable;
var body2Immovable = body2.immovable;
if (overlapOnly || overlap === 0 || body1Immovable && body2Immovable || body1.customSeparateX || body2.customSeparateX) {
return overlap !== 0 || body1.embedded && body2.embedded;
}
var blockedState = ProcessX.Set(body1, body2, overlap);
if (!body1Immovable && !body2Immovable) {
if (blockedState > 0) {
return true;
}
return ProcessX.Check();
} else if (body1Immovable) {
ProcessX.RunImmovableBody1(blockedState);
} else if (body2Immovable) {
ProcessX.RunImmovableBody2(blockedState);
}
return true;
};
module2.exports = SeparateX;
}
),
/***/
89936: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetOverlapY = __webpack_require__2(45170);
var ProcessY = __webpack_require__2(47962);
var SeparateY = function(body1, body2, overlapOnly, bias, overlap) {
if (overlap === void 0) {
overlap = GetOverlapY(body1, body2, overlapOnly, bias);
}
var body1Immovable = body1.immovable;
var body2Immovable = body2.immovable;
if (overlapOnly || overlap === 0 || body1Immovable && body2Immovable || body1.customSeparateY || body2.customSeparateY) {
return overlap !== 0 || body1.embedded && body2.embedded;
}
var blockedState = ProcessY.Set(body1, body2, overlap);
if (!body1Immovable && !body2Immovable) {
if (blockedState > 0) {
return true;
}
return ProcessY.Check();
} else if (body1Immovable) {
ProcessY.RunImmovableBody1(blockedState);
} else if (body2Immovable) {
ProcessY.RunImmovableBody2(blockedState);
}
return true;
};
module2.exports = SeparateY;
}
),
/***/
95829: (
/***/
(module2) => {
var SetCollisionObject = function(noneFlip, data) {
if (data === void 0) {
data = {};
}
data.none = noneFlip;
data.up = false;
data.down = false;
data.left = false;
data.right = false;
if (!noneFlip) {
data.up = true;
data.down = true;
data.left = true;
data.right = true;
}
return data;
};
module2.exports = SetCollisionObject;
}
),
/***/
72624: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CircleContains = __webpack_require__2(87902);
var Class = __webpack_require__2(83419);
var CollisionComponent = __webpack_require__2(78389);
var CONST = __webpack_require__2(37747);
var RectangleContains = __webpack_require__2(37303);
var SetCollisionObject = __webpack_require__2(95829);
var Vector2 = __webpack_require__2(26099);
var StaticBody = new Class({
Mixins: [
CollisionComponent
],
initialize: function StaticBody2(world, gameObject) {
var width = 64;
var height = 64;
var dummyGameObject = {
x: 0,
y: 0,
angle: 0,
rotation: 0,
scaleX: 1,
scaleY: 1,
displayOriginX: 0,
displayOriginY: 0
};
var hasGameObject = gameObject !== void 0;
if (hasGameObject && gameObject.displayWidth) {
width = gameObject.displayWidth;
height = gameObject.displayHeight;
}
if (!hasGameObject) {
gameObject = dummyGameObject;
}
this.world = world;
this.gameObject = hasGameObject ? gameObject : void 0;
this.isBody = true;
this.debugShowBody = world.defaults.debugShowStaticBody;
this.debugBodyColor = world.defaults.staticBodyDebugColor;
this.enable = true;
this.isCircle = false;
this.radius = 0;
this.offset = new Vector2();
this.position = new Vector2(gameObject.x - width * gameObject.originX, gameObject.y - height * gameObject.originY);
this.width = width;
this.height = height;
this.halfWidth = Math.abs(this.width / 2);
this.halfHeight = Math.abs(this.height / 2);
this.center = new Vector2(this.position.x + this.halfWidth, this.position.y + this.halfHeight);
this.velocity = Vector2.ZERO;
this.allowGravity = false;
this.gravity = Vector2.ZERO;
this.bounce = Vector2.ZERO;
this.onWorldBounds = false;
this.onCollide = false;
this.onOverlap = false;
this.mass = 1;
this.immovable = true;
this.pushable = false;
this.customSeparateX = false;
this.customSeparateY = false;
this.overlapX = 0;
this.overlapY = 0;
this.overlapR = 0;
this.embedded = false;
this.collideWorldBounds = false;
this.checkCollision = SetCollisionObject(false);
this.touching = SetCollisionObject(true);
this.wasTouching = SetCollisionObject(true);
this.blocked = SetCollisionObject(true);
this.physicsType = CONST.STATIC_BODY;
this.collisionCategory = 1;
this.collisionMask = 1;
this._dx = 0;
this._dy = 0;
},
/**
* Changes the Game Object this Body is bound to.
* First it removes its reference from the old Game Object, then sets the new one.
* You can optionally update the position and dimensions of this Body to reflect that of the new Game Object.
*
* @method Phaser.Physics.Arcade.StaticBody#setGameObject
* @since 3.1.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The new Game Object that will own this Body.
* @param {boolean} [update=true] - Reposition and resize this Body to match the new Game Object?
*
* @return {Phaser.Physics.Arcade.StaticBody} This Static Body object.
*
* @see Phaser.Physics.Arcade.StaticBody#updateFromGameObject
*/
setGameObject: function(gameObject, update) {
if (gameObject && gameObject !== this.gameObject) {
this.gameObject.body = null;
gameObject.body = this;
this.gameObject = gameObject;
}
if (update) {
this.updateFromGameObject();
}
return this;
},
/**
* Syncs the Static Body's position and size with its parent Game Object.
*
* @method Phaser.Physics.Arcade.StaticBody#updateFromGameObject
* @since 3.1.0
*
* @return {Phaser.Physics.Arcade.StaticBody} This Static Body object.
*/
updateFromGameObject: function() {
this.world.staticTree.remove(this);
var gameObject = this.gameObject;
gameObject.getTopLeft(this.position);
this.width = gameObject.displayWidth;
this.height = gameObject.displayHeight;
this.halfWidth = Math.abs(this.width / 2);
this.halfHeight = Math.abs(this.height / 2);
this.center.set(this.position.x + this.halfWidth, this.position.y + this.halfHeight);
this.world.staticTree.insert(this);
return this;
},
/**
* Positions the Static Body at an offset from its Game Object.
*
* @method Phaser.Physics.Arcade.StaticBody#setOffset
* @since 3.4.0
*
* @param {number} x - The horizontal offset of the Static Body from the Game Object's `x`.
* @param {number} y - The vertical offset of the Static Body from the Game Object's `y`.
*
* @return {Phaser.Physics.Arcade.StaticBody} This Static Body object.
*/
setOffset: function(x, y) {
if (y === void 0) {
y = x;
}
this.world.staticTree.remove(this);
this.position.x -= this.offset.x;
this.position.y -= this.offset.y;
this.offset.set(x, y);
this.position.x += this.offset.x;
this.position.y += this.offset.y;
this.updateCenter();
this.world.staticTree.insert(this);
return this;
},
/**
* Sets the size of the Static Body.
* When `center` is true, also repositions it.
* Resets the width and height to match current frame, if no width and height provided and a frame is found.
*
* @method Phaser.Physics.Arcade.StaticBody#setSize
* @since 3.0.0
*
* @param {number} [width] - The width of the Static Body in pixels. Cannot be zero. If not given, and the parent Game Object has a frame, it will use the frame width.
* @param {number} [height] - The height of the Static Body in pixels. Cannot be zero. If not given, and the parent Game Object has a frame, it will use the frame height.
* @param {boolean} [center=true] - Place the Static Body's center on its Game Object's center. Only works if the Game Object has the `getCenter` method.
*
* @return {Phaser.Physics.Arcade.StaticBody} This Static Body object.
*/
setSize: function(width, height, center) {
if (center === void 0) {
center = true;
}
var gameObject = this.gameObject;
if (gameObject && gameObject.frame) {
if (!width) {
width = gameObject.frame.realWidth;
}
if (!height) {
height = gameObject.frame.realHeight;
}
}
this.world.staticTree.remove(this);
this.width = width;
this.height = height;
this.halfWidth = Math.floor(width / 2);
this.halfHeight = Math.floor(height / 2);
if (center && gameObject && gameObject.getCenter) {
var ox = gameObject.displayWidth / 2;
var oy = gameObject.displayHeight / 2;
this.position.x -= this.offset.x;
this.position.y -= this.offset.y;
this.offset.set(ox - this.halfWidth, oy - this.halfHeight);
this.position.x += this.offset.x;
this.position.y += this.offset.y;
}
this.updateCenter();
this.isCircle = false;
this.radius = 0;
this.world.staticTree.insert(this);
return this;
},
/**
* Sets this Static Body to have a circular body and sets its size and position.
*
* @method Phaser.Physics.Arcade.StaticBody#setCircle
* @since 3.0.0
*
* @param {number} radius - The radius of the StaticBody, in pixels.
* @param {number} [offsetX] - The horizontal offset of the StaticBody from its Game Object, in pixels.
* @param {number} [offsetY] - The vertical offset of the StaticBody from its Game Object, in pixels.
*
* @return {Phaser.Physics.Arcade.StaticBody} This Static Body object.
*/
setCircle: function(radius, offsetX, offsetY) {
if (offsetX === void 0) {
offsetX = this.offset.x;
}
if (offsetY === void 0) {
offsetY = this.offset.y;
}
if (radius > 0) {
this.world.staticTree.remove(this);
this.isCircle = true;
this.radius = radius;
this.width = radius * 2;
this.height = radius * 2;
this.halfWidth = Math.floor(this.width / 2);
this.halfHeight = Math.floor(this.height / 2);
this.offset.set(offsetX, offsetY);
this.updateCenter();
this.world.staticTree.insert(this);
} else {
this.isCircle = false;
}
return this;
},
/**
* Updates the StaticBody's `center` from its `position` and dimensions.
*
* @method Phaser.Physics.Arcade.StaticBody#updateCenter
* @since 3.0.0
*/
updateCenter: function() {
this.center.set(this.position.x + this.halfWidth, this.position.y + this.halfHeight);
},
/**
* Resets this Static Body to its parent Game Object's position.
*
* If `x` and `y` are given, the parent Game Object is placed there and this Static Body is centered on it.
* Otherwise this Static Body is centered on the Game Object's current position.
*
* @method Phaser.Physics.Arcade.StaticBody#reset
* @since 3.0.0
*
* @param {number} [x] - The x coordinate to reset the body to. If not given will use the parent Game Object's coordinate.
* @param {number} [y] - The y coordinate to reset the body to. If not given will use the parent Game Object's coordinate.
*/
reset: function(x, y) {
var gameObject = this.gameObject;
if (x === void 0) {
x = gameObject.x;
}
if (y === void 0) {
y = gameObject.y;
}
this.world.staticTree.remove(this);
gameObject.setPosition(x, y);
gameObject.getTopLeft(this.position);
this.position.x += this.offset.x;
this.position.y += this.offset.y;
this.updateCenter();
this.world.staticTree.insert(this);
},
/**
* NOOP function. A Static Body cannot be stopped.
*
* @method Phaser.Physics.Arcade.StaticBody#stop
* @since 3.0.0
*
* @return {Phaser.Physics.Arcade.StaticBody} This Static Body object.
*/
stop: function() {
return this;
},
/**
* Returns the x and y coordinates of the top left and bottom right points of the StaticBody.
*
* @method Phaser.Physics.Arcade.StaticBody#getBounds
* @since 3.0.0
*
* @param {Phaser.Types.Physics.Arcade.ArcadeBodyBounds} obj - The object which will hold the coordinates of the bounds.
*
* @return {Phaser.Types.Physics.Arcade.ArcadeBodyBounds} The same object that was passed with `x`, `y`, `right` and `bottom` values matching the respective values of the StaticBody.
*/
getBounds: function(obj) {
obj.x = this.x;
obj.y = this.y;
obj.right = this.right;
obj.bottom = this.bottom;
return obj;
},
/**
* Checks to see if a given x,y coordinate is colliding with this Static Body.
*
* @method Phaser.Physics.Arcade.StaticBody#hitTest
* @since 3.0.0
*
* @param {number} x - The x coordinate to check against this body.
* @param {number} y - The y coordinate to check against this body.
*
* @return {boolean} `true` if the given coordinate lies within this body, otherwise `false`.
*/
hitTest: function(x, y) {
return this.isCircle ? CircleContains(this, x, y) : RectangleContains(this, x, y);
},
/**
* NOOP
*
* @method Phaser.Physics.Arcade.StaticBody#postUpdate
* @since 3.12.0
*/
postUpdate: function() {
},
/**
* The absolute (non-negative) change in this StaticBody's horizontal position from the previous step. Always zero.
*
* @method Phaser.Physics.Arcade.StaticBody#deltaAbsX
* @since 3.0.0
*
* @return {number} Always zero for a Static Body.
*/
deltaAbsX: function() {
return 0;
},
/**
* The absolute (non-negative) change in this StaticBody's vertical position from the previous step. Always zero.
*
* @method Phaser.Physics.Arcade.StaticBody#deltaAbsY
* @since 3.0.0
*
* @return {number} Always zero for a Static Body.
*/
deltaAbsY: function() {
return 0;
},
/**
* The change in this StaticBody's horizontal position from the previous step. Always zero.
*
* @method Phaser.Physics.Arcade.StaticBody#deltaX
* @since 3.0.0
*
* @return {number} The change in this StaticBody's velocity from the previous step. Always zero.
*/
deltaX: function() {
return 0;
},
/**
* The change in this StaticBody's vertical position from the previous step. Always zero.
*
* @method Phaser.Physics.Arcade.StaticBody#deltaY
* @since 3.0.0
*
* @return {number} The change in this StaticBody's velocity from the previous step. Always zero.
*/
deltaY: function() {
return 0;
},
/**
* The change in this StaticBody's rotation from the previous step. Always zero.
*
* @method Phaser.Physics.Arcade.StaticBody#deltaZ
* @since 3.0.0
*
* @return {number} The change in this StaticBody's rotation from the previous step. Always zero.
*/
deltaZ: function() {
return 0;
},
/**
* Disables this Body and marks it for destruction during the next step.
*
* @method Phaser.Physics.Arcade.StaticBody#destroy
* @since 3.0.0
*/
destroy: function() {
this.enable = false;
this.world.pendingDestroy.set(this);
},
/**
* Draws a graphical representation of the StaticBody for visual debugging purposes.
*
* @method Phaser.Physics.Arcade.StaticBody#drawDebug
* @since 3.0.0
*
* @param {Phaser.GameObjects.Graphics} graphic - The Graphics object to use for the debug drawing of the StaticBody.
*/
drawDebug: function(graphic) {
var pos = this.position;
var x = pos.x + this.halfWidth;
var y = pos.y + this.halfHeight;
if (this.debugShowBody) {
graphic.lineStyle(graphic.defaultStrokeWidth, this.debugBodyColor, 1);
if (this.isCircle) {
graphic.strokeCircle(x, y, this.width / 2);
} else {
graphic.strokeRect(pos.x, pos.y, this.width, this.height);
}
}
},
/**
* Indicates whether the StaticBody is going to be showing a debug visualization during postUpdate.
*
* @method Phaser.Physics.Arcade.StaticBody#willDrawDebug
* @since 3.0.0
*
* @return {boolean} Whether or not the StaticBody is going to show the debug visualization during postUpdate.
*/
willDrawDebug: function() {
return this.debugShowBody;
},
/**
* Sets the Mass of the StaticBody. Will set the Mass to 0.1 if the value passed is less than or equal to zero.
*
* @method Phaser.Physics.Arcade.StaticBody#setMass
* @since 3.0.0
*
* @param {number} value - The value to set the Mass to. Values of zero or less are changed to 0.1.
*
* @return {Phaser.Physics.Arcade.StaticBody} This Static Body object.
*/
setMass: function(value) {
if (value <= 0) {
value = 0.1;
}
this.mass = value;
return this;
},
/**
* The x coordinate of the StaticBody.
*
* @name Phaser.Physics.Arcade.StaticBody#x
* @type {number}
* @since 3.0.0
*/
x: {
get: function() {
return this.position.x;
},
set: function(value) {
this.world.staticTree.remove(this);
this.position.x = value;
this.world.staticTree.insert(this);
}
},
/**
* The y coordinate of the StaticBody.
*
* @name Phaser.Physics.Arcade.StaticBody#y
* @type {number}
* @since 3.0.0
*/
y: {
get: function() {
return this.position.y;
},
set: function(value) {
this.world.staticTree.remove(this);
this.position.y = value;
this.world.staticTree.insert(this);
}
},
/**
* Returns the left-most x coordinate of the area of the StaticBody.
*
* @name Phaser.Physics.Arcade.StaticBody#left
* @type {number}
* @readonly
* @since 3.0.0
*/
left: {
get: function() {
return this.position.x;
}
},
/**
* The right-most x coordinate of the area of the StaticBody.
*
* @name Phaser.Physics.Arcade.StaticBody#right
* @type {number}
* @readonly
* @since 3.0.0
*/
right: {
get: function() {
return this.position.x + this.width;
}
},
/**
* The highest y coordinate of the area of the StaticBody.
*
* @name Phaser.Physics.Arcade.StaticBody#top
* @type {number}
* @readonly
* @since 3.0.0
*/
top: {
get: function() {
return this.position.y;
}
},
/**
* The lowest y coordinate of the area of the StaticBody. (y + height)
*
* @name Phaser.Physics.Arcade.StaticBody#bottom
* @type {number}
* @readonly
* @since 3.0.0
*/
bottom: {
get: function() {
return this.position.y + this.height;
}
}
});
module2.exports = StaticBody;
}
),
/***/
71464: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var ArcadeSprite = __webpack_require__2(13759);
var Class = __webpack_require__2(83419);
var CollisionComponent = __webpack_require__2(78389);
var CONST = __webpack_require__2(37747);
var GetFastValue = __webpack_require__2(95540);
var Group = __webpack_require__2(26479);
var IsPlainObject = __webpack_require__2(41212);
var StaticPhysicsGroup = new Class({
Extends: Group,
Mixins: [
CollisionComponent
],
initialize: function StaticPhysicsGroup2(world, scene, children, config) {
if (!children && !config) {
config = {
internalCreateCallback: this.createCallbackHandler,
internalRemoveCallback: this.removeCallbackHandler,
createMultipleCallback: this.createMultipleCallbackHandler,
classType: ArcadeSprite
};
} else if (IsPlainObject(children)) {
config = children;
children = null;
config.internalCreateCallback = this.createCallbackHandler;
config.internalRemoveCallback = this.removeCallbackHandler;
config.createMultipleCallback = this.createMultipleCallbackHandler;
config.classType = GetFastValue(config, "classType", ArcadeSprite);
} else if (Array.isArray(children) && IsPlainObject(children[0])) {
config = children;
children = null;
config.forEach(function(singleConfig) {
singleConfig.internalCreateCallback = this.createCallbackHandler;
singleConfig.internalRemoveCallback = this.removeCallbackHandler;
singleConfig.createMultipleCallback = this.createMultipleCallbackHandler;
singleConfig.classType = GetFastValue(singleConfig, "classType", ArcadeSprite);
});
} else {
config = {
internalCreateCallback: this.createCallbackHandler,
internalRemoveCallback: this.removeCallbackHandler
};
}
this.world = world;
this.physicsType = CONST.STATIC_BODY;
this.collisionCategory = 1;
this.collisionMask = 1;
Group.call(this, scene, children, config);
this.type = "StaticPhysicsGroup";
},
/**
* Adds a static physics body to the new group member (if it lacks one) and adds it to the simulation.
*
* @method Phaser.Physics.Arcade.StaticGroup#createCallbackHandler
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} child - The new group member.
*
* @see Phaser.Physics.Arcade.World#enableBody
*/
createCallbackHandler: function(child) {
if (!child.body) {
this.world.enableBody(child, CONST.STATIC_BODY);
}
},
/**
* Disables the group member's physics body, removing it from the simulation.
*
* @method Phaser.Physics.Arcade.StaticGroup#removeCallbackHandler
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} child - The group member being removed.
*
* @see Phaser.Physics.Arcade.World#disableBody
*/
removeCallbackHandler: function(child) {
if (child.body) {
this.world.disableBody(child);
}
},
/**
* Refreshes the group.
*
* @method Phaser.Physics.Arcade.StaticGroup#createMultipleCallbackHandler
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject[]} entries - The newly created group members.
*
* @see Phaser.Physics.Arcade.StaticGroup#refresh
*/
createMultipleCallbackHandler: function() {
this.refresh();
},
/**
* Resets each Body to the position of its parent Game Object.
* Body sizes aren't changed (use {@link Phaser.Physics.Arcade.Components.Enable#refreshBody} for that).
*
* @method Phaser.Physics.Arcade.StaticGroup#refresh
* @since 3.0.0
*
* @return {Phaser.Physics.Arcade.StaticGroup} This group.
*
* @see Phaser.Physics.Arcade.StaticBody#reset
*/
refresh: function() {
var children = this.children.entries;
for (var i = 0; i < children.length; i++) {
children[i].body.reset();
}
return this;
}
});
module2.exports = StaticPhysicsGroup;
}
),
/***/
82248: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var AngleBetweenPoints = __webpack_require__2(55495);
var Body = __webpack_require__2(37742);
var Clamp = __webpack_require__2(45319);
var Class = __webpack_require__2(83419);
var Collider = __webpack_require__2(79342);
var CONST = __webpack_require__2(37747);
var DistanceBetween = __webpack_require__2(20339);
var DistanceBetweenPoints = __webpack_require__2(52816);
var EventEmitter = __webpack_require__2(50792);
var Events = __webpack_require__2(63012);
var FuzzyEqual = __webpack_require__2(43855);
var FuzzyGreaterThan = __webpack_require__2(5470);
var FuzzyLessThan = __webpack_require__2(94977);
var GetOverlapX = __webpack_require__2(64897);
var GetOverlapY = __webpack_require__2(45170);
var GetTilesWithinWorldXY = __webpack_require__2(96523);
var GetValue = __webpack_require__2(35154);
var MATH_CONST = __webpack_require__2(36383);
var ProcessQueue = __webpack_require__2(25774);
var ProcessTileCallbacks = __webpack_require__2(96602);
var Rectangle = __webpack_require__2(87841);
var RTree = __webpack_require__2(59542);
var SeparateTile = __webpack_require__2(40012);
var SeparateX = __webpack_require__2(14087);
var SeparateY = __webpack_require__2(89936);
var Set = __webpack_require__2(35072);
var StaticBody = __webpack_require__2(72624);
var TileIntersectsBody = __webpack_require__2(2483);
var TransformMatrix = __webpack_require__2(61340);
var Vector2 = __webpack_require__2(26099);
var Wrap = __webpack_require__2(15994);
var World = new Class({
Extends: EventEmitter,
initialize: function World2(scene, config) {
EventEmitter.call(this);
this.scene = scene;
this.bodies = new Set();
this.staticBodies = new Set();
this.pendingDestroy = new Set();
this.colliders = new ProcessQueue();
this.gravity = new Vector2(GetValue(config, "gravity.x", 0), GetValue(config, "gravity.y", 0));
this.bounds = new Rectangle(
GetValue(config, "x", 0),
GetValue(config, "y", 0),
GetValue(config, "width", scene.sys.scale.width),
GetValue(config, "height", scene.sys.scale.height)
);
this.checkCollision = {
up: GetValue(config, "checkCollision.up", true),
down: GetValue(config, "checkCollision.down", true),
left: GetValue(config, "checkCollision.left", true),
right: GetValue(config, "checkCollision.right", true)
};
this.fps = GetValue(config, "fps", 60);
this.fixedStep = GetValue(config, "fixedStep", true);
this._elapsed = 0;
this._frameTime = 1 / this.fps;
this._frameTimeMS = 1e3 * this._frameTime;
this.stepsLastFrame = 0;
this.timeScale = GetValue(config, "timeScale", 1);
this.OVERLAP_BIAS = GetValue(config, "overlapBias", 4);
this.TILE_BIAS = GetValue(config, "tileBias", 16);
this.forceX = GetValue(config, "forceX", false);
this.isPaused = GetValue(config, "isPaused", false);
this._total = 0;
this.drawDebug = GetValue(config, "debug", false);
this.debugGraphic;
this.defaults = {
debugShowBody: GetValue(config, "debugShowBody", true),
debugShowStaticBody: GetValue(config, "debugShowStaticBody", true),
debugShowVelocity: GetValue(config, "debugShowVelocity", true),
bodyDebugColor: GetValue(config, "debugBodyColor", 16711935),
staticBodyDebugColor: GetValue(config, "debugStaticBodyColor", 255),
velocityDebugColor: GetValue(config, "debugVelocityColor", 65280)
};
this.maxEntries = GetValue(config, "maxEntries", 16);
this.useTree = GetValue(config, "useTree", true);
this.tree = new RTree(this.maxEntries);
this.staticTree = new RTree(this.maxEntries);
this.treeMinMax = { minX: 0, minY: 0, maxX: 0, maxY: 0 };
this._tempMatrix = new TransformMatrix();
this._tempMatrix2 = new TransformMatrix();
this.tileFilterOptions = { isColliding: true, isNotEmpty: true, hasInterestingFace: true };
if (this.drawDebug) {
this.createDebugGraphic();
}
},
/**
* Adds an Arcade Physics Body to a Game Object, an array of Game Objects, or the children of a Group.
*
* The difference between this and the `enableBody` method is that you can pass arrays or Groups
* to this method.
*
* You can specify if the bodies are to be Dynamic or Static. A dynamic body can move via velocity and
* acceleration. A static body remains fixed in place and as such is able to use an optimized search
* tree, making it ideal for static elements such as level objects. You can still collide and overlap
* with static bodies.
*
* Normally, rather than calling this method directly, you'd use the helper methods available in the
* Arcade Physics Factory, such as:
*
* ```javascript
* this.physics.add.image(x, y, textureKey);
* this.physics.add.sprite(x, y, textureKey);
* ```
*
* Calling factory methods encapsulates the creation of a Game Object and the creation of its
* body at the same time. If you are creating custom classes then you can pass them to this
* method to have their bodies created.
*
* @method Phaser.Physics.Arcade.World#enable
* @since 3.0.0
*
* @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object - The object, or objects, on which to create the bodies.
* @param {number} [bodyType] - The type of Body to create. Either `DYNAMIC_BODY` or `STATIC_BODY`.
*/
enable: function(object, bodyType) {
if (bodyType === void 0) {
bodyType = CONST.DYNAMIC_BODY;
}
if (!Array.isArray(object)) {
object = [object];
}
for (var i = 0; i < object.length; i++) {
var entry = object[i];
if (entry.isParent) {
var children = entry.getChildren();
for (var c = 0; c < children.length; c++) {
var child = children[c];
if (child.isParent) {
this.enable(child, bodyType);
} else {
this.enableBody(child, bodyType);
}
}
} else {
this.enableBody(entry, bodyType);
}
}
},
/**
* Creates an Arcade Physics Body on a single Game Object.
*
* If the Game Object already has a body, this method will simply add it back into the simulation.
*
* You can specify if the body is Dynamic or Static. A dynamic body can move via velocity and
* acceleration. A static body remains fixed in place and as such is able to use an optimized search
* tree, making it ideal for static elements such as level objects. You can still collide and overlap
* with static bodies.
*
* Normally, rather than calling this method directly, you'd use the helper methods available in the
* Arcade Physics Factory, such as:
*
* ```javascript
* this.physics.add.image(x, y, textureKey);
* this.physics.add.sprite(x, y, textureKey);
* ```
*
* Calling factory methods encapsulates the creation of a Game Object and the creation of its
* body at the same time. If you are creating custom classes then you can pass them to this
* method to have their bodies created.
*
* @method Phaser.Physics.Arcade.World#enableBody
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} object - The Game Object on which to create the body.
* @param {number} [bodyType] - The type of Body to create. Either `DYNAMIC_BODY` or `STATIC_BODY`.
*
* @return {Phaser.GameObjects.GameObject} The Game Object on which the body was created.
*/
enableBody: function(object, bodyType) {
if (bodyType === void 0) {
bodyType = CONST.DYNAMIC_BODY;
}
if (object.hasTransformComponent) {
if (!object.body) {
if (bodyType === CONST.DYNAMIC_BODY) {
object.body = new Body(this, object);
} else if (bodyType === CONST.STATIC_BODY) {
object.body = new StaticBody(this, object);
}
}
this.add(object.body);
}
return object;
},
/**
* Adds an existing Arcade Physics Body or StaticBody to the simulation.
*
* The body is enabled and added to the local search trees.
*
* @method Phaser.Physics.Arcade.World#add
* @since 3.10.0
*
* @param {(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} body - The Body to be added to the simulation.
*
* @return {(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} The Body that was added to the simulation.
*/
add: function(body) {
if (body.physicsType === CONST.DYNAMIC_BODY) {
this.bodies.set(body);
} else if (body.physicsType === CONST.STATIC_BODY) {
this.staticBodies.set(body);
this.staticTree.insert(body);
}
body.enable = true;
return body;
},
/**
* Disables the Arcade Physics Body of a Game Object, an array of Game Objects, or the children of a Group.
*
* The difference between this and the `disableBody` method is that you can pass arrays or Groups
* to this method.
*
* The body itself is not deleted, it just has its `enable` property set to false, which
* means you can re-enable it again at any point by passing it to enable `World.enable` or `World.add`.
*
* @method Phaser.Physics.Arcade.World#disable
* @since 3.0.0
*
* @param {(Phaser.GameObjects.GameObject|Phaser.GameObjects.GameObject[]|Phaser.GameObjects.Group|Phaser.GameObjects.Group[])} object - The object, or objects, on which to disable the bodies.
*/
disable: function(object) {
if (!Array.isArray(object)) {
object = [object];
}
for (var i = 0; i < object.length; i++) {
var entry = object[i];
if (entry.isParent) {
var children = entry.getChildren();
for (var c = 0; c < children.length; c++) {
var child = children[c];
if (child.isParent) {
this.disable(child);
} else {
this.disableBody(child.body);
}
}
} else {
this.disableBody(entry.body);
}
}
},
/**
* Disables an existing Arcade Physics Body or StaticBody and removes it from the simulation.
*
* The body is disabled and removed from the local search trees.
*
* The body itself is not deleted, it just has its `enable` property set to false, which
* means you can re-enable it again at any point by passing it to enable `World.enable` or `World.add`.
*
* @method Phaser.Physics.Arcade.World#disableBody
* @since 3.0.0
*
* @param {(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} body - The Body to be disabled.
*/
disableBody: function(body) {
this.remove(body);
body.enable = false;
},
/**
* Removes an existing Arcade Physics Body or StaticBody from the simulation.
*
* The body is disabled and removed from the local search trees.
*
* The body itself is not deleted, it just has its `enabled` property set to false, which
* means you can re-enable it again at any point by passing it to enable `enable` or `add`.
*
* @method Phaser.Physics.Arcade.World#remove
* @since 3.0.0
*
* @param {(Phaser.Physics.Arcade.Body|Phaser.Physics.Arcade.StaticBody)} body - The body to be removed from the simulation.
*/
remove: function(body) {
if (body.physicsType === CONST.DYNAMIC_BODY) {
this.tree.remove(body);
this.bodies.delete(body);
} else if (body.physicsType === CONST.STATIC_BODY) {
this.staticBodies.delete(body);
this.staticTree.remove(body);
}
},
/**
* Creates a Graphics Game Object that the world will use to render the debug display to.
*
* This is called automatically when the World is instantiated if the `debug` config property
* was set to `true`. However, you can call it at any point should you need to display the
* debug Graphic from a fixed point.
*
* You can control which objects are drawn to the Graphics object, and the colors they use,
* by setting the debug properties in the physics config.
*
* You should not typically use this in a production game. Use it to aid during debugging.
*
* @method Phaser.Physics.Arcade.World#createDebugGraphic
* @since 3.0.0
*
* @return {Phaser.GameObjects.Graphics} The Graphics object that was created for use by the World.
*/
createDebugGraphic: function() {
var graphic = this.scene.sys.add.graphics({ x: 0, y: 0 });
graphic.setDepth(Number.MAX_VALUE);
this.debugGraphic = graphic;
this.drawDebug = true;
return graphic;
},
/**
* Sets the position, size and properties of the World boundary.
*
* The World boundary is an invisible rectangle that defines the edges of the World.
* If a Body is set to collide with the world bounds then it will automatically stop
* when it reaches any of the edges. You can optionally set which edges of the boundary
* should be checked against.
*
* @method Phaser.Physics.Arcade.World#setBounds
* @since 3.0.0
*
* @param {number} x - The top-left x coordinate of the boundary.
* @param {number} y - The top-left y coordinate of the boundary.
* @param {number} width - The width of the boundary.
* @param {number} height - The height of the boundary.
* @param {boolean} [checkLeft] - Should bodies check against the left edge of the boundary?
* @param {boolean} [checkRight] - Should bodies check against the right edge of the boundary?
* @param {boolean} [checkUp] - Should bodies check against the top edge of the boundary?
* @param {boolean} [checkDown] - Should bodies check against the bottom edge of the boundary?
*
* @return {Phaser.Physics.Arcade.World} This World object.
*/
setBounds: function(x, y, width, height, checkLeft, checkRight, checkUp, checkDown) {
this.bounds.setTo(x, y, width, height);
if (checkLeft !== void 0) {
this.setBoundsCollision(checkLeft, checkRight, checkUp, checkDown);
}
return this;
},
/**
* Enables or disables collisions on each edge of the World boundary.
*
* @method Phaser.Physics.Arcade.World#setBoundsCollision
* @since 3.0.0
*
* @param {boolean} [left=true] - Should bodies check against the left edge of the boundary?
* @param {boolean} [right=true] - Should bodies check against the right edge of the boundary?
* @param {boolean} [up=true] - Should bodies check against the top edge of the boundary?
* @param {boolean} [down=true] - Should bodies check against the bottom edge of the boundary?
*
* @return {Phaser.Physics.Arcade.World} This World object.
*/
setBoundsCollision: function(left, right, up, down) {
if (left === void 0) {
left = true;
}
if (right === void 0) {
right = true;
}
if (up === void 0) {
up = true;
}
if (down === void 0) {
down = true;
}
this.checkCollision.left = left;
this.checkCollision.right = right;
this.checkCollision.up = up;
this.checkCollision.down = down;
return this;
},
/**
* Pauses the simulation.
*
* A paused simulation does not update any existing bodies, or run any Colliders.
*
* However, you can still enable and disable bodies within it, or manually run collide or overlap
* checks.
*
* @method Phaser.Physics.Arcade.World#pause
* @fires Phaser.Physics.Arcade.Events#PAUSE
* @since 3.0.0
*
* @return {Phaser.Physics.Arcade.World} This World object.
*/
pause: function() {
this.isPaused = true;
this.emit(Events.PAUSE);
return this;
},
/**
* Resumes the simulation, if paused.
*
* @method Phaser.Physics.Arcade.World#resume
* @fires Phaser.Physics.Arcade.Events#RESUME
* @since 3.0.0
*
* @return {Phaser.Physics.Arcade.World} This World object.
*/
resume: function() {
this.isPaused = false;
this.emit(Events.RESUME);
return this;
},
/**
* Creates a new Collider object and adds it to the simulation.
*
* A Collider is a way to automatically perform collision checks between two objects,
* calling the collide and process callbacks if they occur.
*
* Colliders are run as part of the World update, after all of the Bodies have updated.
*
* By creating a Collider you don't need then call `World.collide` in your `update` loop,
* as it will be handled for you automatically.
*
* @method Phaser.Physics.Arcade.World#addCollider
* @since 3.0.0
* @see Phaser.Physics.Arcade.World#collide
*
* @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object to check for collision.
* @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object2 - The second object to check for collision.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - The callback to invoke when the two objects collide.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [processCallback] - The callback to invoke when the two objects collide. Must return a boolean.
* @param {*} [callbackContext] - The scope in which to call the callbacks.
*
* @return {Phaser.Physics.Arcade.Collider} The Collider that was created.
*/
addCollider: function(object1, object2, collideCallback, processCallback, callbackContext) {
if (collideCallback === void 0) {
collideCallback = null;
}
if (processCallback === void 0) {
processCallback = null;
}
if (callbackContext === void 0) {
callbackContext = collideCallback;
}
var collider = new Collider(this, false, object1, object2, collideCallback, processCallback, callbackContext);
this.colliders.add(collider);
return collider;
},
/**
* Creates a new Overlap Collider object and adds it to the simulation.
*
* A Collider is a way to automatically perform overlap checks between two objects,
* calling the collide and process callbacks if they occur.
*
* Colliders are run as part of the World update, after all of the Bodies have updated.
*
* By creating a Collider you don't need then call `World.overlap` in your `update` loop,
* as it will be handled for you automatically.
*
* @method Phaser.Physics.Arcade.World#addOverlap
* @since 3.0.0
*
* @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object to check for overlap.
* @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object2 - The second object to check for overlap.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - The callback to invoke when the two objects overlap.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [processCallback] - The callback to invoke when the two objects overlap. Must return a boolean.
* @param {*} [callbackContext] - The scope in which to call the callbacks.
*
* @return {Phaser.Physics.Arcade.Collider} The Collider that was created.
*/
addOverlap: function(object1, object2, collideCallback, processCallback, callbackContext) {
if (collideCallback === void 0) {
collideCallback = null;
}
if (processCallback === void 0) {
processCallback = null;
}
if (callbackContext === void 0) {
callbackContext = collideCallback;
}
var collider = new Collider(this, true, object1, object2, collideCallback, processCallback, callbackContext);
this.colliders.add(collider);
return collider;
},
/**
* Removes a Collider from the simulation so it is no longer processed.
*
* This method does not destroy the Collider. If you wish to add it back at a later stage you can call
* `World.colliders.add(Collider)`.
*
* If you no longer need the Collider you can call the `Collider.destroy` method instead, which will
* automatically clear all of its references and then remove it from the World. If you call destroy on
* a Collider you _don't_ need to pass it to this method too.
*
* @method Phaser.Physics.Arcade.World#removeCollider
* @since 3.0.0
*
* @param {Phaser.Physics.Arcade.Collider} collider - The Collider to remove from the simulation.
*
* @return {Phaser.Physics.Arcade.World} This World object.
*/
removeCollider: function(collider) {
this.colliders.remove(collider);
return this;
},
/**
* Sets the frame rate to run the simulation at.
*
* The frame rate value is used to simulate a fixed update time step. This fixed
* time step allows for a straightforward implementation of a deterministic game state.
*
* This frame rate is independent of the frequency at which the game is rendering. The
* higher you set the fps, the more physics simulation steps will occur per game step.
* Conversely, the lower you set it, the less will take place.
*
* You can optionally advance the simulation directly yourself by calling the `step` method.
*
* @method Phaser.Physics.Arcade.World#setFPS
* @since 3.10.0
*
* @param {number} framerate - The frame rate to advance the simulation at.
*
* @return {this} This World object.
*/
setFPS: function(framerate) {
this.fps = framerate;
this._frameTime = 1 / this.fps;
this._frameTimeMS = 1e3 * this._frameTime;
return this;
},
/**
* Advances the simulation based on the elapsed time and fps rate.
*
* This is called automatically by your Scene and does not need to be invoked directly.
*
* @method Phaser.Physics.Arcade.World#update
* @fires Phaser.Physics.Arcade.Events#WORLD_STEP
* @since 3.0.0
*
* @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout.
* @param {number} delta - The delta time, in ms, elapsed since the last frame.
*/
update: function(time, delta) {
if (this.isPaused || this.bodies.size === 0) {
return;
}
var i;
var fixedDelta = this._frameTime;
var msPerFrame = this._frameTimeMS * this.timeScale;
this._elapsed += delta;
var body;
var bodies = this.bodies.entries;
var willStep = this._elapsed >= msPerFrame;
if (!this.fixedStep) {
fixedDelta = delta * 1e-3;
willStep = true;
this._elapsed = 0;
}
for (i = 0; i < bodies.length; i++) {
body = bodies[i];
if (body.enable) {
body.preUpdate(willStep, fixedDelta);
}
}
if (willStep) {
this._elapsed -= msPerFrame;
this.stepsLastFrame = 1;
if (this.useTree) {
this.tree.clear();
this.tree.load(bodies);
}
var colliders = this.colliders.update();
for (i = 0; i < colliders.length; i++) {
var collider = colliders[i];
if (collider.active) {
collider.update();
}
}
this.emit(Events.WORLD_STEP, fixedDelta);
}
while (this._elapsed >= msPerFrame) {
this._elapsed -= msPerFrame;
this.step(fixedDelta);
}
},
/**
* Advances the simulation by a time increment.
*
* @method Phaser.Physics.Arcade.World#step
* @fires Phaser.Physics.Arcade.Events#WORLD_STEP
* @since 3.10.0
*
* @param {number} delta - The delta time amount, in seconds, by which to advance the simulation.
*/
step: function(delta) {
var i;
var body;
var bodies = this.bodies.entries;
var len = bodies.length;
for (i = 0; i < len; i++) {
body = bodies[i];
if (body.enable) {
body.update(delta);
}
}
if (this.useTree) {
this.tree.clear();
this.tree.load(bodies);
}
var colliders = this.colliders.update();
for (i = 0; i < colliders.length; i++) {
var collider = colliders[i];
if (collider.active) {
collider.update();
}
}
this.emit(Events.WORLD_STEP, delta);
this.stepsLastFrame++;
},
/**
* Advances the simulation by a single step.
*
* @method Phaser.Physics.Arcade.World#singleStep
* @fires Phaser.Physics.Arcade.Events#WORLD_STEP
* @since 3.70.0
*/
singleStep: function() {
this.update(0, this._frameTimeMS);
this.postUpdate();
},
/**
* Updates bodies, draws the debug display, and handles pending queue operations.
*
* @method Phaser.Physics.Arcade.World#postUpdate
* @since 3.0.0
*/
postUpdate: function() {
var i;
var body;
var bodies = this.bodies.entries;
var len = bodies.length;
var dynamic = this.bodies;
var staticBodies = this.staticBodies;
if (this.stepsLastFrame) {
this.stepsLastFrame = 0;
for (i = 0; i < len; i++) {
body = bodies[i];
if (body.enable) {
body.postUpdate();
}
}
}
if (this.drawDebug) {
var graphics = this.debugGraphic;
graphics.clear();
for (i = 0; i < len; i++) {
body = bodies[i];
if (body.willDrawDebug()) {
body.drawDebug(graphics);
}
}
bodies = staticBodies.entries;
len = bodies.length;
for (i = 0; i < len; i++) {
body = bodies[i];
if (body.willDrawDebug()) {
body.drawDebug(graphics);
}
}
}
var pending = this.pendingDestroy;
if (pending.size > 0) {
var dynamicTree = this.tree;
var staticTree = this.staticTree;
bodies = pending.entries;
len = bodies.length;
for (i = 0; i < len; i++) {
body = bodies[i];
if (body.physicsType === CONST.DYNAMIC_BODY) {
dynamicTree.remove(body);
dynamic.delete(body);
} else if (body.physicsType === CONST.STATIC_BODY) {
staticTree.remove(body);
staticBodies.delete(body);
}
body.world = void 0;
body.gameObject = void 0;
}
pending.clear();
}
},
/**
* Calculates a Body's velocity and updates its position.
*
* @method Phaser.Physics.Arcade.World#updateMotion
* @since 3.0.0
*
* @param {Phaser.Physics.Arcade.Body} body - The Body to be updated.
* @param {number} delta - The delta value to be used in the motion calculations, in seconds.
*/
updateMotion: function(body, delta) {
if (body.allowRotation) {
this.computeAngularVelocity(body, delta);
}
this.computeVelocity(body, delta);
},
/**
* Calculates a Body's angular velocity.
*
* @method Phaser.Physics.Arcade.World#computeAngularVelocity
* @since 3.10.0
*
* @param {Phaser.Physics.Arcade.Body} body - The Body to compute the velocity for.
* @param {number} delta - The delta value to be used in the calculation, in seconds.
*/
computeAngularVelocity: function(body, delta) {
var velocity = body.angularVelocity;
var acceleration = body.angularAcceleration;
var drag = body.angularDrag;
var max = body.maxAngular;
if (acceleration) {
velocity += acceleration * delta;
} else if (body.allowDrag && drag) {
drag *= delta;
if (FuzzyGreaterThan(velocity - drag, 0, 0.1)) {
velocity -= drag;
} else if (FuzzyLessThan(velocity + drag, 0, 0.1)) {
velocity += drag;
} else {
velocity = 0;
}
}
velocity = Clamp(velocity, -max, max);
var velocityDelta = velocity - body.angularVelocity;
body.angularVelocity += velocityDelta;
body.rotation += body.angularVelocity * delta;
},
/**
* Calculates a Body's per-axis velocity.
*
* @method Phaser.Physics.Arcade.World#computeVelocity
* @since 3.0.0
*
* @param {Phaser.Physics.Arcade.Body} body - The Body to compute the velocity for.
* @param {number} delta - The delta value to be used in the calculation, in seconds.
*/
computeVelocity: function(body, delta) {
var velocityX = body.velocity.x;
var accelerationX = body.acceleration.x;
var dragX = body.drag.x;
var maxX = body.maxVelocity.x;
var velocityY = body.velocity.y;
var accelerationY = body.acceleration.y;
var dragY = body.drag.y;
var maxY = body.maxVelocity.y;
var speed = body.speed;
var maxSpeed = body.maxSpeed;
var allowDrag = body.allowDrag;
var useDamping = body.useDamping;
if (body.allowGravity) {
velocityX += (this.gravity.x + body.gravity.x) * delta;
velocityY += (this.gravity.y + body.gravity.y) * delta;
}
if (accelerationX) {
velocityX += accelerationX * delta;
} else if (allowDrag && dragX) {
if (useDamping) {
dragX = Math.pow(dragX, delta);
velocityX *= dragX;
speed = Math.sqrt(velocityX * velocityX + velocityY * velocityY);
if (FuzzyEqual(speed, 0, 1e-3)) {
velocityX = 0;
}
} else {
dragX *= delta;
if (FuzzyGreaterThan(velocityX - dragX, 0, 0.01)) {
velocityX -= dragX;
} else if (FuzzyLessThan(velocityX + dragX, 0, 0.01)) {
velocityX += dragX;
} else {
velocityX = 0;
}
}
}
if (accelerationY) {
velocityY += accelerationY * delta;
} else if (allowDrag && dragY) {
if (useDamping) {
dragY = Math.pow(dragY, delta);
velocityY *= dragY;
speed = Math.sqrt(velocityX * velocityX + velocityY * velocityY);
if (FuzzyEqual(speed, 0, 1e-3)) {
velocityY = 0;
}
} else {
dragY *= delta;
if (FuzzyGreaterThan(velocityY - dragY, 0, 0.01)) {
velocityY -= dragY;
} else if (FuzzyLessThan(velocityY + dragY, 0, 0.01)) {
velocityY += dragY;
} else {
velocityY = 0;
}
}
}
velocityX = Clamp(velocityX, -maxX, maxX);
velocityY = Clamp(velocityY, -maxY, maxY);
body.velocity.set(velocityX, velocityY);
if (maxSpeed > -1 && body.velocity.length() > maxSpeed) {
body.velocity.normalize().scale(maxSpeed);
speed = maxSpeed;
}
body.speed = speed;
},
/**
* Separates two Bodies.
*
* @method Phaser.Physics.Arcade.World#separate
* @fires Phaser.Physics.Arcade.Events#COLLIDE
* @fires Phaser.Physics.Arcade.Events#OVERLAP
* @since 3.0.0
*
* @param {Phaser.Physics.Arcade.Body} body1 - The first Body to be separated.
* @param {Phaser.Physics.Arcade.Body} body2 - The second Body to be separated.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [processCallback] - The process callback.
* @param {*} [callbackContext] - The context in which to invoke the callback.
* @param {boolean} [overlapOnly] - If this a collide or overlap check?
*
* @return {boolean} True if separation occurred, otherwise false.
*/
separate: function(body1, body2, processCallback, callbackContext, overlapOnly) {
var overlapX;
var overlapY;
var result = false;
var runSeparation = true;
if (!body1.enable || !body2.enable || body1.checkCollision.none || body2.checkCollision.none || !this.intersects(body1, body2)) {
return result;
}
if (processCallback && processCallback.call(callbackContext, body1.gameObject || body1, body2.gameObject || body2) === false) {
return result;
}
if (body1.isCircle || body2.isCircle) {
var circleResults = this.separateCircle(body1, body2, overlapOnly);
if (circleResults.result) {
result = true;
runSeparation = false;
} else {
overlapX = circleResults.x;
overlapY = circleResults.y;
runSeparation = true;
}
}
if (runSeparation) {
var resultX = false;
var resultY = false;
var bias = this.OVERLAP_BIAS;
if (overlapOnly) {
resultX = SeparateX(body1, body2, overlapOnly, bias, overlapX);
resultY = SeparateY(body1, body2, overlapOnly, bias, overlapY);
} else if (this.forceX || Math.abs(this.gravity.y + body1.gravity.y) < Math.abs(this.gravity.x + body1.gravity.x)) {
resultX = SeparateX(body1, body2, overlapOnly, bias, overlapX);
if (this.intersects(body1, body2)) {
resultY = SeparateY(body1, body2, overlapOnly, bias, overlapY);
}
} else {
resultY = SeparateY(body1, body2, overlapOnly, bias, overlapY);
if (this.intersects(body1, body2)) {
resultX = SeparateX(body1, body2, overlapOnly, bias, overlapX);
}
}
result = resultX || resultY;
}
if (result) {
if (overlapOnly) {
if (body1.onOverlap || body2.onOverlap) {
this.emit(Events.OVERLAP, body1.gameObject, body2.gameObject, body1, body2);
}
} else if (body1.onCollide || body2.onCollide) {
this.emit(Events.COLLIDE, body1.gameObject, body2.gameObject, body1, body2);
}
}
return result;
},
/**
* Separates two Bodies, when both are circular.
*
* @method Phaser.Physics.Arcade.World#separateCircle
* @fires Phaser.Physics.Arcade.Events#COLLIDE
* @fires Phaser.Physics.Arcade.Events#OVERLAP
* @since 3.0.0
*
* @param {Phaser.Physics.Arcade.Body} body1 - The first Body to be separated.
* @param {Phaser.Physics.Arcade.Body} body2 - The second Body to be separated.
* @param {boolean} [overlapOnly] - If this a collide or overlap check?
*
* @return {boolean} True if separation occurred, otherwise false.
*/
separateCircle: function(body1, body2, overlapOnly) {
GetOverlapX(body1, body2, false, 0);
GetOverlapY(body1, body2, false, 0);
var body1IsCircle = body1.isCircle;
var body2IsCircle = body2.isCircle;
var body1Center = body1.center;
var body2Center = body2.center;
var body1Immovable = body1.immovable;
var body2Immovable = body2.immovable;
var body1Velocity = body1.velocity;
var body2Velocity = body2.velocity;
var overlap = 0;
var twoCircles = true;
if (body1IsCircle !== body2IsCircle) {
twoCircles = false;
var circleX = body1Center.x;
var circleY = body1Center.y;
var circleRadius = body1.halfWidth;
var rectX = body2.position.x;
var rectY = body2.position.y;
var rectRight = body2.right;
var rectBottom = body2.bottom;
if (body2IsCircle) {
circleX = body2Center.x;
circleY = body2Center.y;
circleRadius = body2.halfWidth;
rectX = body1.position.x;
rectY = body1.position.y;
rectRight = body1.right;
rectBottom = body1.bottom;
}
if (circleY < rectY) {
if (circleX < rectX) {
overlap = DistanceBetween(circleX, circleY, rectX, rectY) - circleRadius;
} else if (circleX > rectRight) {
overlap = DistanceBetween(circleX, circleY, rectRight, rectY) - circleRadius;
}
} else if (circleY > rectBottom) {
if (circleX < rectX) {
overlap = DistanceBetween(circleX, circleY, rectX, rectBottom) - circleRadius;
} else if (circleX > rectRight) {
overlap = DistanceBetween(circleX, circleY, rectRight, rectBottom) - circleRadius;
}
}
overlap *= -1;
} else {
overlap = body1.halfWidth + body2.halfWidth - DistanceBetweenPoints(body1Center, body2Center);
}
body1.overlapR = overlap;
body2.overlapR = overlap;
var angle = AngleBetweenPoints(body1Center, body2Center);
var overlapX = (overlap + MATH_CONST.EPSILON) * Math.cos(angle);
var overlapY = (overlap + MATH_CONST.EPSILON) * Math.sin(angle);
var results = { overlap, result: false, x: overlapX, y: overlapY };
if (overlapOnly && (!twoCircles || twoCircles && overlap !== 0)) {
results.result = true;
return results;
}
if (!twoCircles && overlap === 0 || body1Immovable && body2Immovable || body1.customSeparateX || body2.customSeparateX) {
results.x = void 0;
results.y = void 0;
return results;
}
var deadlock = !body1.pushable && !body2.pushable;
if (twoCircles) {
var dx = body1Center.x - body2Center.x;
var dy = body1Center.y - body2Center.y;
var d = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
var nx = (body2Center.x - body1Center.x) / d || 0;
var ny = (body2Center.y - body1Center.y) / d || 0;
var p = 2 * (body1Velocity.x * nx + body1Velocity.y * ny - body2Velocity.x * nx - body2Velocity.y * ny) / (body1.mass + body2.mass);
if (body1Immovable || body2Immovable || !body1.pushable || !body2.pushable) {
p *= 2;
}
if (!body1Immovable && body1.pushable) {
body1Velocity.x = body1Velocity.x - p / body1.mass * nx;
body1Velocity.y = body1Velocity.y - p / body1.mass * ny;
body1Velocity.multiply(body1.bounce);
}
if (!body2Immovable && body2.pushable) {
body2Velocity.x = body2Velocity.x + p / body2.mass * nx;
body2Velocity.y = body2Velocity.y + p / body2.mass * ny;
body2Velocity.multiply(body2.bounce);
}
if (!body1Immovable && !body2Immovable) {
overlapX *= 0.5;
overlapY *= 0.5;
}
if (!body1Immovable || body1.pushable || deadlock) {
body1.x -= overlapX;
body1.y -= overlapY;
body1.updateCenter();
} else if (!body2Immovable || body2.pushable || deadlock) {
body2.x += overlapX;
body2.y += overlapY;
body2.updateCenter();
}
results.result = true;
} else {
if (!body1Immovable || body1.pushable || deadlock) {
body1.x -= overlapX;
body1.y -= overlapY;
body1.updateCenter();
} else if (!body2Immovable || body2.pushable || deadlock) {
body2.x += overlapX;
body2.y += overlapY;
body2.updateCenter();
}
results.x = void 0;
results.y = void 0;
}
return results;
},
/**
* Checks to see if two Bodies intersect at all.
*
* @method Phaser.Physics.Arcade.World#intersects
* @since 3.0.0
*
* @param {Phaser.Physics.Arcade.Body} body1 - The first body to check.
* @param {Phaser.Physics.Arcade.Body} body2 - The second body to check.
*
* @return {boolean} True if the two bodies intersect, otherwise false.
*/
intersects: function(body1, body2) {
if (body1 === body2) {
return false;
}
if (!body1.isCircle && !body2.isCircle) {
return !(body1.right <= body2.left || body1.bottom <= body2.top || body1.left >= body2.right || body1.top >= body2.bottom);
} else if (body1.isCircle) {
if (body2.isCircle) {
return DistanceBetweenPoints(body1.center, body2.center) <= body1.halfWidth + body2.halfWidth;
} else {
return this.circleBodyIntersects(body1, body2);
}
} else {
return this.circleBodyIntersects(body2, body1);
}
},
/**
* Tests if a circular Body intersects with another Body.
*
* @method Phaser.Physics.Arcade.World#circleBodyIntersects
* @since 3.0.0
*
* @param {Phaser.Physics.Arcade.Body} circle - The circular body to test.
* @param {Phaser.Physics.Arcade.Body} body - The rectangular body to test.
*
* @return {boolean} True if the two bodies intersect, otherwise false.
*/
circleBodyIntersects: function(circle, body) {
var x = Clamp(circle.center.x, body.left, body.right);
var y = Clamp(circle.center.y, body.top, body.bottom);
var dx = (circle.center.x - x) * (circle.center.x - x);
var dy = (circle.center.y - y) * (circle.center.y - y);
return dx + dy <= circle.halfWidth * circle.halfWidth;
},
/**
* Tests if Game Objects overlap.
*
* See details in {@link Phaser.Physics.Arcade.World#collide}.
*
* @method Phaser.Physics.Arcade.World#overlap
* @since 3.0.0
*
* @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object or array of objects to check.
* @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} [object2] - The second object or array of objects to check, or `undefined`.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [overlapCallback] - An optional callback function that is called if the objects overlap.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they overlap. If this is set then `overlapCallback` will only be called if this callback returns `true`.
* @param {*} [callbackContext] - The context in which to run the callbacks.
*
* @return {boolean} True if at least one Game Object overlaps another.
*
* @see Phaser.Physics.Arcade.World#collide
*/
overlap: function(object1, object2, overlapCallback, processCallback, callbackContext) {
if (overlapCallback === void 0) {
overlapCallback = null;
}
if (processCallback === void 0) {
processCallback = null;
}
if (callbackContext === void 0) {
callbackContext = overlapCallback;
}
return this.collideObjects(object1, object2, overlapCallback, processCallback, callbackContext, true);
},
/**
* Performs a collision check and separation between the two physics enabled objects given, which can be single
* Game Objects, arrays of Game Objects, Physics Groups, arrays of Physics Groups or normal Groups.
*
* If you don't require separation then use {@link Phaser.Physics.Arcade.World#overlap} instead.
*
* If two Groups or arrays are passed, each member of one will be tested against each member of the other.
*
* If **only** one Group is passed (as `object1`), each member of the Group will be collided against the other members.
*
* If **only** one Array is passed, the array is iterated and every element in it is tested against the others.
*
* Two callbacks can be provided; they receive the colliding game objects as arguments.
* If an overlap is detected, the `processCallback` is called first. It can cancel the collision by returning false.
* Next the objects are separated and `collideCallback` is invoked.
*
* Arcade Physics uses the Projection Method of collision resolution and separation. While it's fast and suitable
* for 'arcade' style games it lacks stability when multiple objects are in close proximity or resting upon each other.
* The separation that stops two objects penetrating may create a new penetration against a different object. If you
* require a high level of stability please consider using an alternative physics system, such as Matter.js.
*
* @method Phaser.Physics.Arcade.World#collide
* @since 3.0.0
*
* @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object or array of objects to check.
* @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} [object2] - The second object or array of objects to check, or `undefined`.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`.
* @param {any} [callbackContext] - The context in which to run the callbacks.
*
* @return {boolean} `true` if any overlapping Game Objects were separated, otherwise `false`.
*/
collide: function(object1, object2, collideCallback, processCallback, callbackContext) {
if (collideCallback === void 0) {
collideCallback = null;
}
if (processCallback === void 0) {
processCallback = null;
}
if (callbackContext === void 0) {
callbackContext = collideCallback;
}
return this.collideObjects(object1, object2, collideCallback, processCallback, callbackContext, false);
},
/**
* Internal helper function. Please use Phaser.Physics.Arcade.World#collide instead.
*
* @method Phaser.Physics.Arcade.World#collideObjects
* @private
* @since 3.0.0
*
* @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object to check for collision.
* @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} [object2] - The second object to check for collision.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} collideCallback - The callback to invoke when the two objects collide.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} processCallback - The callback to invoke when the two objects collide. Must return a boolean.
* @param {any} callbackContext - The scope in which to call the callbacks.
* @param {boolean} overlapOnly - Whether this is a collision or overlap check.
*
* @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated.
*/
collideObjects: function(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly) {
var i;
var j;
if (object1.isParent && (object1.physicsType === void 0 || object2 === void 0 || object1 === object2)) {
object1 = object1.children.entries;
}
if (object2 && object2.isParent && object2.physicsType === void 0) {
object2 = object2.children.entries;
}
var object1isArray = Array.isArray(object1);
var object2isArray = Array.isArray(object2);
this._total = 0;
if (!object1isArray && !object2isArray) {
this.collideHandler(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly);
} else if (!object1isArray && object2isArray) {
for (i = 0; i < object2.length; i++) {
this.collideHandler(object1, object2[i], collideCallback, processCallback, callbackContext, overlapOnly);
}
} else if (object1isArray && !object2isArray) {
if (!object2) {
for (i = 0; i < object1.length; i++) {
var child = object1[i];
for (j = i + 1; j < object1.length; j++) {
if (i === j) {
continue;
}
this.collideHandler(child, object1[j], collideCallback, processCallback, callbackContext, overlapOnly);
}
}
} else {
for (i = 0; i < object1.length; i++) {
this.collideHandler(object1[i], object2, collideCallback, processCallback, callbackContext, overlapOnly);
}
}
} else {
for (i = 0; i < object1.length; i++) {
for (j = 0; j < object2.length; j++) {
this.collideHandler(object1[i], object2[j], collideCallback, processCallback, callbackContext, overlapOnly);
}
}
}
return this._total > 0;
},
/**
* Internal helper function. Please use Phaser.Physics.Arcade.World#collide and Phaser.Physics.Arcade.World#overlap instead.
*
* @method Phaser.Physics.Arcade.World#collideHandler
* @private
* @since 3.0.0
*
* @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object1 - The first object or array of objects to check.
* @param {Phaser.Types.Physics.Arcade.ArcadeColliderType} object2 - The second object or array of objects to check, or `undefined`.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} collideCallback - An optional callback function that is called if the objects collide.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} processCallback - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`.
* @param {any} callbackContext - The context in which to run the callbacks.
* @param {boolean} overlapOnly - Whether this is a collision or overlap check.
*
* @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated.
*/
collideHandler: function(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly) {
if (object2 === void 0 && object1.isParent) {
return this.collideGroupVsGroup(object1, object1, collideCallback, processCallback, callbackContext, overlapOnly);
}
if (!object1 || !object2) {
return false;
}
if (object1.body || object1.isBody) {
if (object2.body || object2.isBody) {
return this.collideSpriteVsSprite(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly);
} else if (object2.isParent) {
return this.collideSpriteVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly);
} else if (object2.isTilemap) {
return this.collideSpriteVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly);
}
} else if (object1.isParent) {
if (object2.body || object2.isBody) {
return this.collideSpriteVsGroup(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly);
} else if (object2.isParent) {
return this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly);
} else if (object2.isTilemap) {
return this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly);
}
} else if (object1.isTilemap) {
if (object2.body || object2.isBody) {
return this.collideSpriteVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly);
} else if (object2.isParent) {
return this.collideGroupVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly);
}
}
},
/**
* Checks if the two given Arcade Physics bodies will collide, or not,
* based on their collision mask and collision categories.
*
* @method Phaser.Physics.Arcade.World#canCollide
* @since 3.70.0
*
* @param {Phaser.Types.Physics.Arcade.ArcadeCollider} body1 - The first body to check.
* @param {Phaser.Types.Physics.Arcade.ArcadeCollider} body2 - The second body to check.
*
* @return {boolean} True if the two bodies will collide, otherwise false.
*/
canCollide: function(body1, body2) {
return body1 && body2 && (body1.collisionMask & body2.collisionCategory) !== 0 && (body2.collisionMask & body1.collisionCategory) !== 0;
},
/**
* Internal handler for Sprite vs. Sprite collisions.
* Please use Phaser.Physics.Arcade.World#collide instead.
*
* @method Phaser.Physics.Arcade.World#collideSpriteVsSprite
* @private
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} sprite1 - The first object to check for collision.
* @param {Phaser.GameObjects.GameObject} sprite2 - The second object to check for collision.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`.
* @param {any} [callbackContext] - The context in which to run the callbacks.
* @param {boolean} overlapOnly - Whether this is a collision or overlap check.
*
* @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated.
*/
collideSpriteVsSprite: function(sprite1, sprite2, collideCallback, processCallback, callbackContext, overlapOnly) {
var body1 = sprite1.isBody ? sprite1 : sprite1.body;
var body2 = sprite2.isBody ? sprite2 : sprite2.body;
if (!this.canCollide(body1, body2)) {
return false;
}
if (this.separate(body1, body2, processCallback, callbackContext, overlapOnly)) {
if (collideCallback) {
collideCallback.call(callbackContext, sprite1, sprite2);
}
this._total++;
}
return true;
},
/**
* Internal handler for Sprite vs. Group collisions.
* Please use Phaser.Physics.Arcade.World#collide instead.
*
* @method Phaser.Physics.Arcade.World#collideSpriteVsGroup
* @private
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision.
* @param {Phaser.GameObjects.Group} group - The second object to check for collision.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} collideCallback - The callback to invoke when the two objects collide.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} processCallback - The callback to invoke when the two objects collide. Must return a boolean.
* @param {any} callbackContext - The scope in which to call the callbacks.
* @param {boolean} overlapOnly - Whether this is a collision or overlap check.
*/
collideSpriteVsGroup: function(sprite, group, collideCallback, processCallback, callbackContext, overlapOnly) {
var bodyA = sprite.isBody ? sprite : sprite.body;
if (group.getLength() === 0 || !bodyA || !bodyA.enable || bodyA.checkCollision.none || !this.canCollide(bodyA, group)) {
return;
}
var i;
var len;
var bodyB;
if (this.useTree || group.physicsType === CONST.STATIC_BODY) {
var minMax = this.treeMinMax;
minMax.minX = bodyA.left;
minMax.minY = bodyA.top;
minMax.maxX = bodyA.right;
minMax.maxY = bodyA.bottom;
var results = group.physicsType === CONST.DYNAMIC_BODY ? this.tree.search(minMax) : this.staticTree.search(minMax);
len = results.length;
for (i = 0; i < len; i++) {
bodyB = results[i];
if (bodyA === bodyB || !bodyB.enable || bodyB.checkCollision.none || !group.contains(bodyB.gameObject)) {
continue;
}
if (this.separate(bodyA, bodyB, processCallback, callbackContext, overlapOnly)) {
if (collideCallback) {
collideCallback.call(callbackContext, bodyA.gameObject, bodyB.gameObject);
}
this._total++;
}
}
} else {
var children = group.getChildren();
var skipIndex = group.children.entries.indexOf(sprite);
len = children.length;
for (i = 0; i < len; i++) {
bodyB = children[i].body;
if (!bodyB || i === skipIndex || !bodyB.enable) {
continue;
}
if (this.separate(bodyA, bodyB, processCallback, callbackContext, overlapOnly)) {
if (collideCallback) {
collideCallback.call(callbackContext, bodyA.gameObject, bodyB.gameObject);
}
this._total++;
}
}
}
},
/**
* Internal handler for Group vs. Tilemap collisions.
* Please use Phaser.Physics.Arcade.World#collide instead.
*
* @method Phaser.Physics.Arcade.World#collideGroupVsTilemapLayer
* @private
* @since 3.0.0
*
* @param {Phaser.GameObjects.Group} group - The first object to check for collision.
* @param {Phaser.Tilemaps.TilemapLayer} tilemapLayer - The second object to check for collision.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} collideCallback - An optional callback function that is called if the objects collide.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} processCallback - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`.
* @param {any} callbackContext - The context in which to run the callbacks.
* @param {boolean} overlapOnly - Whether this is a collision or overlap check.
*
* @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated.
*/
collideGroupVsTilemapLayer: function(group, tilemapLayer, collideCallback, processCallback, callbackContext, overlapOnly) {
if (!this.canCollide(group, tilemapLayer)) {
return false;
}
var children = group.getChildren();
if (children.length === 0) {
return false;
}
var didCollide = false;
for (var i = 0; i < children.length; i++) {
if (children[i].body || children[i].isBody) {
if (this.collideSpriteVsTilemapLayer(children[i], tilemapLayer, collideCallback, processCallback, callbackContext, overlapOnly)) {
didCollide = true;
}
}
}
return didCollide;
},
/**
* This advanced method is specifically for testing for collision between a single Sprite and an array of Tile objects.
*
* You should generally use the `collide` method instead, with a Sprite vs. a Tilemap Layer, as that will perform
* tile filtering and culling for you, as well as handle the interesting face collision automatically.
*
* This method is offered for those who would like to check for collision with specific Tiles in a layer, without
* having to set any collision attributes on the tiles in question. This allows you to perform quick dynamic collisions
* on small sets of Tiles. As such, no culling or checks are made to the array of Tiles given to this method,
* you should filter them before passing them to this method.
*
* Important: Use of this method skips the `interesting faces` system that Tilemap Layers use. This means if you have
* say a row or column of tiles, and you jump into, or walk over them, it's possible to get stuck on the edges of the
* tiles as the interesting face calculations are skipped. However, for quick-fire small collision set tests on
* dynamic maps, this method can prove very useful.
*
* This method does not factor in the Collision Mask or Category.
*
* @method Phaser.Physics.Arcade.World#collideTiles
* @fires Phaser.Physics.Arcade.Events#TILE_COLLIDE
* @since 3.17.0
*
* @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision.
* @param {Phaser.Tilemaps.Tile[]} tiles - An array of Tiles to check for collision against.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`.
* @param {any} [callbackContext] - The context in which to run the callbacks.
*
* @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated.
*/
collideTiles: function(sprite, tiles, collideCallback, processCallback, callbackContext) {
if (tiles.length === 0 || sprite.body && !sprite.body.enable || sprite.isBody && !sprite.enable) {
return false;
} else {
return this.collideSpriteVsTilesHandler(sprite, tiles, collideCallback, processCallback, callbackContext, false, false);
}
},
/**
* This advanced method is specifically for testing for overlaps between a single Sprite and an array of Tile objects.
*
* You should generally use the `overlap` method instead, with a Sprite vs. a Tilemap Layer, as that will perform
* tile filtering and culling for you, as well as handle the interesting face collision automatically.
*
* This method is offered for those who would like to check for overlaps with specific Tiles in a layer, without
* having to set any collision attributes on the tiles in question. This allows you to perform quick dynamic overlap
* tests on small sets of Tiles. As such, no culling or checks are made to the array of Tiles given to this method,
* you should filter them before passing them to this method.
*
* This method does not factor in the Collision Mask or Category.
*
* @method Phaser.Physics.Arcade.World#overlapTiles
* @fires Phaser.Physics.Arcade.Events#TILE_OVERLAP
* @since 3.17.0
*
* @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision.
* @param {Phaser.Tilemaps.Tile[]} tiles - An array of Tiles to check for collision against.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects overlap.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`.
* @param {any} [callbackContext] - The context in which to run the callbacks.
*
* @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated.
*/
overlapTiles: function(sprite, tiles, collideCallback, processCallback, callbackContext) {
if (tiles.length === 0 || sprite.body && !sprite.body.enable || sprite.isBody && !sprite.enable) {
return false;
} else {
return this.collideSpriteVsTilesHandler(sprite, tiles, collideCallback, processCallback, callbackContext, true, false);
}
},
/**
* Internal handler for Sprite vs. Tilemap collisions.
* Please use Phaser.Physics.Arcade.World#collide instead.
*
* @method Phaser.Physics.Arcade.World#collideSpriteVsTilemapLayer
* @fires Phaser.Physics.Arcade.Events#TILE_COLLIDE
* @fires Phaser.Physics.Arcade.Events#TILE_OVERLAP
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision.
* @param {Phaser.Tilemaps.TilemapLayer} tilemapLayer - The second object to check for collision.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`.
* @param {any} [callbackContext] - The context in which to run the callbacks.
* @param {boolean} [overlapOnly] - Whether this is a collision or overlap check.
*
* @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated.
*/
collideSpriteVsTilemapLayer: function(sprite, tilemapLayer, collideCallback, processCallback, callbackContext, overlapOnly) {
var body = sprite.isBody ? sprite : sprite.body;
if (!body.enable || body.checkCollision.none || !this.canCollide(body, tilemapLayer)) {
return false;
}
var layerData = tilemapLayer.layer;
var x = body.x - layerData.tileWidth * tilemapLayer.scaleX;
var y = body.y - layerData.tileHeight * tilemapLayer.scaleY;
var w = body.width + layerData.tileWidth * tilemapLayer.scaleX;
var h = body.height + layerData.tileHeight * tilemapLayer.scaleY;
var options = overlapOnly ? null : this.tileFilterOptions;
var mapData = GetTilesWithinWorldXY(x, y, w, h, options, tilemapLayer.scene.cameras.main, tilemapLayer.layer);
if (mapData.length === 0) {
return false;
} else {
return this.collideSpriteVsTilesHandler(sprite, mapData, collideCallback, processCallback, callbackContext, overlapOnly, true);
}
},
/**
* Internal handler for Sprite vs. Tilemap collisions.
* Please use Phaser.Physics.Arcade.World#collide instead.
*
* @method Phaser.Physics.Arcade.World#collideSpriteVsTilesHandler
* @fires Phaser.Physics.Arcade.Events#TILE_COLLIDE
* @fires Phaser.Physics.Arcade.Events#TILE_OVERLAP
* @private
* @since 3.17.0
*
* @param {Phaser.GameObjects.GameObject} sprite - The first object to check for collision.
* @param {Phaser.Tilemaps.TilemapLayer} tilemapLayer - The second object to check for collision.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`.
* @param {any} [callbackContext] - The context in which to run the callbacks.
* @param {boolean} [overlapOnly] - Whether this is a collision or overlap check.
* @param {boolean} [isLayer] - Is this check coming from a TilemapLayer or an array of tiles?
*
* @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated.
*/
collideSpriteVsTilesHandler: function(sprite, tiles, collideCallback, processCallback, callbackContext, overlapOnly, isLayer) {
var body = sprite.isBody ? sprite : sprite.body;
var tile;
var tileWorldRect = { left: 0, right: 0, top: 0, bottom: 0 };
var tilemapLayer;
var collision = false;
for (var i = 0; i < tiles.length; i++) {
tile = tiles[i];
tilemapLayer = tile.tilemapLayer;
var point = tilemapLayer.tileToWorldXY(tile.x, tile.y);
tileWorldRect.left = point.x;
tileWorldRect.top = point.y;
tileWorldRect.right = tileWorldRect.left + tile.width * tilemapLayer.scaleX;
tileWorldRect.bottom = tileWorldRect.top + tile.height * tilemapLayer.scaleY;
if (TileIntersectsBody(tileWorldRect, body) && (!processCallback || processCallback.call(callbackContext, sprite, tile)) && ProcessTileCallbacks(tile, sprite) && (overlapOnly || SeparateTile(i, body, tile, tileWorldRect, tilemapLayer, this.TILE_BIAS, isLayer))) {
this._total++;
collision = true;
if (collideCallback) {
collideCallback.call(callbackContext, sprite, tile);
}
if (overlapOnly && body.onOverlap) {
this.emit(Events.TILE_OVERLAP, sprite, tile, body);
} else if (body.onCollide) {
this.emit(Events.TILE_COLLIDE, sprite, tile, body);
}
}
}
return collision;
},
/**
* Internal helper for Group vs. Group collisions.
* Please use Phaser.Physics.Arcade.World#collide instead.
*
* @method Phaser.Physics.Arcade.World#collideGroupVsGroup
* @private
* @since 3.0.0
*
* @param {Phaser.GameObjects.Group} group1 - The first object to check for collision.
* @param {Phaser.GameObjects.Group} group2 - The second object to check for collision.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [collideCallback] - An optional callback function that is called if the objects collide.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two objects if they collide. If this is set then `collideCallback` will only be called if this callback returns `true`.
* @param {any} [callbackContext] - The context in which to run the callbacks.
* @param {boolean} overlapOnly - Whether this is a collision or overlap check.
*
* @return {boolean} True if any objects overlap (with `overlapOnly`); or true if any overlapping objects were separated.
*/
collideGroupVsGroup: function(group1, group2, collideCallback, processCallback, callbackContext, overlapOnly) {
if (group1.getLength() === 0 || group2.getLength() === 0 || !this.canCollide(group1, group2)) {
return;
}
var children = group1.getChildren();
for (var i = 0; i < children.length; i++) {
this.collideSpriteVsGroup(children[i], group2, collideCallback, processCallback, callbackContext, overlapOnly);
}
},
/**
* Wrap an object's coordinates (or several objects' coordinates) within {@link Phaser.Physics.Arcade.World#bounds}.
*
* If the object is outside any boundary edge (left, top, right, bottom), it will be moved to the same offset from the opposite edge (the interior).
*
* @method Phaser.Physics.Arcade.World#wrap
* @since 3.3.0
*
* @param {any} object - A Game Object, a Group, an object with `x` and `y` coordinates, or an array of such objects.
* @param {number} [padding=0] - An amount added to each boundary edge during the operation.
*/
wrap: function(object, padding) {
if (object.body) {
this.wrapObject(object, padding);
} else if (object.getChildren) {
this.wrapArray(object.getChildren(), padding);
} else if (Array.isArray(object)) {
this.wrapArray(object, padding);
} else {
this.wrapObject(object, padding);
}
},
/**
* Wrap each object's coordinates within {@link Phaser.Physics.Arcade.World#bounds}.
*
* @method Phaser.Physics.Arcade.World#wrapArray
* @since 3.3.0
*
* @param {Array.<*>} objects - An array of objects to be wrapped.
* @param {number} [padding=0] - An amount added to the boundary.
*/
wrapArray: function(objects, padding) {
for (var i = 0; i < objects.length; i++) {
this.wrapObject(objects[i], padding);
}
},
/**
* Wrap an object's coordinates within {@link Phaser.Physics.Arcade.World#bounds}.
*
* @method Phaser.Physics.Arcade.World#wrapObject
* @since 3.3.0
*
* @param {*} object - A Game Object, a Physics Body, or any object with `x` and `y` coordinates
* @param {number} [padding=0] - An amount added to the boundary.
*/
wrapObject: function(object, padding) {
if (padding === void 0) {
padding = 0;
}
object.x = Wrap(object.x, this.bounds.left - padding, this.bounds.right + padding);
object.y = Wrap(object.y, this.bounds.top - padding, this.bounds.bottom + padding);
},
/**
* Shuts down the simulation, clearing physics data and removing listeners.
*
* @method Phaser.Physics.Arcade.World#shutdown
* @since 3.0.0
*/
shutdown: function() {
this.tree.clear();
this.staticTree.clear();
this.bodies.clear();
this.staticBodies.clear();
this.colliders.destroy();
this.removeAllListeners();
},
/**
* Shuts down the simulation and disconnects it from the current scene.
*
* @method Phaser.Physics.Arcade.World#destroy
* @since 3.0.0
*/
destroy: function() {
this.shutdown();
this.scene = null;
if (this.debugGraphic) {
this.debugGraphic.destroy();
this.debugGraphic = null;
}
}
});
module2.exports = World;
}
),
/***/
1093: (
/***/
(module2) => {
var Acceleration = {
/**
* Sets the body's horizontal and vertical acceleration. If the vertical acceleration value is not provided, the vertical acceleration is set to the same value as the horizontal acceleration.
*
* @method Phaser.Physics.Arcade.Components.Acceleration#setAcceleration
* @since 3.0.0
*
* @param {number} x - The horizontal acceleration
* @param {number} [y=x] - The vertical acceleration
*
* @return {this} This Game Object.
*/
setAcceleration: function(x, y) {
this.body.acceleration.set(x, y);
return this;
},
/**
* Sets the body's horizontal acceleration.
*
* @method Phaser.Physics.Arcade.Components.Acceleration#setAccelerationX
* @since 3.0.0
*
* @param {number} value - The horizontal acceleration
*
* @return {this} This Game Object.
*/
setAccelerationX: function(value) {
this.body.acceleration.x = value;
return this;
},
/**
* Sets the body's vertical acceleration.
*
* @method Phaser.Physics.Arcade.Components.Acceleration#setAccelerationY
* @since 3.0.0
*
* @param {number} value - The vertical acceleration
*
* @return {this} This Game Object.
*/
setAccelerationY: function(value) {
this.body.acceleration.y = value;
return this;
}
};
module2.exports = Acceleration;
}
),
/***/
59023: (
/***/
(module2) => {
var Angular = {
/**
* Sets the angular velocity of the body.
*
* In Arcade Physics, bodies cannot rotate. They are always axis-aligned.
* However, they can have angular motion, which is passed on to the Game Object bound to the body,
* causing them to visually rotate, even though the body remains axis-aligned.
*
* @method Phaser.Physics.Arcade.Components.Angular#setAngularVelocity
* @since 3.0.0
*
* @param {number} value - The amount of angular velocity.
*
* @return {this} This Game Object.
*/
setAngularVelocity: function(value) {
this.body.angularVelocity = value;
return this;
},
/**
* Sets the angular acceleration of the body.
*
* In Arcade Physics, bodies cannot rotate. They are always axis-aligned.
* However, they can have angular motion, which is passed on to the Game Object bound to the body,
* causing them to visually rotate, even though the body remains axis-aligned.
*
* @method Phaser.Physics.Arcade.Components.Angular#setAngularAcceleration
* @since 3.0.0
*
* @param {number} value - The amount of angular acceleration.
*
* @return {this} This Game Object.
*/
setAngularAcceleration: function(value) {
this.body.angularAcceleration = value;
return this;
},
/**
* Sets the angular drag of the body. Drag is applied to the current velocity, providing a form of deceleration.
*
* @method Phaser.Physics.Arcade.Components.Angular#setAngularDrag
* @since 3.0.0
*
* @param {number} value - The amount of drag.
*
* @return {this} This Game Object.
*/
setAngularDrag: function(value) {
this.body.angularDrag = value;
return this;
}
};
module2.exports = Angular;
}
),
/***/
62069: (
/***/
(module2) => {
var Bounce = {
/**
* Sets the bounce values of this body.
*
* Bounce is the amount of restitution, or elasticity, the body has when it collides with another object.
* A value of 1 means that it will retain its full velocity after the rebound. A value of 0 means it will not rebound at all.
*
* @method Phaser.Physics.Arcade.Components.Bounce#setBounce
* @since 3.0.0
*
* @param {number} x - The amount of horizontal bounce to apply on collision. A float, typically between 0 and 1.
* @param {number} [y=x] - The amount of vertical bounce to apply on collision. A float, typically between 0 and 1.
*
* @return {this} This Game Object.
*/
setBounce: function(x, y) {
this.body.bounce.set(x, y);
return this;
},
/**
* Sets the horizontal bounce value for this body.
*
* @method Phaser.Physics.Arcade.Components.Bounce#setBounceX
* @since 3.0.0
*
* @param {number} value - The amount of horizontal bounce to apply on collision. A float, typically between 0 and 1.
*
* @return {this} This Game Object.
*/
setBounceX: function(value) {
this.body.bounce.x = value;
return this;
},
/**
* Sets the vertical bounce value for this body.
*
* @method Phaser.Physics.Arcade.Components.Bounce#setBounceY
* @since 3.0.0
*
* @param {number} value - The amount of vertical bounce to apply on collision. A float, typically between 0 and 1.
*
* @return {this} This Game Object.
*/
setBounceY: function(value) {
this.body.bounce.y = value;
return this;
},
/**
* Sets whether this Body collides with the world boundary.
*
* Optionally also sets the World Bounce values. If the `Body.worldBounce` is null, it's set to a new Phaser.Math.Vector2 first.
*
* @method Phaser.Physics.Arcade.Components.Bounce#setCollideWorldBounds
* @since 3.0.0
*
* @param {boolean} [value=true] - `true` if this body should collide with the world bounds, otherwise `false`.
* @param {number} [bounceX] - If given this will be replace the `worldBounce.x` value.
* @param {number} [bounceY] - If given this will be replace the `worldBounce.y` value.
* @param {boolean} [onWorldBounds] - If given this replaces the Body's `onWorldBounds` value.
*
* @return {this} This Game Object.
*/
setCollideWorldBounds: function(value, bounceX, bounceY, onWorldBounds) {
this.body.setCollideWorldBounds(value, bounceX, bounceY, onWorldBounds);
return this;
}
};
module2.exports = Bounce;
}
),
/***/
78389: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetCollidesWith = __webpack_require__2(79599);
var Collision = {
/**
* Sets the Collision Category that this Arcade Physics Body
* will use in order to determine what it can collide with.
*
* It can only have one single category assigned to it.
*
* If you wish to reset the collision category and mask, call
* the `resetCollisionCategory` method.
*
* @method Phaser.Physics.Arcade.Components.Collision#setCollisionCategory
* @since 3.70.0
*
* @param {number} category - The collision category.
*
* @return {this} This Game Object.
*/
setCollisionCategory: function(category) {
var target = this.body ? this.body : this;
target.collisionCategory = category;
return this;
},
/**
* Checks to see if the given Collision Category will collide with
* this Arcade Physics object or not.
*
* @method Phaser.Physics.Arcade.Components.Collision#willCollideWith
* @since 3.70.0
*
* @param {number} category - Collision category value to test.
*
* @return {boolean} `true` if the given category will collide with this object, otherwise `false`.
*/
willCollideWith: function(category) {
var target = this.body ? this.body : this;
return (target.collisionMask & category) !== 0;
},
/**
* Adds the given Collision Category to the list of those that this
* Arcade Physics Body will collide with.
*
* @method Phaser.Physics.Arcade.Components.Collision#addCollidesWith
* @since 3.70.0
*
* @param {number} category - The collision category to add.
*
* @return {this} This Game Object.
*/
addCollidesWith: function(category) {
var target = this.body ? this.body : this;
target.collisionMask = target.collisionMask | category;
return this;
},
/**
* Removes the given Collision Category from the list of those that this
* Arcade Physics Body will collide with.
*
* @method Phaser.Physics.Arcade.Components.Collision#removeCollidesWith
* @since 3.70.0
*
* @param {number} category - The collision category to add.
*
* @return {this} This Game Object.
*/
removeCollidesWith: function(category) {
var target = this.body ? this.body : this;
target.collisionMask = target.collisionMask & ~category;
return this;
},
/**
* Sets all of the Collision Categories that this Arcade Physics Body
* will collide with. You can either pass a single category value, or
* an array of them.
*
* Calling this method will reset all of the collision categories,
* so only those passed to this method are enabled.
*
* If you wish to add a new category to the existing mask, call
* the `addCollisionCategory` method.
*
* If you wish to reset the collision category and mask, call
* the `resetCollisionCategory` method.
*
* @method Phaser.Physics.Arcade.Components.Collision#setCollidesWith
* @since 3.70.0
*
* @param {(number|number[])} categories - The collision category to collide with, or an array of them.
*
* @return {this} This Game Object.
*/
setCollidesWith: function(categories) {
var target = this.body ? this.body : this;
target.collisionMask = GetCollidesWith(categories);
return this;
},
/**
* Resets the Collision Category and Mask back to the defaults,
* which is to collide with everything.
*
* @method Phaser.Physics.Arcade.Components.Collision#resetCollisionCategory
* @since 3.70.0
*
* @return {this} This Game Object.
*/
resetCollisionCategory: function() {
var target = this.body ? this.body : this;
target.collisionCategory = 1;
target.collisionMask = 2147483647;
return this;
}
};
module2.exports = Collision;
}
),
/***/
87118: (
/***/
(module2) => {
var Debug = {
/**
* Sets the debug values of this body.
*
* Bodies will only draw their debug if debug has been enabled for Arcade Physics as a whole.
* Note that there is a performance cost in drawing debug displays. It should never be used in production.
*
* @method Phaser.Physics.Arcade.Components.Debug#setDebug
* @since 3.0.0
*
* @param {boolean} showBody - Set to `true` to have this body render its outline to the debug display.
* @param {boolean} showVelocity - Set to `true` to have this body render a velocity marker to the debug display.
* @param {number} bodyColor - The color of the body outline when rendered to the debug display.
*
* @return {this} This Game Object.
*/
setDebug: function(showBody, showVelocity, bodyColor) {
this.debugShowBody = showBody;
this.debugShowVelocity = showVelocity;
this.debugBodyColor = bodyColor;
return this;
},
/**
* Sets the color of the body outline when it renders to the debug display.
*
* @method Phaser.Physics.Arcade.Components.Debug#setDebugBodyColor
* @since 3.0.0
*
* @param {number} value - The color of the body outline when rendered to the debug display.
*
* @return {this} This Game Object.
*/
setDebugBodyColor: function(value) {
this.body.debugBodyColor = value;
return this;
},
/**
* Set to `true` to have this body render its outline to the debug display.
*
* @name Phaser.Physics.Arcade.Components.Debug#debugShowBody
* @type {boolean}
* @since 3.0.0
*/
debugShowBody: {
get: function() {
return this.body.debugShowBody;
},
set: function(value) {
this.body.debugShowBody = value;
}
},
/**
* Set to `true` to have this body render a velocity marker to the debug display.
*
* @name Phaser.Physics.Arcade.Components.Debug#debugShowVelocity
* @type {boolean}
* @since 3.0.0
*/
debugShowVelocity: {
get: function() {
return this.body.debugShowVelocity;
},
set: function(value) {
this.body.debugShowVelocity = value;
}
},
/**
* The color of the body outline when it renders to the debug display.
*
* @name Phaser.Physics.Arcade.Components.Debug#debugBodyColor
* @type {number}
* @since 3.0.0
*/
debugBodyColor: {
get: function() {
return this.body.debugBodyColor;
},
set: function(value) {
this.body.debugBodyColor = value;
}
}
};
module2.exports = Debug;
}
),
/***/
52819: (
/***/
(module2) => {
var Drag = {
/**
* Sets the body's horizontal and vertical drag. If the vertical drag value is not provided, the vertical drag is set to the same value as the horizontal drag.
*
* Drag can be considered as a form of deceleration that will return the velocity of a body back to zero over time.
* It is the absolute loss of velocity due to movement, in pixels per second squared.
* The x and y components are applied separately.
*
* When `useDamping` is true, this is 1 minus the damping factor.
* A value of 1 means the Body loses no velocity.
* A value of 0.95 means the Body loses 5% of its velocity per step.
* A value of 0.5 means the Body loses 50% of its velocity per step.
*
* Drag is applied only when `acceleration` is zero.
*
* @method Phaser.Physics.Arcade.Components.Drag#setDrag
* @since 3.0.0
*
* @param {number} x - The amount of horizontal drag to apply.
* @param {number} [y=x] - The amount of vertical drag to apply.
*
* @return {this} This Game Object.
*/
setDrag: function(x, y) {
this.body.drag.set(x, y);
return this;
},
/**
* Sets the body's horizontal drag.
*
* Drag can be considered as a form of deceleration that will return the velocity of a body back to zero over time.
* It is the absolute loss of velocity due to movement, in pixels per second squared.
* The x and y components are applied separately.
*
* When `useDamping` is true, this is 1 minus the damping factor.
* A value of 1 means the Body loses no velocity.
* A value of 0.95 means the Body loses 5% of its velocity per step.
* A value of 0.5 means the Body loses 50% of its velocity per step.
*
* Drag is applied only when `acceleration` is zero.
*
* @method Phaser.Physics.Arcade.Components.Drag#setDragX
* @since 3.0.0
*
* @param {number} value - The amount of horizontal drag to apply.
*
* @return {this} This Game Object.
*/
setDragX: function(value) {
this.body.drag.x = value;
return this;
},
/**
* Sets the body's vertical drag.
*
* Drag can be considered as a form of deceleration that will return the velocity of a body back to zero over time.
* It is the absolute loss of velocity due to movement, in pixels per second squared.
* The x and y components are applied separately.
*
* When `useDamping` is true, this is 1 minus the damping factor.
* A value of 1 means the Body loses no velocity.
* A value of 0.95 means the Body loses 5% of its velocity per step.
* A value of 0.5 means the Body loses 50% of its velocity per step.
*
* Drag is applied only when `acceleration` is zero.
*
* @method Phaser.Physics.Arcade.Components.Drag#setDragY
* @since 3.0.0
*
* @param {number} value - The amount of vertical drag to apply.
*
* @return {this} This Game Object.
*/
setDragY: function(value) {
this.body.drag.y = value;
return this;
},
/**
* If this Body is using `drag` for deceleration this function controls how the drag is applied.
* If set to `true` drag will use a damping effect rather than a linear approach. If you are
* creating a game where the Body moves freely at any angle (i.e. like the way the ship moves in
* the game Asteroids) then you will get a far smoother and more visually correct deceleration
* by using damping, avoiding the axis-drift that is prone with linear deceleration.
*
* If you enable this property then you should use far smaller `drag` values than with linear, as
* they are used as a multiplier on the velocity. Values such as 0.95 will give a nice slow
* deceleration, where-as smaller values, such as 0.5 will stop an object almost immediately.
*
* @method Phaser.Physics.Arcade.Components.Drag#setDamping
* @since 3.10.0
*
* @param {boolean} value - `true` to use damping for deceleration, or `false` to use linear deceleration.
*
* @return {this} This Game Object.
*/
setDamping: function(value) {
this.body.useDamping = value;
return this;
}
};
module2.exports = Drag;
}
),
/***/
4074: (
/***/
(module2) => {
var Enable = {
/**
* Sets whether this Body should calculate its velocity based on its change in
* position every frame. The default, which is to not do this, means that you
* make this Body move by setting the velocity directly. However, if you are
* trying to move this Body via a Tween, or have it follow a Path, then you
* should enable this instead. This will allow it to still collide with other
* bodies, something that isn't possible if you're just changing its position directly.
*
* @method Phaser.Physics.Arcade.Components.Enable#setDirectControl
* @since 3.70.0
*
* @param {boolean} [value=true] - `true` if the Body calculate velocity based on changes in position, otherwise `false`.
*
* @return {this} This Game Object.
*/
setDirectControl: function(value) {
this.body.setDirectControl(value);
return this;
},
/**
* Enables this Game Object's Body.
* If you reset the Body you must also pass `x` and `y`.
*
* @method Phaser.Physics.Arcade.Components.Enable#enableBody
* @since 3.0.0
*
* @param {boolean} [reset] - Also reset the Body and place the Game Object at (x, y).
* @param {number} [x] - The horizontal position to place the Game Object, if `reset` is true.
* @param {number} [y] - The horizontal position to place the Game Object, if `reset` is true.
* @param {boolean} [enableGameObject] - Also set this Game Object's `active` to true.
* @param {boolean} [showGameObject] - Also set this Game Object's `visible` to true.
*
* @return {this} This Game Object.
*
* @see Phaser.Physics.Arcade.Body#enable
* @see Phaser.Physics.Arcade.StaticBody#enable
* @see Phaser.Physics.Arcade.Body#reset
* @see Phaser.Physics.Arcade.StaticBody#reset
* @see Phaser.GameObjects.GameObject#active
* @see Phaser.GameObjects.GameObject#visible
*/
enableBody: function(reset, x, y, enableGameObject, showGameObject) {
if (reset) {
this.body.reset(x, y);
}
if (enableGameObject) {
this.body.gameObject.active = true;
}
if (showGameObject) {
this.body.gameObject.visible = true;
}
this.body.enable = true;
return this;
},
/**
* Stops and disables this Game Object's Body.
*
* @method Phaser.Physics.Arcade.Components.Enable#disableBody
* @since 3.0.0
*
* @param {boolean} [disableGameObject=false] - Also set this Game Object's `active` to false.
* @param {boolean} [hideGameObject=false] - Also set this Game Object's `visible` to false.
*
* @return {this} This Game Object.
*
* @see Phaser.Physics.Arcade.Body#enable
* @see Phaser.Physics.Arcade.StaticBody#enable
* @see Phaser.GameObjects.GameObject#active
* @see Phaser.GameObjects.GameObject#visible
*/
disableBody: function(disableGameObject, hideGameObject) {
if (disableGameObject === void 0) {
disableGameObject = false;
}
if (hideGameObject === void 0) {
hideGameObject = false;
}
this.body.stop();
this.body.enable = false;
if (disableGameObject) {
this.body.gameObject.active = false;
}
if (hideGameObject) {
this.body.gameObject.visible = false;
}
return this;
},
/**
* Syncs the Body's position and size with its parent Game Object.
* You don't need to call this for Dynamic Bodies, as it happens automatically.
* But for Static bodies it's a useful way of modifying the position of a Static Body
* in the Physics World, based on its Game Object.
*
* @method Phaser.Physics.Arcade.Components.Enable#refreshBody
* @since 3.1.0
*
* @return {this} This Game Object.
*
* @see Phaser.Physics.Arcade.StaticBody#updateFromGameObject
*/
refreshBody: function() {
this.body.updateFromGameObject();
return this;
}
};
module2.exports = Enable;
}
),
/***/
40831: (
/***/
(module2) => {
var Friction = {
/**
* Sets the friction of this game object's physics body.
* In Arcade Physics, friction is a special case of motion transfer from an "immovable" body to a riding body.
*
* @method Phaser.Physics.Arcade.Components.Friction#setFriction
* @since 3.0.0
*
* @param {number} x - The amount of horizontal friction to apply, [0, 1].
* @param {number} [y=x] - The amount of vertical friction to apply, [0, 1].
*
* @return {this} This Game Object.
*
* @see Phaser.Physics.Arcade.Body#friction
*/
setFriction: function(x, y) {
this.body.friction.set(x, y);
return this;
},
/**
* Sets the horizontal friction of this game object's physics body.
* This can move a riding body horizontally when it collides with this one on the vertical axis.
*
* @method Phaser.Physics.Arcade.Components.Friction#setFrictionX
* @since 3.0.0
*
* @param {number} x - The amount of friction to apply, [0, 1].
*
* @return {this} This Game Object.
*
* @see Phaser.Physics.Arcade.Body#friction
*/
setFrictionX: function(x) {
this.body.friction.x = x;
return this;
},
/**
* Sets the vertical friction of this game object's physics body.
* This can move a riding body vertically when it collides with this one on the horizontal axis.
*
* @method Phaser.Physics.Arcade.Components.Friction#setFrictionY
* @since 3.0.0
*
* @param {number} y - The amount of friction to apply, [0, 1].
*
* @return {this} This Game Object.
*
* @see Phaser.Physics.Arcade.Body#friction
*/
setFrictionY: function(y) {
this.body.friction.y = y;
return this;
}
};
module2.exports = Friction;
}
),
/***/
26775: (
/***/
(module2) => {
var Gravity = {
/**
* Set the X and Y values of the gravitational pull to act upon this Arcade Physics Game Object. Values can be positive or negative. Larger values result in a stronger effect.
*
* If only one value is provided, this value will be used for both the X and Y axis.
*
* @method Phaser.Physics.Arcade.Components.Gravity#setGravity
* @since 3.0.0
*
* @param {number} x - The gravitational force to be applied to the X-axis.
* @param {number} [y=x] - The gravitational force to be applied to the Y-axis. If this is not specified, the X value will be used.
*
* @return {this} This Game Object.
*/
setGravity: function(x, y) {
this.body.gravity.set(x, y);
return this;
},
/**
* Set the gravitational force to be applied to the X axis. Value can be positive or negative. Larger values result in a stronger effect.
*
* @method Phaser.Physics.Arcade.Components.Gravity#setGravityX
* @since 3.0.0
*
* @param {number} x - The gravitational force to be applied to the X-axis.
*
* @return {this} This Game Object.
*/
setGravityX: function(x) {
this.body.gravity.x = x;
return this;
},
/**
* Set the gravitational force to be applied to the Y axis. Value can be positive or negative. Larger values result in a stronger effect.
*
* @method Phaser.Physics.Arcade.Components.Gravity#setGravityY
* @since 3.0.0
*
* @param {number} y - The gravitational force to be applied to the Y-axis.
*
* @return {this} This Game Object.
*/
setGravityY: function(y) {
this.body.gravity.y = y;
return this;
}
};
module2.exports = Gravity;
}
),
/***/
9437: (
/***/
(module2) => {
var Immovable = {
/**
* Sets if this Body can be separated during collisions with other bodies.
*
* When a body is immovable it means it won't move at all, not even to separate it from collision
* overlap. If you just wish to prevent a body from being knocked around by other bodies, see
* the `setPushable` method instead.
*
* @method Phaser.Physics.Arcade.Components.Immovable#setImmovable
* @since 3.0.0
*
* @param {boolean} [value=true] - Sets if this body will be separated during collisions with other bodies.
*
* @return {this} This Game Object.
*/
setImmovable: function(value) {
if (value === void 0) {
value = true;
}
this.body.immovable = value;
return this;
}
};
module2.exports = Immovable;
}
),
/***/
30621: (
/***/
(module2) => {
var Mass = {
/**
* Sets the mass of the physics body
*
* @method Phaser.Physics.Arcade.Components.Mass#setMass
* @since 3.0.0
*
* @param {number} value - New value for the mass of the body.
*
* @return {this} This Game Object.
*/
setMass: function(value) {
this.body.mass = value;
return this;
}
};
module2.exports = Mass;
}
),
/***/
72441: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var OverlapRect = __webpack_require__2(47956);
var Circle = __webpack_require__2(96503);
var CircleToCircle = __webpack_require__2(2044);
var CircleToRectangle = __webpack_require__2(81491);
var OverlapCirc = function(world, x, y, radius, includeDynamic, includeStatic) {
var bodiesInRect = OverlapRect(world, x - radius, y - radius, 2 * radius, 2 * radius, includeDynamic, includeStatic);
if (bodiesInRect.length === 0) {
return bodiesInRect;
}
var area = new Circle(x, y, radius);
var circFromBody = new Circle();
var bodiesInArea = [];
for (var i = 0; i < bodiesInRect.length; i++) {
var body = bodiesInRect[i];
if (body.isCircle) {
circFromBody.setTo(body.center.x, body.center.y, body.halfWidth);
if (CircleToCircle(area, circFromBody)) {
bodiesInArea.push(body);
}
} else if (CircleToRectangle(area, body)) {
bodiesInArea.push(body);
}
}
return bodiesInArea;
};
module2.exports = OverlapCirc;
}
),
/***/
47956: (
/***/
(module2) => {
var OverlapRect = function(world, x, y, width, height, includeDynamic, includeStatic) {
if (includeDynamic === void 0) {
includeDynamic = true;
}
if (includeStatic === void 0) {
includeStatic = false;
}
var dynamicBodies = [];
var staticBodies = [];
var minMax = world.treeMinMax;
minMax.minX = x;
minMax.minY = y;
minMax.maxX = x + width;
minMax.maxY = y + height;
if (includeStatic) {
staticBodies = world.staticTree.search(minMax);
}
if (includeDynamic && world.useTree) {
dynamicBodies = world.tree.search(minMax);
} else if (includeDynamic) {
var bodies = world.bodies;
var fakeBody = {
position: {
x,
y
},
left: x,
top: y,
right: x + width,
bottom: y + height,
isCircle: false
};
var intersects = world.intersects;
bodies.iterate(function(target) {
if (intersects(target, fakeBody)) {
dynamicBodies.push(target);
}
});
}
return staticBodies.concat(dynamicBodies);
};
module2.exports = OverlapRect;
}
),
/***/
62121: (
/***/
(module2) => {
var Pushable = {
/**
* Sets if this Body can be pushed by another Body.
*
* A body that cannot be pushed will reflect back all of the velocity it is given to the
* colliding body. If that body is also not pushable, then the separation will be split
* between them evenly.
*
* If you want your body to never move or seperate at all, see the `setImmovable` method.
*
* @method Phaser.Physics.Arcade.Components.Pushable#setPushable
* @since 3.50.0
*
* @param {boolean} [value=true] - Sets if this body can be pushed by collisions with another Body.
*
* @return {this} This Game Object.
*/
setPushable: function(value) {
if (value === void 0) {
value = true;
}
this.body.pushable = value;
return this;
}
};
module2.exports = Pushable;
}
),
/***/
29384: (
/***/
(module2) => {
var Size = {
/**
* Sets the body offset. This allows you to adjust the difference between the center of the body
* and the x and y coordinates of the parent Game Object.
*
* @method Phaser.Physics.Arcade.Components.Size#setOffset
* @since 3.0.0
*
* @param {number} x - The amount to offset the body from the parent Game Object along the x-axis.
* @param {number} [y=x] - The amount to offset the body from the parent Game Object along the y-axis. Defaults to the value given for the x-axis.
*
* @return {this} This Game Object.
*/
setOffset: function(x, y) {
this.body.setOffset(x, y);
return this;
},
/**
* **DEPRECATED**: Please use `setBodySize` instead.
*
* Sets the size of this physics body. Setting the size does not adjust the dimensions of the parent Game Object.
*
* @method Phaser.Physics.Arcade.Components.Size#setSize
* @since 3.0.0
* @deprecated
*
* @param {number} width - The new width of the physics body, in pixels.
* @param {number} height - The new height of the physics body, in pixels.
* @param {boolean} [center=true] - Should the body be re-positioned so its center aligns with the parent Game Object?
*
* @return {this} This Game Object.
*/
setSize: function(width, height, center) {
this.body.setSize(width, height, center);
return this;
},
/**
* Sets the size of this physics body. Setting the size does not adjust the dimensions of the parent Game Object.
*
* @method Phaser.Physics.Arcade.Components.Size#setBodySize
* @since 3.24.0
*
* @param {number} width - The new width of the physics body, in pixels.
* @param {number} height - The new height of the physics body, in pixels.
* @param {boolean} [center=true] - Should the body be re-positioned so its center aligns with the parent Game Object?
*
* @return {this} This Game Object.
*/
setBodySize: function(width, height, center) {
this.body.setSize(width, height, center);
return this;
},
/**
* Sets this physics body to use a circle for collision instead of a rectangle.
*
* @method Phaser.Physics.Arcade.Components.Size#setCircle
* @since 3.0.0
*
* @param {number} radius - The radius of the physics body, in pixels.
* @param {number} [offsetX] - The amount to offset the body from the parent Game Object along the x-axis.
* @param {number} [offsetY] - The amount to offset the body from the parent Game Object along the y-axis.
*
* @return {this} This Game Object.
*/
setCircle: function(radius, offsetX, offsetY) {
this.body.setCircle(radius, offsetX, offsetY);
return this;
}
};
module2.exports = Size;
}
),
/***/
15098: (
/***/
(module2) => {
var Velocity = {
/**
* Sets the velocity of the Body.
*
* @method Phaser.Physics.Arcade.Components.Velocity#setVelocity
* @since 3.0.0
*
* @param {number} x - The horizontal velocity of the body, in pixels per second. Positive values move the body to the right, while negative values move it to the left.
* @param {number} [y=x] - The vertical velocity of the body, in pixels per second. Positive values move the body down, while negative values move it up.
*
* @return {this} This Game Object.
*/
setVelocity: function(x, y) {
this.body.setVelocity(x, y);
return this;
},
/**
* Sets the horizontal component of the body's velocity.
*
* Positive values move the body to the right, while negative values move it to the left.
*
* @method Phaser.Physics.Arcade.Components.Velocity#setVelocityX
* @since 3.0.0
*
* @param {number} x - The new horizontal velocity, in pixels per second.
*
* @return {this} This Game Object.
*/
setVelocityX: function(x) {
this.body.setVelocityX(x);
return this;
},
/**
* Sets the vertical component of the body's velocity.
*
* Positive values move the body down, while negative values move it up.
*
* @method Phaser.Physics.Arcade.Components.Velocity#setVelocityY
* @since 3.0.0
*
* @param {number} y - The new vertical velocity, in pixels per second.
*
* @return {this} This Game Object.
*/
setVelocityY: function(y) {
this.body.setVelocityY(y);
return this;
},
/**
* Sets the maximum velocity of the body.
*
* @method Phaser.Physics.Arcade.Components.Velocity#setMaxVelocity
* @since 3.0.0
*
* @param {number} x - The new maximum horizontal velocity, in pixels per second.
* @param {number} [y=x] - The new maximum vertical velocity, in pixels per second.
*
* @return {this} This Game Object.
*/
setMaxVelocity: function(x, y) {
this.body.maxVelocity.set(x, y);
return this;
}
};
module2.exports = Velocity;
}
),
/***/
92209: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Acceleration: __webpack_require__2(1093),
Angular: __webpack_require__2(59023),
Bounce: __webpack_require__2(62069),
Collision: __webpack_require__2(78389),
Debug: __webpack_require__2(87118),
Drag: __webpack_require__2(52819),
Enable: __webpack_require__2(4074),
Friction: __webpack_require__2(40831),
Gravity: __webpack_require__2(26775),
Immovable: __webpack_require__2(9437),
Mass: __webpack_require__2(30621),
OverlapCirc: __webpack_require__2(72441),
OverlapRect: __webpack_require__2(47956),
Pushable: __webpack_require__2(62121),
Size: __webpack_require__2(29384),
Velocity: __webpack_require__2(15098)
};
}
),
/***/
37747: (
/***/
(module2) => {
var CONST = {
/**
* Dynamic Body.
*
* @name Phaser.Physics.Arcade.DYNAMIC_BODY
* @readonly
* @type {number}
* @since 3.0.0
*
* @see Phaser.Physics.Arcade.Body#physicsType
* @see Phaser.Physics.Arcade.Group#physicsType
*/
DYNAMIC_BODY: 0,
/**
* Static Body.
*
* @name Phaser.Physics.Arcade.STATIC_BODY
* @readonly
* @type {number}
* @since 3.0.0
*
* @see Phaser.Physics.Arcade.Body#physicsType
* @see Phaser.Physics.Arcade.StaticBody#physicsType
*/
STATIC_BODY: 1,
/**
* Arcade Physics Group containing Dynamic Bodies.
*
* @name Phaser.Physics.Arcade.GROUP
* @readonly
* @type {number}
* @since 3.0.0
*/
GROUP: 2,
/**
* A Tilemap Layer.
*
* @name Phaser.Physics.Arcade.TILEMAPLAYER
* @readonly
* @type {number}
* @since 3.0.0
*/
TILEMAPLAYER: 3,
/**
* Facing no direction (initial value).
*
* @name Phaser.Physics.Arcade.FACING_NONE
* @readonly
* @type {number}
* @since 3.0.0
*
* @see Phaser.Physics.Arcade.Body#facing
*/
FACING_NONE: 10,
/**
* Facing up.
*
* @name Phaser.Physics.Arcade.FACING_UP
* @readonly
* @type {number}
* @since 3.0.0
*
* @see Phaser.Physics.Arcade.Body#facing
*/
FACING_UP: 11,
/**
* Facing down.
*
* @name Phaser.Physics.Arcade.FACING_DOWN
* @readonly
* @type {number}
* @since 3.0.0
*
* @see Phaser.Physics.Arcade.Body#facing
*/
FACING_DOWN: 12,
/**
* Facing left.
*
* @name Phaser.Physics.Arcade.FACING_LEFT
* @readonly
* @type {number}
* @since 3.0.0
*
* @see Phaser.Physics.Arcade.Body#facing
*/
FACING_LEFT: 13,
/**
* Facing right.
*
* @name Phaser.Physics.Arcade.FACING_RIGHT
* @readonly
* @type {number}
* @since 3.0.0
*
* @see Phaser.Physics.Arcade.Body#facing
*/
FACING_RIGHT: 14
};
module2.exports = CONST;
}
),
/***/
20009: (
/***/
(module2) => {
module2.exports = "collide";
}
),
/***/
36768: (
/***/
(module2) => {
module2.exports = "overlap";
}
),
/***/
60473: (
/***/
(module2) => {
module2.exports = "pause";
}
),
/***/
89954: (
/***/
(module2) => {
module2.exports = "resume";
}
),
/***/
61804: (
/***/
(module2) => {
module2.exports = "tilecollide";
}
),
/***/
7161: (
/***/
(module2) => {
module2.exports = "tileoverlap";
}
),
/***/
34689: (
/***/
(module2) => {
module2.exports = "worldbounds";
}
),
/***/
16006: (
/***/
(module2) => {
module2.exports = "worldstep";
}
),
/***/
63012: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
COLLIDE: __webpack_require__2(20009),
OVERLAP: __webpack_require__2(36768),
PAUSE: __webpack_require__2(60473),
RESUME: __webpack_require__2(89954),
TILE_COLLIDE: __webpack_require__2(61804),
TILE_OVERLAP: __webpack_require__2(7161),
WORLD_BOUNDS: __webpack_require__2(34689),
WORLD_STEP: __webpack_require__2(16006)
};
}
),
/***/
27064: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(37747);
var Extend = __webpack_require__2(79291);
var Arcade = {
ArcadePhysics: __webpack_require__2(86689),
Body: __webpack_require__2(37742),
Collider: __webpack_require__2(79342),
Components: __webpack_require__2(92209),
Events: __webpack_require__2(63012),
Factory: __webpack_require__2(66022),
GetCollidesWith: __webpack_require__2(79599),
GetOverlapX: __webpack_require__2(64897),
GetOverlapY: __webpack_require__2(45170),
SeparateX: __webpack_require__2(14087),
SeparateY: __webpack_require__2(89936),
Group: __webpack_require__2(60758),
Image: __webpack_require__2(71289),
Sprite: __webpack_require__2(13759),
StaticBody: __webpack_require__2(72624),
StaticGroup: __webpack_require__2(71464),
Tilemap: __webpack_require__2(55173),
World: __webpack_require__2(82248)
};
Arcade = Extend(false, Arcade, CONST);
module2.exports = Arcade;
}
),
/***/
96602: (
/***/
(module2) => {
var ProcessTileCallbacks = function(tile, sprite) {
if (tile.collisionCallback) {
return !tile.collisionCallback.call(tile.collisionCallbackContext, sprite, tile);
} else if (tile.layer.callbacks[tile.index]) {
return !tile.layer.callbacks[tile.index].callback.call(
tile.layer.callbacks[tile.index].callbackContext,
sprite,
tile
);
}
return true;
};
module2.exports = ProcessTileCallbacks;
}
),
/***/
36294: (
/***/
(module2) => {
var ProcessTileSeparationX = function(body, x) {
if (x < 0) {
body.blocked.none = false;
body.blocked.left = true;
} else if (x > 0) {
body.blocked.none = false;
body.blocked.right = true;
}
body.position.x -= x;
body.updateCenter();
if (body.bounce.x === 0) {
body.velocity.x = 0;
} else {
body.velocity.x = -body.velocity.x * body.bounce.x;
}
};
module2.exports = ProcessTileSeparationX;
}
),
/***/
67013: (
/***/
(module2) => {
var ProcessTileSeparationY = function(body, y) {
if (y < 0) {
body.blocked.none = false;
body.blocked.up = true;
} else if (y > 0) {
body.blocked.none = false;
body.blocked.down = true;
}
body.position.y -= y;
body.updateCenter();
if (body.bounce.y === 0) {
body.velocity.y = 0;
} else {
body.velocity.y = -body.velocity.y * body.bounce.y;
}
};
module2.exports = ProcessTileSeparationY;
}
),
/***/
40012: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var TileCheckX = __webpack_require__2(21329);
var TileCheckY = __webpack_require__2(53442);
var TileIntersectsBody = __webpack_require__2(2483);
var SeparateTile = function(i, body, tile, tileWorldRect, tilemapLayer, tileBias, isLayer) {
var tileLeft = tileWorldRect.left;
var tileTop = tileWorldRect.top;
var tileRight = tileWorldRect.right;
var tileBottom = tileWorldRect.bottom;
var faceHorizontal = tile.faceLeft || tile.faceRight;
var faceVertical = tile.faceTop || tile.faceBottom;
if (!isLayer) {
faceHorizontal = true;
faceVertical = true;
}
if (!faceHorizontal && !faceVertical) {
return false;
}
var ox = 0;
var oy = 0;
var minX = 0;
var minY = 1;
if (body.deltaAbsX() > body.deltaAbsY()) {
minX = -1;
} else if (body.deltaAbsX() < body.deltaAbsY()) {
minY = -1;
}
if (body.deltaX() !== 0 && body.deltaY() !== 0 && faceHorizontal && faceVertical) {
minX = Math.min(Math.abs(body.position.x - tileRight), Math.abs(body.right - tileLeft));
minY = Math.min(Math.abs(body.position.y - tileBottom), Math.abs(body.bottom - tileTop));
}
if (minX < minY) {
if (faceHorizontal) {
ox = TileCheckX(body, tile, tileLeft, tileRight, tileBias, isLayer);
if (ox !== 0 && !TileIntersectsBody(tileWorldRect, body)) {
return true;
}
}
if (faceVertical) {
oy = TileCheckY(body, tile, tileTop, tileBottom, tileBias, isLayer);
}
} else {
if (faceVertical) {
oy = TileCheckY(body, tile, tileTop, tileBottom, tileBias, isLayer);
if (oy !== 0 && !TileIntersectsBody(tileWorldRect, body)) {
return true;
}
}
if (faceHorizontal) {
ox = TileCheckX(body, tile, tileLeft, tileRight, tileBias, isLayer);
}
}
return ox !== 0 || oy !== 0;
};
module2.exports = SeparateTile;
}
),
/***/
21329: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var ProcessTileSeparationX = __webpack_require__2(36294);
var TileCheckX = function(body, tile, tileLeft, tileRight, tileBias, isLayer) {
var ox = 0;
var faceLeft = tile.faceLeft;
var faceRight = tile.faceRight;
var collideLeft = tile.collideLeft;
var collideRight = tile.collideRight;
if (!isLayer) {
faceLeft = true;
faceRight = true;
collideLeft = true;
collideRight = true;
}
if (body.deltaX() < 0 && collideRight && body.checkCollision.left) {
if (faceRight && body.x < tileRight) {
ox = body.x - tileRight;
if (ox < -tileBias) {
ox = 0;
}
}
} else if (body.deltaX() > 0 && collideLeft && body.checkCollision.right) {
if (faceLeft && body.right > tileLeft) {
ox = body.right - tileLeft;
if (ox > tileBias) {
ox = 0;
}
}
}
if (ox !== 0) {
if (body.customSeparateX) {
body.overlapX = ox;
} else {
ProcessTileSeparationX(body, ox);
}
}
return ox;
};
module2.exports = TileCheckX;
}
),
/***/
53442: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var ProcessTileSeparationY = __webpack_require__2(67013);
var TileCheckY = function(body, tile, tileTop, tileBottom, tileBias, isLayer) {
var oy = 0;
var faceTop = tile.faceTop;
var faceBottom = tile.faceBottom;
var collideUp = tile.collideUp;
var collideDown = tile.collideDown;
if (!isLayer) {
faceTop = true;
faceBottom = true;
collideUp = true;
collideDown = true;
}
if (body.deltaY() < 0 && collideDown && body.checkCollision.up) {
if (faceBottom && body.y < tileBottom) {
oy = body.y - tileBottom;
if (oy < -tileBias) {
oy = 0;
}
}
} else if (body.deltaY() > 0 && collideUp && body.checkCollision.down) {
if (faceTop && body.bottom > tileTop) {
oy = body.bottom - tileTop;
if (oy > tileBias) {
oy = 0;
}
}
}
if (oy !== 0) {
if (body.customSeparateY) {
body.overlapY = oy;
} else {
ProcessTileSeparationY(body, oy);
}
}
return oy;
};
module2.exports = TileCheckY;
}
),
/***/
2483: (
/***/
(module2) => {
var TileIntersectsBody = function(tileWorldRect, body) {
return !(body.right <= tileWorldRect.left || body.bottom <= tileWorldRect.top || body.position.x >= tileWorldRect.right || body.position.y >= tileWorldRect.bottom);
};
module2.exports = TileIntersectsBody;
}
),
/***/
55173: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Tilemap = {
ProcessTileCallbacks: __webpack_require__2(96602),
ProcessTileSeparationX: __webpack_require__2(36294),
ProcessTileSeparationY: __webpack_require__2(67013),
SeparateTile: __webpack_require__2(40012),
TileCheckX: __webpack_require__2(21329),
TileCheckY: __webpack_require__2(53442),
TileIntersectsBody: __webpack_require__2(2483)
};
module2.exports = Tilemap;
}
),
/***/
44563: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Arcade: __webpack_require__2(27064),
Matter: __webpack_require__2(3875)
};
}
),
/***/
68174: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Vector2 = __webpack_require__2(26099);
var BodyBounds = new Class({
initialize: function BodyBounds2() {
this.boundsCenter = new Vector2();
this.centerDiff = new Vector2();
},
/**
* Parses the given body to get the bounds diff values from it.
*
* They're stored in this class in the temporary properties `boundsCenter` and `centerDiff`.
*
* This method is called automatically by all other methods in this class.
*
* @method Phaser.Physics.Matter.BodyBounds#parseBody
* @since 3.22.0
*
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the bounds position from.
*
* @return {boolean} `true` if it was able to get the bounds, otherwise `false`.
*/
parseBody: function(body) {
body = body.hasOwnProperty("body") ? body.body : body;
if (!body.hasOwnProperty("bounds") || !body.hasOwnProperty("centerOfMass")) {
return false;
}
var boundsCenter = this.boundsCenter;
var centerDiff = this.centerDiff;
var boundsWidth = body.bounds.max.x - body.bounds.min.x;
var boundsHeight = body.bounds.max.y - body.bounds.min.y;
var bodyCenterX = boundsWidth * body.centerOfMass.x;
var bodyCenterY = boundsHeight * body.centerOfMass.y;
boundsCenter.set(boundsWidth / 2, boundsHeight / 2);
centerDiff.set(bodyCenterX - boundsCenter.x, bodyCenterY - boundsCenter.y);
return true;
},
/**
* Takes a Body and returns the world coordinates of the top-left of its _bounds_.
*
* Body bounds are updated by Matter each step and factor in scale and rotation.
* This will return the world coordinate based on the bodies _current_ position and bounds.
*
* @method Phaser.Physics.Matter.BodyBounds#getTopLeft
* @since 3.22.0
*
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from.
* @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates.
* @param {number} [y=0] - Optional vertical offset to add to the returned coordinates.
*
* @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body.
*/
getTopLeft: function(body, x, y) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (this.parseBody(body)) {
var center = this.boundsCenter;
var diff = this.centerDiff;
return new Vector2(
x + center.x + diff.x,
y + center.y + diff.y
);
}
return false;
},
/**
* Takes a Body and returns the world coordinates of the top-center of its _bounds_.
*
* Body bounds are updated by Matter each step and factor in scale and rotation.
* This will return the world coordinate based on the bodies _current_ position and bounds.
*
* @method Phaser.Physics.Matter.BodyBounds#getTopCenter
* @since 3.22.0
*
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from.
* @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates.
* @param {number} [y=0] - Optional vertical offset to add to the returned coordinates.
*
* @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body.
*/
getTopCenter: function(body, x, y) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (this.parseBody(body)) {
var center = this.boundsCenter;
var diff = this.centerDiff;
return new Vector2(
x + diff.x,
y + center.y + diff.y
);
}
return false;
},
/**
* Takes a Body and returns the world coordinates of the top-right of its _bounds_.
*
* Body bounds are updated by Matter each step and factor in scale and rotation.
* This will return the world coordinate based on the bodies _current_ position and bounds.
*
* @method Phaser.Physics.Matter.BodyBounds#getTopRight
* @since 3.22.0
*
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from.
* @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates.
* @param {number} [y=0] - Optional vertical offset to add to the returned coordinates.
*
* @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body.
*/
getTopRight: function(body, x, y) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (this.parseBody(body)) {
var center = this.boundsCenter;
var diff = this.centerDiff;
return new Vector2(
x - (center.x - diff.x),
y + center.y + diff.y
);
}
return false;
},
/**
* Takes a Body and returns the world coordinates of the left-center of its _bounds_.
*
* Body bounds are updated by Matter each step and factor in scale and rotation.
* This will return the world coordinate based on the bodies _current_ position and bounds.
*
* @method Phaser.Physics.Matter.BodyBounds#getLeftCenter
* @since 3.22.0
*
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from.
* @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates.
* @param {number} [y=0] - Optional vertical offset to add to the returned coordinates.
*
* @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body.
*/
getLeftCenter: function(body, x, y) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (this.parseBody(body)) {
var center = this.boundsCenter;
var diff = this.centerDiff;
return new Vector2(
x + center.x + diff.x,
y + diff.y
);
}
return false;
},
/**
* Takes a Body and returns the world coordinates of the center of its _bounds_.
*
* Body bounds are updated by Matter each step and factor in scale and rotation.
* This will return the world coordinate based on the bodies _current_ position and bounds.
*
* @method Phaser.Physics.Matter.BodyBounds#getCenter
* @since 3.22.0
*
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from.
* @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates.
* @param {number} [y=0] - Optional vertical offset to add to the returned coordinates.
*
* @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body.
*/
getCenter: function(body, x, y) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (this.parseBody(body)) {
var diff = this.centerDiff;
return new Vector2(
x + diff.x,
y + diff.y
);
}
return false;
},
/**
* Takes a Body and returns the world coordinates of the right-center of its _bounds_.
*
* Body bounds are updated by Matter each step and factor in scale and rotation.
* This will return the world coordinate based on the bodies _current_ position and bounds.
*
* @method Phaser.Physics.Matter.BodyBounds#getRightCenter
* @since 3.22.0
*
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from.
* @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates.
* @param {number} [y=0] - Optional vertical offset to add to the returned coordinates.
*
* @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body.
*/
getRightCenter: function(body, x, y) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (this.parseBody(body)) {
var center = this.boundsCenter;
var diff = this.centerDiff;
return new Vector2(
x - (center.x - diff.x),
y + diff.y
);
}
return false;
},
/**
* Takes a Body and returns the world coordinates of the bottom-left of its _bounds_.
*
* Body bounds are updated by Matter each step and factor in scale and rotation.
* This will return the world coordinate based on the bodies _current_ position and bounds.
*
* @method Phaser.Physics.Matter.BodyBounds#getBottomLeft
* @since 3.22.0
*
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from.
* @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates.
* @param {number} [y=0] - Optional vertical offset to add to the returned coordinates.
*
* @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body.
*/
getBottomLeft: function(body, x, y) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (this.parseBody(body)) {
var center = this.boundsCenter;
var diff = this.centerDiff;
return new Vector2(
x + center.x + diff.x,
y - (center.y - diff.y)
);
}
return false;
},
/**
* Takes a Body and returns the world coordinates of the bottom-center of its _bounds_.
*
* Body bounds are updated by Matter each step and factor in scale and rotation.
* This will return the world coordinate based on the bodies _current_ position and bounds.
*
* @method Phaser.Physics.Matter.BodyBounds#getBottomCenter
* @since 3.22.0
*
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from.
* @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates.
* @param {number} [y=0] - Optional vertical offset to add to the returned coordinates.
*
* @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body.
*/
getBottomCenter: function(body, x, y) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (this.parseBody(body)) {
var center = this.boundsCenter;
var diff = this.centerDiff;
return new Vector2(
x + diff.x,
y - (center.y - diff.y)
);
}
return false;
},
/**
* Takes a Body and returns the world coordinates of the bottom-right of its _bounds_.
*
* Body bounds are updated by Matter each step and factor in scale and rotation.
* This will return the world coordinate based on the bodies _current_ position and bounds.
*
* @method Phaser.Physics.Matter.BodyBounds#getBottomRight
* @since 3.22.0
*
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to get the position from.
* @param {number} [x=0] - Optional horizontal offset to add to the returned coordinates.
* @param {number} [y=0] - Optional vertical offset to add to the returned coordinates.
*
* @return {(Phaser.Math.Vector2|false)} A Vector2 containing the coordinates, or `false` if it was unable to parse the body.
*/
getBottomRight: function(body, x, y) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (this.parseBody(body)) {
var center = this.boundsCenter;
var diff = this.centerDiff;
return new Vector2(
x - (center.x - diff.x),
y - (center.y - diff.y)
);
}
return false;
}
});
module2.exports = BodyBounds;
}
),
/***/
19933: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Matter = __webpack_require__2(6790);
Matter.Body = __webpack_require__2(22562);
Matter.Composite = __webpack_require__2(69351);
Matter.World = __webpack_require__2(4372);
Matter.Collision = __webpack_require__2(52284);
Matter.Detector = __webpack_require__2(81388);
Matter.Pairs = __webpack_require__2(99561);
Matter.Pair = __webpack_require__2(4506);
Matter.Query = __webpack_require__2(73296);
Matter.Resolver = __webpack_require__2(66272);
Matter.Constraint = __webpack_require__2(48140);
Matter.Common = __webpack_require__2(53402);
Matter.Engine = __webpack_require__2(48413);
Matter.Events = __webpack_require__2(35810);
Matter.Sleeping = __webpack_require__2(53614);
Matter.Plugin = __webpack_require__2(73832);
Matter.Bodies = __webpack_require__2(66280);
Matter.Composites = __webpack_require__2(74116);
Matter.Axes = __webpack_require__2(66615);
Matter.Bounds = __webpack_require__2(15647);
Matter.Svg = __webpack_require__2(74058);
Matter.Vector = __webpack_require__2(31725);
Matter.Vertices = __webpack_require__2(41598);
Matter.World.add = Matter.Composite.add;
Matter.World.remove = Matter.Composite.remove;
Matter.World.addComposite = Matter.Composite.addComposite;
Matter.World.addBody = Matter.Composite.addBody;
Matter.World.addConstraint = Matter.Composite.addConstraint;
Matter.World.clear = Matter.Composite.clear;
module2.exports = Matter;
}
),
/***/
28137: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Bodies = __webpack_require__2(66280);
var Class = __webpack_require__2(83419);
var Composites = __webpack_require__2(74116);
var Constraint = __webpack_require__2(48140);
var Svg = __webpack_require__2(74058);
var MatterGameObject = __webpack_require__2(75803);
var MatterImage = __webpack_require__2(23181);
var MatterSprite = __webpack_require__2(34803);
var MatterTileBody = __webpack_require__2(73834);
var PhysicsEditorParser = __webpack_require__2(19496);
var PhysicsJSONParser = __webpack_require__2(85791);
var PointerConstraint = __webpack_require__2(98713);
var Vertices = __webpack_require__2(41598);
var Factory = new Class({
initialize: function Factory2(world) {
this.world = world;
this.scene = world.scene;
this.sys = world.scene.sys;
},
/**
* Creates a new rigid rectangular Body and adds it to the World.
*
* @method Phaser.Physics.Matter.Factory#rectangle
* @since 3.0.0
*
* @param {number} x - The X coordinate of the center of the Body.
* @param {number} y - The Y coordinate of the center of the Body.
* @param {number} width - The width of the Body.
* @param {number} height - The height of the Body.
* @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation.
*
* @return {MatterJS.BodyType} A Matter JS Body.
*/
rectangle: function(x, y, width, height, options) {
var body = Bodies.rectangle(x, y, width, height, options);
this.world.add(body);
return body;
},
/**
* Creates a new rigid trapezoidal Body and adds it to the World.
*
* @method Phaser.Physics.Matter.Factory#trapezoid
* @since 3.0.0
*
* @param {number} x - The X coordinate of the center of the Body.
* @param {number} y - The Y coordinate of the center of the Body.
* @param {number} width - The width of the trapezoid Body.
* @param {number} height - The height of the trapezoid Body.
* @param {number} slope - The slope of the trapezoid. 0 creates a rectangle, while 1 creates a triangle. Positive values make the top side shorter, while negative values make the bottom side shorter.
* @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation.
*
* @return {MatterJS.BodyType} A Matter JS Body.
*/
trapezoid: function(x, y, width, height, slope, options) {
var body = Bodies.trapezoid(x, y, width, height, slope, options);
this.world.add(body);
return body;
},
/**
* Creates a new rigid circular Body and adds it to the World.
*
* @method Phaser.Physics.Matter.Factory#circle
* @since 3.0.0
*
* @param {number} x - The X coordinate of the center of the Body.
* @param {number} y - The Y coordinate of the center of the Body.
* @param {number} radius - The radius of the circle.
* @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation.
* @param {number} [maxSides] - The maximum amount of sides to use for the polygon which will approximate this circle.
*
* @return {MatterJS.BodyType} A Matter JS Body.
*/
circle: function(x, y, radius, options, maxSides) {
var body = Bodies.circle(x, y, radius, options, maxSides);
this.world.add(body);
return body;
},
/**
* Creates a new rigid polygonal Body and adds it to the World.
*
* @method Phaser.Physics.Matter.Factory#polygon
* @since 3.0.0
*
* @param {number} x - The X coordinate of the center of the Body.
* @param {number} y - The Y coordinate of the center of the Body.
* @param {number} sides - The number of sides the polygon will have.
* @param {number} radius - The "radius" of the polygon, i.e. the distance from its center to any vertex. This is also the radius of its circumcircle.
* @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation.
*
* @return {MatterJS.BodyType} A Matter JS Body.
*/
polygon: function(x, y, sides, radius, options) {
var body = Bodies.polygon(x, y, sides, radius, options);
this.world.add(body);
return body;
},
/**
* Creates a body using the supplied vertices (or an array containing multiple sets of vertices) and adds it to the World.
* If the vertices are convex, they will pass through as supplied. Otherwise, if the vertices are concave, they will be decomposed. Note that this process is not guaranteed to support complex sets of vertices, e.g. ones with holes.
*
* @method Phaser.Physics.Matter.Factory#fromVertices
* @since 3.0.0
*
* @param {number} x - The X coordinate of the center of the Body.
* @param {number} y - The Y coordinate of the center of the Body.
* @param {(string|array)} vertexSets - The vertices data. Either a path string or an array of vertices.
* @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation.
* @param {boolean} [flagInternal=false] - Flag internal edges (coincident part edges)
* @param {number} [removeCollinear=0.01] - Whether Matter.js will discard collinear edges (to improve performance).
* @param {number} [minimumArea=10] - During decomposition discard parts that have an area less than this.
*
* @return {MatterJS.BodyType} A Matter JS Body.
*/
fromVertices: function(x, y, vertexSets, options, flagInternal, removeCollinear, minimumArea) {
if (typeof vertexSets === "string") {
vertexSets = Vertices.fromPath(vertexSets);
}
var body = Bodies.fromVertices(x, y, vertexSets, options, flagInternal, removeCollinear, minimumArea);
this.world.add(body);
return body;
},
/**
* Creates a body using data exported from the application PhysicsEditor (https://www.codeandweb.com/physicseditor)
*
* The PhysicsEditor file should be loaded as JSON:
*
* ```javascript
* preload ()
* {
* this.load.json('vehicles', 'assets/vehicles.json);
* }
*
* create ()
* {
* const vehicleShapes = this.cache.json.get('vehicles');
* this.matter.add.fromPhysicsEditor(400, 300, vehicleShapes.truck);
* }
* ```
*
* Do not pass the entire JSON file to this method, but instead pass one of the shapes contained within it.
*
* If you pas in an `options` object, any settings in there will override those in the PhysicsEditor config object.
*
* @method Phaser.Physics.Matter.Factory#fromPhysicsEditor
* @since 3.22.0
*
* @param {number} x - The horizontal world location of the body.
* @param {number} y - The vertical world location of the body.
* @param {any} config - The JSON data exported from PhysicsEditor.
* @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation.
* @param {boolean} [addToWorld=true] - Should the newly created body be immediately added to the World?
*
* @return {MatterJS.BodyType} A Matter JS Body.
*/
fromPhysicsEditor: function(x, y, config, options, addToWorld) {
if (addToWorld === void 0) {
addToWorld = true;
}
var body = PhysicsEditorParser.parseBody(x, y, config, options);
if (addToWorld && !this.world.has(body)) {
this.world.add(body);
}
return body;
},
/**
* Creates a body using the path data from an SVG file.
*
* SVG Parsing requires the pathseg polyfill from https://github.com/progers/pathseg
*
* The SVG file should be loaded as XML, as this method requires the ability to extract
* the path data from it. I.e.:
*
* ```javascript
* preload ()
* {
* this.load.xml('face', 'assets/face.svg);
* }
*
* create ()
* {
* this.matter.add.fromSVG(400, 300, this.cache.xml.get('face'));
* }
* ```
*
* @method Phaser.Physics.Matter.Factory#fromSVG
* @since 3.22.0
*
* @param {number} x - The X coordinate of the body.
* @param {number} y - The Y coordinate of the body.
* @param {object} xml - The SVG Path data.
* @param {number} [scale=1] - Scale the vertices by this amount after creation.
* @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation.
* @param {boolean} [addToWorld=true] - Should the newly created body be immediately added to the World?
*
* @return {MatterJS.BodyType} A Matter JS Body.
*/
fromSVG: function(x, y, xml, scale, options, addToWorld) {
if (scale === void 0) {
scale = 1;
}
if (options === void 0) {
options = {};
}
if (addToWorld === void 0) {
addToWorld = true;
}
var path = xml.getElementsByTagName("path");
var vertexSets = [];
for (var i = 0; i < path.length; i++) {
var points = Svg.pathToVertices(path[i], 30);
if (scale !== 1) {
Vertices.scale(points, scale, scale);
}
vertexSets.push(points);
}
var body = Bodies.fromVertices(x, y, vertexSets, options);
if (addToWorld) {
this.world.add(body);
}
return body;
},
/**
* Creates a body using the supplied physics data, as provided by a JSON file.
*
* The data file should be loaded as JSON:
*
* ```javascript
* preload ()
* {
* this.load.json('ninjas', 'assets/ninjas.json);
* }
*
* create ()
* {
* const ninjaShapes = this.cache.json.get('ninjas');
*
* this.matter.add.fromJSON(400, 300, ninjaShapes.shinobi);
* }
* ```
*
* Do not pass the entire JSON file to this method, but instead pass one of the shapes contained within it.
*
* If you pas in an `options` object, any settings in there will override those in the config object.
*
* The structure of the JSON file is as follows:
*
* ```text
* {
* 'generator_info': // The name of the application that created the JSON data
* 'shapeName': {
* 'type': // The type of body
* 'label': // Optional body label
* 'vertices': // An array, or an array of arrays, containing the vertex data in x/y object pairs
* }
* }
* ```
*
* At the time of writing, only the Phaser Physics Tracer App exports in this format.
*
* @method Phaser.Physics.Matter.Factory#fromJSON
* @since 3.22.0
*
* @param {number} x - The X coordinate of the body.
* @param {number} y - The Y coordinate of the body.
* @param {any} config - The JSON physics data.
* @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation.
* @param {boolean} [addToWorld=true] - Should the newly created body be immediately added to the World?
*
* @return {MatterJS.BodyType} A Matter JS Body.
*/
fromJSON: function(x, y, config, options, addToWorld) {
if (options === void 0) {
options = {};
}
if (addToWorld === void 0) {
addToWorld = true;
}
var body = PhysicsJSONParser.parseBody(x, y, config, options);
if (body && addToWorld) {
this.world.add(body);
}
return body;
},
/**
* Create a new composite containing Matter Image objects created in a grid arrangement.
* This function uses the body bounds to prevent overlaps.
*
* @method Phaser.Physics.Matter.Factory#imageStack
* @since 3.0.0
*
* @param {string} key - The key of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|number)} frame - An optional frame from the Texture this Game Object is rendering with. Set to `null` to skip this value.
* @param {number} x - The horizontal position of this composite in the world.
* @param {number} y - The vertical position of this composite in the world.
* @param {number} columns - The number of columns in the grid.
* @param {number} rows - The number of rows in the grid.
* @param {number} [columnGap=0] - The distance between each column.
* @param {number} [rowGap=0] - The distance between each row.
* @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation.
*
* @return {MatterJS.CompositeType} A Matter JS Composite Stack.
*/
imageStack: function(key, frame, x, y, columns, rows, columnGap, rowGap, options) {
if (columnGap === void 0) {
columnGap = 0;
}
if (rowGap === void 0) {
rowGap = 0;
}
if (options === void 0) {
options = {};
}
var world = this.world;
var displayList = this.sys.displayList;
options.addToWorld = false;
var stack = Composites.stack(x, y, columns, rows, columnGap, rowGap, function(x2, y2) {
var image = new MatterImage(world, x2, y2, key, frame, options);
displayList.add(image);
return image.body;
});
world.add(stack);
return stack;
},
/**
* Create a new composite containing bodies created in the callback in a grid arrangement.
*
* This function uses the body bounds to prevent overlaps.
*
* @method Phaser.Physics.Matter.Factory#stack
* @since 3.0.0
*
* @param {number} x - The horizontal position of this composite in the world.
* @param {number} y - The vertical position of this composite in the world.
* @param {number} columns - The number of columns in the grid.
* @param {number} rows - The number of rows in the grid.
* @param {number} columnGap - The distance between each column.
* @param {number} rowGap - The distance between each row.
* @param {function} callback - The callback that creates the stack.
*
* @return {MatterJS.CompositeType} A new composite containing objects created in the callback.
*/
stack: function(x, y, columns, rows, columnGap, rowGap, callback) {
var stack = Composites.stack(x, y, columns, rows, columnGap, rowGap, callback);
this.world.add(stack);
return stack;
},
/**
* Create a new composite containing bodies created in the callback in a pyramid arrangement.
* This function uses the body bounds to prevent overlaps.
*
* @method Phaser.Physics.Matter.Factory#pyramid
* @since 3.0.0
*
* @param {number} x - The horizontal position of this composite in the world.
* @param {number} y - The vertical position of this composite in the world.
* @param {number} columns - The number of columns in the pyramid.
* @param {number} rows - The number of rows in the pyramid.
* @param {number} columnGap - The distance between each column.
* @param {number} rowGap - The distance between each row.
* @param {function} callback - The callback function to be invoked.
*
* @return {MatterJS.CompositeType} A Matter JS Composite pyramid.
*/
pyramid: function(x, y, columns, rows, columnGap, rowGap, callback) {
var stack = Composites.pyramid(x, y, columns, rows, columnGap, rowGap, callback);
this.world.add(stack);
return stack;
},
/**
* Chains all bodies in the given composite together using constraints.
*
* @method Phaser.Physics.Matter.Factory#chain
* @since 3.0.0
*
* @param {MatterJS.CompositeType} composite - The composite in which all bodies will be chained together sequentially.
* @param {number} xOffsetA - The horizontal offset of the BodyA constraint. This is a percentage based on the body size, not a world position.
* @param {number} yOffsetA - The vertical offset of the BodyA constraint. This is a percentage based on the body size, not a world position.
* @param {number} xOffsetB - The horizontal offset of the BodyB constraint. This is a percentage based on the body size, not a world position.
* @param {number} yOffsetB - The vertical offset of the BodyB constraint. This is a percentage based on the body size, not a world position.
* @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [options] - An optional Constraint configuration object that is used to set initial Constraint properties on creation.
*
* @return {MatterJS.CompositeType} The original composite that was passed to this method.
*/
chain: function(composite, xOffsetA, yOffsetA, xOffsetB, yOffsetB, options) {
return Composites.chain(composite, xOffsetA, yOffsetA, xOffsetB, yOffsetB, options);
},
/**
* Connects bodies in the composite with constraints in a grid pattern, with optional cross braces.
*
* @method Phaser.Physics.Matter.Factory#mesh
* @since 3.0.0
*
* @param {MatterJS.CompositeType} composite - The composite in which all bodies will be chained together.
* @param {number} columns - The number of columns in the mesh.
* @param {number} rows - The number of rows in the mesh.
* @param {boolean} crossBrace - Create cross braces for the mesh as well?
* @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [options] - An optional Constraint configuration object that is used to set initial Constraint properties on creation.
*
* @return {MatterJS.CompositeType} The original composite that was passed to this method.
*/
mesh: function(composite, columns, rows, crossBrace, options) {
return Composites.mesh(composite, columns, rows, crossBrace, options);
},
/**
* Creates a composite with a Newton's Cradle setup of bodies and constraints.
*
* @method Phaser.Physics.Matter.Factory#newtonsCradle
* @since 3.0.0
*
* @param {number} x - The horizontal position of the start of the cradle.
* @param {number} y - The vertical position of the start of the cradle.
* @param {number} number - The number of balls in the cradle.
* @param {number} size - The radius of each ball in the cradle.
* @param {number} length - The length of the 'string' the balls hang from.
*
* @return {MatterJS.CompositeType} A Newton's cradle composite.
*/
newtonsCradle: function(x, y, number, size, length) {
var composite = Composites.newtonsCradle(x, y, number, size, length);
this.world.add(composite);
return composite;
},
/**
* Creates a composite with simple car setup of bodies and constraints.
*
* @method Phaser.Physics.Matter.Factory#car
* @since 3.0.0
*
* @param {number} x - The horizontal position of the car in the world.
* @param {number} y - The vertical position of the car in the world.
* @param {number} width - The width of the car chasis.
* @param {number} height - The height of the car chasis.
* @param {number} wheelSize - The radius of the car wheels.
*
* @return {MatterJS.CompositeType} A new composite car body.
*/
car: function(x, y, width, height, wheelSize) {
var composite = Composites.car(x, y, width, height, wheelSize);
this.world.add(composite);
return composite;
},
/**
* Creates a simple soft body like object.
*
* @method Phaser.Physics.Matter.Factory#softBody
* @since 3.0.0
*
* @param {number} x - The horizontal position of this composite in the world.
* @param {number} y - The vertical position of this composite in the world.
* @param {number} columns - The number of columns in the Composite.
* @param {number} rows - The number of rows in the Composite.
* @param {number} columnGap - The distance between each column.
* @param {number} rowGap - The distance between each row.
* @param {boolean} crossBrace - `true` to create cross braces between the bodies, or `false` to create just straight braces.
* @param {number} particleRadius - The radius of this circlular composite.
* @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [particleOptions] - An optional Body configuration object that is used to set initial Body properties on creation.
* @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [constraintOptions] - An optional Constraint configuration object that is used to set initial Constraint properties on creation.
*
* @return {MatterJS.CompositeType} A new composite simple soft body.
*/
softBody: function(x, y, columns, rows, columnGap, rowGap, crossBrace, particleRadius, particleOptions, constraintOptions) {
var composite = Composites.softBody(x, y, columns, rows, columnGap, rowGap, crossBrace, particleRadius, particleOptions, constraintOptions);
this.world.add(composite);
return composite;
},
/**
* This method is an alias for `Factory.constraint`.
*
* Constraints (or joints) are used for specifying that a fixed distance must be maintained
* between two bodies, or a body and a fixed world-space position.
*
* The stiffness of constraints can be modified to create springs or elastic.
*
* To simulate a revolute constraint (or pin joint) set `length: 0` and a high `stiffness`
* value (e.g. `0.7` or above).
*
* If the constraint is unstable, try lowering the `stiffness` value and / or increasing
* `constraintIterations` within the Matter Config.
*
* For compound bodies, constraints must be applied to the parent body and not one of its parts.
*
* @method Phaser.Physics.Matter.Factory#joint
* @since 3.0.0
*
* @param {MatterJS.BodyType} bodyA - The first possible `Body` that this constraint is attached to.
* @param {MatterJS.BodyType} bodyB - The second possible `Body` that this constraint is attached to.
* @param {number} [length] - A Number that specifies the target resting length of the constraint. If not given it is calculated automatically in `Constraint.create` from initial positions of the `constraint.bodyA` and `constraint.bodyB`.
* @param {number} [stiffness=1] - A Number that specifies the stiffness of the constraint, i.e. the rate at which it returns to its resting `constraint.length`. A value of `1` means the constraint should be very stiff. A value of `0.2` means the constraint acts as a soft spring.
* @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [options] - An optional Constraint configuration object that is used to set initial Constraint properties on creation.
*
* @return {MatterJS.ConstraintType} A Matter JS Constraint.
*/
joint: function(bodyA, bodyB, length, stiffness, options) {
return this.constraint(bodyA, bodyB, length, stiffness, options);
},
/**
* This method is an alias for `Factory.constraint`.
*
* Constraints (or joints) are used for specifying that a fixed distance must be maintained
* between two bodies, or a body and a fixed world-space position.
*
* The stiffness of constraints can be modified to create springs or elastic.
*
* To simulate a revolute constraint (or pin joint) set `length: 0` and a high `stiffness`
* value (e.g. `0.7` or above).
*
* If the constraint is unstable, try lowering the `stiffness` value and / or increasing
* `constraintIterations` within the Matter Config.
*
* For compound bodies, constraints must be applied to the parent body and not one of its parts.
*
* @method Phaser.Physics.Matter.Factory#spring
* @since 3.0.0
*
* @param {MatterJS.BodyType} bodyA - The first possible `Body` that this constraint is attached to.
* @param {MatterJS.BodyType} bodyB - The second possible `Body` that this constraint is attached to.
* @param {number} [length] - A Number that specifies the target resting length of the constraint. If not given it is calculated automatically in `Constraint.create` from initial positions of the `constraint.bodyA` and `constraint.bodyB`.
* @param {number} [stiffness=1] - A Number that specifies the stiffness of the constraint, i.e. the rate at which it returns to its resting `constraint.length`. A value of `1` means the constraint should be very stiff. A value of `0.2` means the constraint acts as a soft spring.
* @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [options] - An optional Constraint configuration object that is used to set initial Constraint properties on creation.
*
* @return {MatterJS.ConstraintType} A Matter JS Constraint.
*/
spring: function(bodyA, bodyB, length, stiffness, options) {
return this.constraint(bodyA, bodyB, length, stiffness, options);
},
/**
* Constraints (or joints) are used for specifying that a fixed distance must be maintained
* between two bodies, or a body and a fixed world-space position.
*
* The stiffness of constraints can be modified to create springs or elastic.
*
* To simulate a revolute constraint (or pin joint) set `length: 0` and a high `stiffness`
* value (e.g. `0.7` or above).
*
* If the constraint is unstable, try lowering the `stiffness` value and / or increasing
* `constraintIterations` within the Matter Config.
*
* For compound bodies, constraints must be applied to the parent body and not one of its parts.
*
* @method Phaser.Physics.Matter.Factory#constraint
* @since 3.0.0
*
* @param {MatterJS.BodyType} bodyA - The first possible `Body` that this constraint is attached to.
* @param {MatterJS.BodyType} bodyB - The second possible `Body` that this constraint is attached to.
* @param {number} [length] - A Number that specifies the target resting length of the constraint. If not given it is calculated automatically in `Constraint.create` from initial positions of the `constraint.bodyA` and `constraint.bodyB`.
* @param {number} [stiffness=1] - A Number that specifies the stiffness of the constraint, i.e. the rate at which it returns to its resting `constraint.length`. A value of `1` means the constraint should be very stiff. A value of `0.2` means the constraint acts as a soft spring.
* @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [options] - An optional Constraint configuration object that is used to set initial Constraint properties on creation.
*
* @return {MatterJS.ConstraintType} A Matter JS Constraint.
*/
constraint: function(bodyA, bodyB, length, stiffness, options) {
if (stiffness === void 0) {
stiffness = 1;
}
if (options === void 0) {
options = {};
}
options.bodyA = bodyA.type === "body" ? bodyA : bodyA.body;
options.bodyB = bodyB.type === "body" ? bodyB : bodyB.body;
if (!isNaN(length)) {
options.length = length;
}
options.stiffness = stiffness;
var constraint = Constraint.create(options);
this.world.add(constraint);
return constraint;
},
/**
* Constraints (or joints) are used for specifying that a fixed distance must be maintained
* between two bodies, or a body and a fixed world-space position.
*
* A world constraint has only one body, you should specify a `pointA` position in
* the constraint options parameter to attach the constraint to the world.
*
* The stiffness of constraints can be modified to create springs or elastic.
*
* To simulate a revolute constraint (or pin joint) set `length: 0` and a high `stiffness`
* value (e.g. `0.7` or above).
*
* If the constraint is unstable, try lowering the `stiffness` value and / or increasing
* `constraintIterations` within the Matter Config.
*
* For compound bodies, constraints must be applied to the parent body and not one of its parts.
*
* @method Phaser.Physics.Matter.Factory#worldConstraint
* @since 3.0.0
*
* @param {MatterJS.BodyType} body - The Matter `Body` that this constraint is attached to.
* @param {number} [length] - A number that specifies the target resting length of the constraint. If not given it is calculated automatically in `Constraint.create` from initial positions of the `constraint.bodyA` and `constraint.bodyB`.
* @param {number} [stiffness=1] - A Number that specifies the stiffness of the constraint, i.e. the rate at which it returns to its resting `constraint.length`. A value of `1` means the constraint should be very stiff. A value of `0.2` means the constraint acts as a soft spring.
* @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [options] - An optional Constraint configuration object that is used to set initial Constraint properties on creation.
*
* @return {MatterJS.ConstraintType} A Matter JS Constraint.
*/
worldConstraint: function(body, length, stiffness, options) {
if (stiffness === void 0) {
stiffness = 1;
}
if (options === void 0) {
options = {};
}
options.bodyB = body.type === "body" ? body : body.body;
if (!isNaN(length)) {
options.length = length;
}
options.stiffness = stiffness;
var constraint = Constraint.create(options);
this.world.add(constraint);
return constraint;
},
/**
* This method is an alias for `Factory.pointerConstraint`.
*
* A Pointer Constraint is a special type of constraint that allows you to click
* and drag bodies in a Matter World. It monitors the active Pointers in a Scene,
* and when one is pressed down it checks to see if that hit any part of any active
* body in the world. If it did, and the body has input enabled, it will begin to
* drag it until either released, or you stop it via the `stopDrag` method.
*
* You can adjust the stiffness, length and other properties of the constraint via
* the `options` object on creation.
*
* @method Phaser.Physics.Matter.Factory#mouseSpring
* @since 3.0.0
*
* @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [options] - An optional Constraint configuration object that is used to set initial Constraint properties on creation.
*
* @return {MatterJS.ConstraintType} A Matter JS Constraint.
*/
mouseSpring: function(options) {
return this.pointerConstraint(options);
},
/**
* A Pointer Constraint is a special type of constraint that allows you to click
* and drag bodies in a Matter World. It monitors the active Pointers in a Scene,
* and when one is pressed down it checks to see if that hit any part of any active
* body in the world. If it did, and the body has input enabled, it will begin to
* drag it until either released, or you stop it via the `stopDrag` method.
*
* You can adjust the stiffness, length and other properties of the constraint via
* the `options` object on creation.
*
* @method Phaser.Physics.Matter.Factory#pointerConstraint
* @since 3.0.0
*
* @param {Phaser.Types.Physics.Matter.MatterConstraintConfig} [options] - An optional Constraint configuration object that is used to set initial Constraint properties on creation.
*
* @return {MatterJS.ConstraintType} A Matter JS Constraint.
*/
pointerConstraint: function(options) {
if (options === void 0) {
options = {};
}
if (!options.hasOwnProperty("render")) {
options.render = { visible: false };
}
var pointerConstraint = new PointerConstraint(this.scene, this.world, options);
this.world.add(pointerConstraint.constraint);
return pointerConstraint;
},
/**
* Creates a Matter Physics Image Game Object.
*
* An Image is a light-weight Game Object useful for the display of static images in your game,
* such as logos, backgrounds, scenery or other non-animated elements. Images can have input
* events and physics bodies, or be tweened, tinted or scrolled. The main difference between an
* Image and a Sprite is that you cannot animate an Image as they do not have the Animation component.
*
* @method Phaser.Physics.Matter.Factory#image
* @since 3.0.0
*
* @param {number} x - The horizontal position of this Game Object in the world.
* @param {number} y - The vertical position of this Game Object in the world.
* @param {string} key - The key of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. Set to `null` to skip this value.
* @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation.
*
* @return {Phaser.Physics.Matter.Image} The Matter Image Game Object.
*/
image: function(x, y, key, frame, options) {
var image = new MatterImage(this.world, x, y, key, frame, options);
this.sys.displayList.add(image);
return image;
},
/**
* Creates a wrapper around a Tile that provides access to a corresponding Matter body. A tile can only
* have one Matter body associated with it. You can either pass in an existing Matter body for
* the tile or allow the constructor to create the corresponding body for you. If the Tile has a
* collision group (defined in Tiled), those shapes will be used to create the body. If not, the
* tile's rectangle bounding box will be used.
*
* The corresponding body will be accessible on the Tile itself via Tile.physics.matterBody.
*
* Note: not all Tiled collision shapes are supported. See
* Phaser.Physics.Matter.TileBody#setFromTileCollision for more information.
*
* @method Phaser.Physics.Matter.Factory#tileBody
* @since 3.0.0
*
* @param {Phaser.Tilemaps.Tile} tile - The target tile that should have a Matter body.
* @param {Phaser.Types.Physics.Matter.MatterTileOptions} [options] - Options to be used when creating the Matter body.
*
* @return {Phaser.Physics.Matter.TileBody} The Matter Tile Body Game Object.
*/
tileBody: function(tile, options) {
return new MatterTileBody(this.world, tile, options);
},
/**
* Creates a Matter Physics Sprite Game Object.
*
* A Sprite Game Object is used for the display of both static and animated images in your game.
* Sprites can have input events and physics bodies. They can also be tweened, tinted, scrolled
* and animated.
*
* The main difference between a Sprite and an Image Game Object is that you cannot animate Images.
* As such, Sprites take a fraction longer to process and have a larger API footprint due to the Animation
* Component. If you do not require animation then you can safely use Images to replace Sprites in all cases.
*
* @method Phaser.Physics.Matter.Factory#sprite
* @since 3.0.0
*
* @param {number} x - The horizontal position of this Game Object in the world.
* @param {number} y - The vertical position of this Game Object in the world.
* @param {string} key - The key of the Texture this Game Object will use to render with, as stored in the Texture Manager.
* @param {(string|number)} [frame] - An optional frame from the Texture this Game Object is rendering with. Set to `null` to skip this value.
* @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation.
*
* @return {Phaser.Physics.Matter.Sprite} The Matter Sprite Game Object.
*/
sprite: function(x, y, key, frame, options) {
var sprite = new MatterSprite(this.world, x, y, key, frame, options);
this.sys.displayList.add(sprite);
this.sys.updateList.add(sprite);
return sprite;
},
/**
* Takes an existing Game Object and injects all of the Matter Components into it.
*
* This enables you to use component methods such as `setVelocity` or `isSensor` directly from
* this Game Object.
*
* You can also pass in either a Matter Body Configuration object, or a Matter Body instance
* to link with this Game Object.
*
* @method Phaser.Physics.Matter.Factory#gameObject
* @since 3.3.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to inject the Matter Components in to.
* @param {(Phaser.Types.Physics.Matter.MatterBodyConfig|MatterJS.Body)} [options] - A Matter Body configuration object, or an instance of a Matter Body.
* @param {boolean} [addToWorld=true] - Add this Matter Body to the World?
*
* @return {(Phaser.Physics.Matter.Image|Phaser.Physics.Matter.Sprite|Phaser.GameObjects.GameObject)} The Game Object that had the Matter Components injected into it.
*/
gameObject: function(gameObject, options, addToWorld) {
return MatterGameObject(this.world, gameObject, options, addToWorld);
},
/**
* Destroys this Factory.
*
* @method Phaser.Physics.Matter.Factory#destroy
* @since 3.5.0
*/
destroy: function() {
this.world = null;
this.scene = null;
this.sys = null;
}
});
module2.exports = Factory;
}
),
/***/
75803: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Components = __webpack_require__2(31884);
var GetFastValue = __webpack_require__2(95540);
var Vector2 = __webpack_require__2(26099);
function hasGetterOrSetter(def) {
return !!def.get && typeof def.get === "function" || !!def.set && typeof def.set === "function";
}
var MatterGameObject = function(world, gameObject, options, addToWorld) {
if (options === void 0) {
options = {};
}
if (addToWorld === void 0) {
addToWorld = true;
}
var x = gameObject.x;
var y = gameObject.y;
gameObject.body = {
temp: true,
position: {
x,
y
}
};
var mixins = [
Components.Bounce,
Components.Collision,
Components.Force,
Components.Friction,
Components.Gravity,
Components.Mass,
Components.Sensor,
Components.SetBody,
Components.Sleep,
Components.Static,
Components.Transform,
Components.Velocity
];
mixins.forEach(function(mixin) {
for (var key in mixin) {
if (hasGetterOrSetter(mixin[key])) {
Object.defineProperty(gameObject, key, {
get: mixin[key].get,
set: mixin[key].set
});
} else {
Object.defineProperty(gameObject, key, { value: mixin[key] });
}
}
});
gameObject.world = world;
gameObject._tempVec2 = new Vector2(x, y);
if (options.hasOwnProperty("type") && options.type === "body") {
gameObject.setExistingBody(options, addToWorld);
} else {
var shape = GetFastValue(options, "shape", null);
if (!shape) {
shape = "rectangle";
}
options.addToWorld = addToWorld;
gameObject.setBody(shape, options);
}
return gameObject;
};
module2.exports = MatterGameObject;
}
),
/***/
23181: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31884);
var GameObject = __webpack_require__2(95643);
var GetFastValue = __webpack_require__2(95540);
var Image2 = __webpack_require__2(88571);
var Pipeline = __webpack_require__2(72699);
var Vector2 = __webpack_require__2(26099);
var MatterImage = new Class({
Extends: Image2,
Mixins: [
Components.Bounce,
Components.Collision,
Components.Force,
Components.Friction,
Components.Gravity,
Components.Mass,
Components.Sensor,
Components.SetBody,
Components.Sleep,
Components.Static,
Components.Transform,
Components.Velocity,
Pipeline
],
initialize: function MatterImage2(world, x, y, texture, frame, options) {
GameObject.call(this, world.scene, "Image");
this._crop = this.resetCropObject();
this.setTexture(texture, frame);
this.setSizeToFrame();
this.setOrigin();
this.world = world;
this._tempVec2 = new Vector2(x, y);
var shape = GetFastValue(options, "shape", null);
if (shape) {
this.setBody(shape, options);
} else {
this.setRectangle(this.width, this.height, options);
}
this.setPosition(x, y);
this.initPipeline();
this.initPostPipeline(true);
}
});
module2.exports = MatterImage;
}
),
/***/
42045: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var ALIGN_CONST = __webpack_require__2(60461);
var Axes = __webpack_require__2(66615);
var Bodies = __webpack_require__2(66280);
var Body = __webpack_require__2(22562);
var BodyBounds = __webpack_require__2(68174);
var Bounds = __webpack_require__2(15647);
var Class = __webpack_require__2(83419);
var Collision = __webpack_require__2(52284);
var Common = __webpack_require__2(53402);
var Composite = __webpack_require__2(69351);
var Composites = __webpack_require__2(74116);
var Constraint = __webpack_require__2(48140);
var Detector = __webpack_require__2(81388);
var DistanceBetween = __webpack_require__2(20339);
var Factory = __webpack_require__2(28137);
var GetFastValue = __webpack_require__2(95540);
var GetValue = __webpack_require__2(35154);
var Merge = __webpack_require__2(46975);
var Pair = __webpack_require__2(4506);
var Pairs = __webpack_require__2(99561);
var PluginCache = __webpack_require__2(37277);
var Query = __webpack_require__2(73296);
var Resolver = __webpack_require__2(66272);
var SceneEvents = __webpack_require__2(44594);
var Svg = __webpack_require__2(74058);
var Vector = __webpack_require__2(31725);
var Vertices = __webpack_require__2(41598);
var World = __webpack_require__2(68243);
Common.setDecomp(__webpack_require__2(55973));
var MatterPhysics = new Class({
initialize: function MatterPhysics2(scene) {
this.scene = scene;
this.systems = scene.sys;
this.config = this.getConfig();
this.world;
this.add;
this.bodyBounds;
this.body = Body;
this.composite = Composite;
this.collision = Collision;
this.detector = Detector;
this.pair = Pair;
this.pairs = Pairs;
this.query = Query;
this.resolver = Resolver;
this.constraint = Constraint;
this.bodies = Bodies;
this.composites = Composites;
this.axes = Axes;
this.bounds = Bounds;
this.svg = Svg;
this.vector = Vector;
this.vertices = Vertices;
this.verts = Vertices;
this._tempVec2 = Vector.create();
Resolver._restingThresh = GetValue(this.config, "restingThresh", 4);
Resolver._restingThreshTangent = GetValue(this.config, "restingThreshTangent", 6);
Resolver._positionDampen = GetValue(this.config, "positionDampen", 0.9);
Resolver._positionWarming = GetValue(this.config, "positionWarming", 0.8);
Resolver._frictionNormalMultiplier = GetValue(this.config, "frictionNormalMultiplier", 5);
scene.sys.events.once(SceneEvents.BOOT, this.boot, this);
scene.sys.events.on(SceneEvents.START, this.start, this);
},
/**
* This method is called automatically, only once, when the Scene is first created.
* Do not invoke it directly.
*
* @method Phaser.Physics.Matter.MatterPhysics#boot
* @private
* @since 3.5.1
*/
boot: function() {
this.world = new World(this.scene, this.config);
this.add = new Factory(this.world);
this.bodyBounds = new BodyBounds();
this.systems.events.once(SceneEvents.DESTROY, this.destroy, this);
},
/**
* This method is called automatically by the Scene when it is starting up.
* It is responsible for creating local systems, properties and listening for Scene events.
* Do not invoke it directly.
*
* @method Phaser.Physics.Matter.MatterPhysics#start
* @private
* @since 3.5.0
*/
start: function() {
if (!this.world) {
this.world = new World(this.scene, this.config);
this.add = new Factory(this.world);
}
var eventEmitter = this.systems.events;
eventEmitter.on(SceneEvents.UPDATE, this.world.update, this.world);
eventEmitter.on(SceneEvents.POST_UPDATE, this.world.postUpdate, this.world);
eventEmitter.once(SceneEvents.SHUTDOWN, this.shutdown, this);
},
/**
* This internal method is called when this class starts and retrieves the final Matter World Config.
*
* @method Phaser.Physics.Matter.MatterPhysics#getConfig
* @since 3.0.0
*
* @return {Phaser.Types.Physics.Matter.MatterWorldConfig} The Matter World Config.
*/
getConfig: function() {
var gameConfig = this.systems.game.config.physics;
var sceneConfig = this.systems.settings.physics;
var config = Merge(
GetFastValue(sceneConfig, "matter", {}),
GetFastValue(gameConfig, "matter", {})
);
return config;
},
/**
* Pauses the Matter World instance and sets `enabled` to `false`.
*
* A paused world will not run any simulations for the duration it is paused.
*
* @method Phaser.Physics.Matter.MatterPhysics#pause
* @fires Phaser.Physics.Matter.Events#PAUSE
* @since 3.0.0
*
* @return {Phaser.Physics.Matter.World} The Matter World object.
*/
pause: function() {
return this.world.pause();
},
/**
* Resumes this Matter World instance from a paused state and sets `enabled` to `true`.
*
* @method Phaser.Physics.Matter.MatterPhysics#resume
* @since 3.0.0
*
* @return {Phaser.Physics.Matter.World} The Matter World object.
*/
resume: function() {
return this.world.resume();
},
/**
* Sets the Matter Engine to run at fixed timestep of 60Hz and enables `autoUpdate`.
* If you have set a custom `getDelta` function then this will override it.
*
* @method Phaser.Physics.Matter.MatterPhysics#set60Hz
* @since 3.4.0
*
* @return {this} This Matter Physics instance.
*/
set60Hz: function() {
this.world.getDelta = this.world.update60Hz;
this.world.autoUpdate = true;
return this;
},
/**
* Sets the Matter Engine to run at fixed timestep of 30Hz and enables `autoUpdate`.
* If you have set a custom `getDelta` function then this will override it.
*
* @method Phaser.Physics.Matter.MatterPhysics#set30Hz
* @since 3.4.0
*
* @return {this} This Matter Physics instance.
*/
set30Hz: function() {
this.world.getDelta = this.world.update30Hz;
this.world.autoUpdate = true;
return this;
},
/**
* Manually advances the physics simulation by one iteration.
*
* You can optionally pass in the `delta` and `correction` values to be used by Engine.update.
* If undefined they use the Matter defaults of 60Hz and no correction.
*
* Calling `step` directly bypasses any checks of `enabled` or `autoUpdate`.
*
* It also ignores any custom `getDelta` functions, as you should be passing the delta
* value in to this call.
*
* You can adjust the number of iterations that Engine.update performs internally.
* Use the Scene Matter Physics config object to set the following properties:
*
* positionIterations (defaults to 6)
* velocityIterations (defaults to 4)
* constraintIterations (defaults to 2)
*
* Adjusting these values can help performance in certain situations, depending on the physics requirements
* of your game.
*
* @method Phaser.Physics.Matter.MatterPhysics#step
* @since 3.4.0
*
* @param {number} [delta=16.666] - The delta value.
* @param {number} [correction=1] - Optional delta correction value.
*/
step: function(delta, correction) {
this.world.step(delta, correction);
},
/**
* Checks if the vertices of the given body, or an array of bodies, contains the given point, or not.
*
* You can pass in either a single body, or an array of bodies to be checked. This method will
* return `true` if _any_ of the bodies in the array contain the point. See the `intersectPoint` method if you need
* to get a list of intersecting bodies.
*
* The point should be transformed into the Matter World coordinate system in advance. This happens by
* default with Input Pointers, but if you wish to use points from another system you may need to
* transform them before passing them.
*
* @method Phaser.Physics.Matter.MatterPhysics#containsPoint
* @since 3.22.0
*
* @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} body - The body, or an array of bodies, to check against the point.
* @param {number} x - The horizontal coordinate of the point.
* @param {number} y - The vertical coordinate of the point.
*
* @return {boolean} `true` if the point is within one of the bodies given, otherwise `false`.
*/
containsPoint: function(body, x, y) {
body = this.getMatterBodies(body);
var position = Vector.create(x, y);
var result = Query.point(body, position);
return result.length > 0 ? true : false;
},
/**
* Checks the given coordinates to see if any vertices of the given bodies contain it.
*
* If no bodies are provided it will search all bodies in the Matter World, including within Composites.
*
* The coordinates should be transformed into the Matter World coordinate system in advance. This happens by
* default with Input Pointers, but if you wish to use coordinates from another system you may need to
* transform them before passing them.
*
* @method Phaser.Physics.Matter.MatterPhysics#intersectPoint
* @since 3.22.0
*
* @param {number} x - The horizontal coordinate of the point.
* @param {number} y - The vertical coordinate of the point.
* @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - An array of bodies to check. If not provided it will search all bodies in the world.
*
* @return {Phaser.Types.Physics.Matter.MatterBody[]} An array of bodies which contain the given point.
*/
intersectPoint: function(x, y, bodies) {
bodies = this.getMatterBodies(bodies);
var position = Vector.create(x, y);
var output = [];
var result = Query.point(bodies, position);
result.forEach(function(body) {
if (output.indexOf(body) === -1) {
output.push(body);
}
});
return output;
},
/**
* Checks the given rectangular area to see if any vertices of the given bodies intersect with it.
* Or, if the `outside` parameter is set to `true`, it checks to see which bodies do not
* intersect with it.
*
* If no bodies are provided it will search all bodies in the Matter World, including within Composites.
*
* @method Phaser.Physics.Matter.MatterPhysics#intersectRect
* @since 3.22.0
*
* @param {number} x - The horizontal coordinate of the top-left of the area.
* @param {number} y - The vertical coordinate of the top-left of the area.
* @param {number} width - The width of the area.
* @param {number} height - The height of the area.
* @param {boolean} [outside=false] - If `false` it checks for vertices inside the area, if `true` it checks for vertices outside the area.
* @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - An array of bodies to check. If not provided it will search all bodies in the world.
*
* @return {Phaser.Types.Physics.Matter.MatterBody[]} An array of bodies that intersect with the given area.
*/
intersectRect: function(x, y, width, height, outside, bodies) {
if (outside === void 0) {
outside = false;
}
bodies = this.getMatterBodies(bodies);
var bounds = {
min: { x, y },
max: { x: x + width, y: y + height }
};
var output = [];
var result = Query.region(bodies, bounds, outside);
result.forEach(function(body) {
if (output.indexOf(body) === -1) {
output.push(body);
}
});
return output;
},
/**
* Checks the given ray segment to see if any vertices of the given bodies intersect with it.
*
* If no bodies are provided it will search all bodies in the Matter World.
*
* The width of the ray can be specified via the `rayWidth` parameter.
*
* @method Phaser.Physics.Matter.MatterPhysics#intersectRay
* @since 3.22.0
*
* @param {number} x1 - The horizontal coordinate of the start of the ray segment.
* @param {number} y1 - The vertical coordinate of the start of the ray segment.
* @param {number} x2 - The horizontal coordinate of the end of the ray segment.
* @param {number} y2 - The vertical coordinate of the end of the ray segment.
* @param {number} [rayWidth=1] - The width of the ray segment.
* @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - An array of bodies to check. If not provided it will search all bodies in the world.
*
* @return {Phaser.Types.Physics.Matter.MatterBody[]} An array of bodies whos vertices intersect with the ray segment.
*/
intersectRay: function(x1, y1, x2, y2, rayWidth, bodies) {
if (rayWidth === void 0) {
rayWidth = 1;
}
bodies = this.getMatterBodies(bodies);
var result = [];
var collisions = Query.ray(bodies, Vector.create(x1, y1), Vector.create(x2, y2), rayWidth);
for (var i = 0; i < collisions.length; i++) {
result.push(collisions[i].body);
}
return result;
},
/**
* Checks the given Matter Body to see if it intersects with any of the given bodies.
*
* If no bodies are provided it will check against all bodies in the Matter World.
*
* @method Phaser.Physics.Matter.MatterPhysics#intersectBody
* @since 3.22.0
*
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The target body.
* @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - An array of bodies to check the target body against. If not provided it will search all bodies in the world.
*
* @return {Phaser.Types.Physics.Matter.MatterBody[]} An array of bodies whos vertices intersect with target body.
*/
intersectBody: function(body, bodies) {
bodies = this.getMatterBodies(bodies);
var result = [];
var collisions = Query.collides(body, bodies);
for (var i = 0; i < collisions.length; i++) {
var pair = collisions[i];
if (pair.bodyA === body) {
result.push(pair.bodyB);
} else {
result.push(pair.bodyA);
}
}
return result;
},
/**
* Checks to see if the target body, or an array of target bodies, intersects with any of the given bodies.
*
* If intersection occurs this method will return `true` and, if provided, invoke the callbacks.
*
* If no bodies are provided for the second parameter the target will check against all bodies in the Matter World.
*
* **Note that bodies can only overlap if they are in non-colliding collision groups or categories.**
*
* If you provide a `processCallback` then the two bodies that overlap are sent to it. This callback
* must return a boolean and is used to allow you to perform additional processing tests before a final
* outcome is decided. If it returns `true` then the bodies are finally passed to the `overlapCallback`, if set.
*
* If you provide an `overlapCallback` then the matching pairs of overlapping bodies will be sent to it.
*
* Both callbacks have the following signature: `function (bodyA, bodyB, collisionInfo)` where `bodyA` is always
* the target body. The `collisionInfo` object contains additional data, such as the angle and depth of penetration.
*
* @method Phaser.Physics.Matter.MatterPhysics#overlap
* @since 3.22.0
*
* @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} target - The target body, or array of target bodies, to check.
* @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - The second body, or array of bodies, to check. If falsey it will check against all bodies in the world.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [overlapCallback] - An optional callback function that is called if the bodies overlap.
* @param {Phaser.Types.Physics.Arcade.ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two bodies if they overlap. If this is set then `overlapCallback` will only be invoked if this callback returns `true`.
* @param {*} [callbackContext] - The context, or scope, in which to run the callbacks.
*
* @return {boolean} `true` if the target body intersects with _any_ of the bodies given, otherwise `false`.
*/
overlap: function(target, bodies, overlapCallback, processCallback, callbackContext) {
if (overlapCallback === void 0) {
overlapCallback = null;
}
if (processCallback === void 0) {
processCallback = null;
}
if (callbackContext === void 0) {
callbackContext = overlapCallback;
}
if (!Array.isArray(target)) {
target = [target];
}
target = this.getMatterBodies(target);
bodies = this.getMatterBodies(bodies);
var match = false;
for (var i = 0; i < target.length; i++) {
var entry = target[i];
var collisions = Query.collides(entry, bodies);
for (var c = 0; c < collisions.length; c++) {
var info = collisions[c];
var bodyB = info.bodyA.id === entry.id ? info.bodyB : info.bodyA;
if (!processCallback || processCallback.call(callbackContext, entry, bodyB, info)) {
match = true;
if (overlapCallback) {
overlapCallback.call(callbackContext, entry, bodyB, info);
} else if (!processCallback) {
return true;
}
}
}
}
return match;
},
/**
* Sets the collision filter category of all given Matter Bodies to the given value.
*
* This number must be a power of two between 2^0 (= 1) and 2^31.
*
* Bodies with different collision groups (see {@link #setCollisionGroup}) will only collide if their collision
* categories are included in their collision masks (see {@link #setCollidesWith}).
*
* @method Phaser.Physics.Matter.MatterPhysics#setCollisionCategory
* @since 3.22.0
*
* @param {Phaser.Types.Physics.Matter.MatterBody[]} bodies - An array of bodies to update. If falsey it will use all bodies in the world.
* @param {number} value - Unique category bitfield.
*
* @return {this} This Matter Physics instance.
*/
setCollisionCategory: function(bodies, value) {
bodies = this.getMatterBodies(bodies);
bodies.forEach(function(body) {
body.collisionFilter.category = value;
});
return this;
},
/**
* Sets the collision filter group of all given Matter Bodies to the given value.
*
* If the group value is zero, or if two Matter Bodies have different group values,
* they will collide according to the usual collision filter rules (see {@link #setCollisionCategory} and {@link #setCollisionGroup}).
*
* If two Matter Bodies have the same positive group value, they will always collide;
* if they have the same negative group value they will never collide.
*
* @method Phaser.Physics.Matter.MatterPhysics#setCollisionGroup
* @since 3.22.0
*
* @param {Phaser.Types.Physics.Matter.MatterBody[]} bodies - An array of bodies to update. If falsey it will use all bodies in the world.
* @param {number} value - Unique group index.
*
* @return {this} This Matter Physics instance.
*/
setCollisionGroup: function(bodies, value) {
bodies = this.getMatterBodies(bodies);
bodies.forEach(function(body) {
body.collisionFilter.group = value;
});
return this;
},
/**
* Sets the collision filter mask of all given Matter Bodies to the given value.
*
* Two Matter Bodies with different collision groups will only collide if each one includes the others
* category in its mask based on a bitwise AND operation: `(categoryA & maskB) !== 0` and
* `(categoryB & maskA) !== 0` are both true.
*
* @method Phaser.Physics.Matter.MatterPhysics#setCollidesWith
* @since 3.22.0
*
* @param {Phaser.Types.Physics.Matter.MatterBody[]} bodies - An array of bodies to update. If falsey it will use all bodies in the world.
* @param {(number|number[])} categories - A unique category bitfield, or an array of them.
*
* @return {this} This Matter Physics instance.
*/
setCollidesWith: function(bodies, categories) {
bodies = this.getMatterBodies(bodies);
var flags = 0;
if (!Array.isArray(categories)) {
flags = categories;
} else {
for (var i = 0; i < categories.length; i++) {
flags |= categories[i];
}
}
bodies.forEach(function(body) {
body.collisionFilter.mask = flags;
});
return this;
},
/**
* Takes an array and returns a new array made from all of the Matter Bodies found in the original array.
*
* For example, passing in Matter Game Objects, such as a bunch of Matter Sprites, to this method, would
* return an array containing all of their native Matter Body objects.
*
* If the `bodies` argument is falsey, it will return all bodies in the world.
*
* @method Phaser.Physics.Matter.MatterPhysics#getMatterBodies
* @since 3.22.0
*
* @param {array} [bodies] - An array of objects to extract the bodies from. If falsey, it will return all bodies in the world.
*
* @return {MatterJS.BodyType[]} An array of native Matter Body objects.
*/
getMatterBodies: function(bodies) {
if (!bodies) {
return this.world.getAllBodies();
}
if (!Array.isArray(bodies)) {
bodies = [bodies];
}
var output = [];
for (var i = 0; i < bodies.length; i++) {
var body = bodies[i].hasOwnProperty("body") ? bodies[i].body : bodies[i];
output.push(body);
}
return output;
},
/**
* Sets both the horizontal and vertical linear velocity of the physics bodies.
*
* @method Phaser.Physics.Matter.MatterPhysics#setVelocity
* @since 3.22.0
*
* @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world.
* @param {number} x - The horizontal linear velocity value.
* @param {number} y - The vertical linear velocity value.
*
* @return {this} This Matter Physics instance.
*/
setVelocity: function(bodies, x, y) {
bodies = this.getMatterBodies(bodies);
var vec2 = this._tempVec2;
vec2.x = x;
vec2.y = y;
bodies.forEach(function(body) {
Body.setVelocity(body, vec2);
});
return this;
},
/**
* Sets just the horizontal linear velocity of the physics bodies.
* The vertical velocity of the body is unchanged.
*
* @method Phaser.Physics.Matter.MatterPhysics#setVelocityX
* @since 3.22.0
*
* @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world.
* @param {number} x - The horizontal linear velocity value.
*
* @return {this} This Matter Physics instance.
*/
setVelocityX: function(bodies, x) {
bodies = this.getMatterBodies(bodies);
var vec2 = this._tempVec2;
vec2.x = x;
bodies.forEach(function(body) {
vec2.y = body.velocity.y;
Body.setVelocity(body, vec2);
});
return this;
},
/**
* Sets just the vertical linear velocity of the physics bodies.
* The horizontal velocity of the body is unchanged.
*
* @method Phaser.Physics.Matter.MatterPhysics#setVelocityY
* @since 3.22.0
*
* @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world.
* @param {number} y - The vertical linear velocity value.
*
* @return {this} This Matter Physics instance.
*/
setVelocityY: function(bodies, y) {
bodies = this.getMatterBodies(bodies);
var vec2 = this._tempVec2;
vec2.y = y;
bodies.forEach(function(body) {
vec2.x = body.velocity.x;
Body.setVelocity(body, vec2);
});
return this;
},
/**
* Sets the angular velocity of the bodies instantly.
* Position, angle, force etc. are unchanged.
*
* @method Phaser.Physics.Matter.MatterPhysics#setAngularVelocity
* @since 3.22.0
*
* @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world.
* @param {number} value - The angular velocity.
*
* @return {this} This Matter Physics instance.
*/
setAngularVelocity: function(bodies, value) {
bodies = this.getMatterBodies(bodies);
bodies.forEach(function(body) {
Body.setAngularVelocity(body, value);
});
return this;
},
/**
* Applies a force to a body, at the bodies current position, including resulting torque.
*
* @method Phaser.Physics.Matter.MatterPhysics#applyForce
* @since 3.22.0
*
* @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world.
* @param {Phaser.Types.Math.Vector2Like} force - A Vector that specifies the force to apply.
*
* @return {this} This Matter Physics instance.
*/
applyForce: function(bodies, force) {
bodies = this.getMatterBodies(bodies);
var vec2 = this._tempVec2;
bodies.forEach(function(body) {
vec2.x = body.position.x;
vec2.y = body.position.y;
Body.applyForce(body, vec2, force);
});
return this;
},
/**
* Applies a force to a body, from the given world position, including resulting torque.
* If no angle is given, the current body angle is used.
*
* Use very small speed values, such as 0.1, depending on the mass and required velocity.
*
* @method Phaser.Physics.Matter.MatterPhysics#applyForceFromPosition
* @since 3.22.0
*
* @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world.
* @param {Phaser.Types.Math.Vector2Like} position - A Vector that specifies the world-space position to apply the force at.
* @param {number} speed - A speed value to be applied to a directional force.
* @param {number} [angle] - The angle, in radians, to apply the force from. Leave undefined to use the current body angle.
*
* @return {this} This Matter Physics instance.
*/
applyForceFromPosition: function(bodies, position, speed, angle) {
bodies = this.getMatterBodies(bodies);
var vec2 = this._tempVec2;
bodies.forEach(function(body) {
if (angle === void 0) {
angle = body.angle;
}
vec2.x = speed * Math.cos(angle);
vec2.y = speed * Math.sin(angle);
Body.applyForce(body, position, vec2);
});
return this;
},
/**
* Apply a force to a body based on the given angle and speed.
* If no angle is given, the current body angle is used.
*
* Use very small speed values, such as 0.1, depending on the mass and required velocity.
*
* @method Phaser.Physics.Matter.MatterPhysics#applyForceFromAngle
* @since 3.22.0
*
* @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world.
* @param {number} speed - A speed value to be applied to a directional force.
* @param {number} [angle] - The angle, in radians, to apply the force from. Leave undefined to use the current body angle.
*
* @return {this} This Matter Physics instance.
*/
applyForceFromAngle: function(bodies, speed, angle) {
bodies = this.getMatterBodies(bodies);
var vec2 = this._tempVec2;
bodies.forEach(function(body) {
if (angle === void 0) {
angle = body.angle;
}
vec2.x = speed * Math.cos(angle);
vec2.y = speed * Math.sin(angle);
Body.applyForce(body, { x: body.position.x, y: body.position.y }, vec2);
});
return this;
},
/**
* Returns the length of the given constraint, which is the distance between the two points.
*
* @method Phaser.Physics.Matter.MatterPhysics#getConstraintLength
* @since 3.22.0
*
* @param {MatterJS.ConstraintType} constraint - The constraint to get the length from.
*
* @return {number} The length of the constraint.
*/
getConstraintLength: function(constraint) {
var aX = constraint.pointA.x;
var aY = constraint.pointA.y;
var bX = constraint.pointB.x;
var bY = constraint.pointB.y;
if (constraint.bodyA) {
aX += constraint.bodyA.position.x;
aY += constraint.bodyA.position.y;
}
if (constraint.bodyB) {
bX += constraint.bodyB.position.x;
bY += constraint.bodyB.position.y;
}
return DistanceBetween(aX, aY, bX, bY);
},
/**
* Aligns a Body, or Matter Game Object, against the given coordinates.
*
* The alignment takes place using the body bounds, which take into consideration things
* like body scale and rotation.
*
* Although a Body has a `position` property, it is based on the center of mass for the body,
* not a dimension based center. This makes aligning bodies difficult, especially if they have
* rotated or scaled. This method will derive the correct position based on the body bounds and
* its center of mass offset, in order to align the body with the given coordinate.
*
* For example, if you wanted to align a body so it sat in the bottom-center of the
* Scene, and the world was 800 x 600 in size:
*
* ```javascript
* this.matter.alignBody(body, 400, 600, Phaser.Display.Align.BOTTOM_CENTER);
* ```
*
* You pass in 400 for the x coordinate, because that is the center of the world, and 600 for
* the y coordinate, as that is the base of the world.
*
* @method Phaser.Physics.Matter.MatterPhysics#alignBody
* @since 3.22.0
*
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to align.
* @param {number} x - The horizontal position to align the body to.
* @param {number} y - The vertical position to align the body to.
* @param {number} align - One of the `Phaser.Display.Align` constants, such as `Phaser.Display.Align.TOP_LEFT`.
*
* @return {this} This Matter Physics instance.
*/
alignBody: function(body, x, y, align) {
body = body.hasOwnProperty("body") ? body.body : body;
var pos;
switch (align) {
case ALIGN_CONST.TOP_LEFT:
case ALIGN_CONST.LEFT_TOP:
pos = this.bodyBounds.getTopLeft(body, x, y);
break;
case ALIGN_CONST.TOP_CENTER:
pos = this.bodyBounds.getTopCenter(body, x, y);
break;
case ALIGN_CONST.TOP_RIGHT:
case ALIGN_CONST.RIGHT_TOP:
pos = this.bodyBounds.getTopRight(body, x, y);
break;
case ALIGN_CONST.LEFT_CENTER:
pos = this.bodyBounds.getLeftCenter(body, x, y);
break;
case ALIGN_CONST.CENTER:
pos = this.bodyBounds.getCenter(body, x, y);
break;
case ALIGN_CONST.RIGHT_CENTER:
pos = this.bodyBounds.getRightCenter(body, x, y);
break;
case ALIGN_CONST.LEFT_BOTTOM:
case ALIGN_CONST.BOTTOM_LEFT:
pos = this.bodyBounds.getBottomLeft(body, x, y);
break;
case ALIGN_CONST.BOTTOM_CENTER:
pos = this.bodyBounds.getBottomCenter(body, x, y);
break;
case ALIGN_CONST.BOTTOM_RIGHT:
case ALIGN_CONST.RIGHT_BOTTOM:
pos = this.bodyBounds.getBottomRight(body, x, y);
break;
}
if (pos) {
Body.setPosition(body, pos);
}
return this;
},
/**
* The Scene that owns this plugin is shutting down.
* We need to kill and reset all internal properties as well as stop listening to Scene events.
*
* @method Phaser.Physics.Matter.MatterPhysics#shutdown
* @private
* @since 3.0.0
*/
shutdown: function() {
var eventEmitter = this.systems.events;
if (this.world) {
eventEmitter.off(SceneEvents.UPDATE, this.world.update, this.world);
eventEmitter.off(SceneEvents.POST_UPDATE, this.world.postUpdate, this.world);
}
eventEmitter.off(SceneEvents.SHUTDOWN, this.shutdown, this);
if (this.add) {
this.add.destroy();
}
if (this.world) {
this.world.destroy();
}
this.add = null;
this.world = null;
},
/**
* The Scene that owns this plugin is being destroyed.
* We need to shutdown and then kill off all external references.
*
* @method Phaser.Physics.Matter.MatterPhysics#destroy
* @private
* @since 3.0.0
*/
destroy: function() {
this.shutdown();
this.scene.sys.events.off(SceneEvents.START, this.start, this);
this.scene = null;
this.systems = null;
}
});
PluginCache.register("MatterPhysics", MatterPhysics, "matterPhysics");
module2.exports = MatterPhysics;
}
),
/***/
34803: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var AnimationState = __webpack_require__2(9674);
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31884);
var GameObject = __webpack_require__2(95643);
var GetFastValue = __webpack_require__2(95540);
var Pipeline = __webpack_require__2(72699);
var Sprite = __webpack_require__2(68287);
var Vector2 = __webpack_require__2(26099);
var MatterSprite = new Class({
Extends: Sprite,
Mixins: [
Components.Bounce,
Components.Collision,
Components.Force,
Components.Friction,
Components.Gravity,
Components.Mass,
Components.Sensor,
Components.SetBody,
Components.Sleep,
Components.Static,
Components.Transform,
Components.Velocity,
Pipeline
],
initialize: function MatterSprite2(world, x, y, texture, frame, options) {
GameObject.call(this, world.scene, "Sprite");
this._crop = this.resetCropObject();
this.anims = new AnimationState(this);
this.setTexture(texture, frame);
this.setSizeToFrame();
this.setOrigin();
this.world = world;
this._tempVec2 = new Vector2(x, y);
var shape = GetFastValue(options, "shape", null);
if (shape) {
this.setBody(shape, options);
} else {
this.setRectangle(this.width, this.height, options);
}
this.setPosition(x, y);
this.initPipeline();
this.initPostPipeline(true);
}
});
module2.exports = MatterSprite;
}
),
/***/
73834: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Bodies = __webpack_require__2(66280);
var Body = __webpack_require__2(22562);
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31884);
var DeepCopy = __webpack_require__2(62644);
var EventEmitter = __webpack_require__2(50792);
var GetFastValue = __webpack_require__2(95540);
var HasValue = __webpack_require__2(97022);
var Vertices = __webpack_require__2(41598);
var MatterTileBody = new Class({
Extends: EventEmitter,
Mixins: [
Components.Bounce,
Components.Collision,
Components.Friction,
Components.Gravity,
Components.Mass,
Components.Sensor,
Components.Sleep,
Components.Static
],
initialize: function MatterTileBody2(world, tile, options) {
EventEmitter.call(this);
this.tile = tile;
this.world = world;
if (tile.physics.matterBody) {
tile.physics.matterBody.destroy();
}
tile.physics.matterBody = this;
var body = GetFastValue(options, "body", null);
var addToWorld = GetFastValue(options, "addToWorld", true);
if (!body) {
var collisionGroup = tile.getCollisionGroup();
var collisionObjects = GetFastValue(collisionGroup, "objects", []);
if (collisionObjects.length > 0) {
this.setFromTileCollision(options);
} else {
this.setFromTileRectangle(options);
}
} else {
this.setBody(body, addToWorld);
}
if (tile.flipX || tile.flipY) {
var rotationPoint = { x: tile.getCenterX(), y: tile.getCenterY() };
var scaleX = tile.flipX ? -1 : 1;
var scaleY = tile.flipY ? -1 : 1;
Body.scale(body, scaleX, scaleY, rotationPoint);
}
},
/**
* Sets the current body to a rectangle that matches the bounds of the tile.
*
* @method Phaser.Physics.Matter.TileBody#setFromTileRectangle
* @since 3.0.0
*
* @param {Phaser.Types.Physics.Matter.MatterBodyTileOptions} [options] - Options to be used when creating the Matter body. See MatterJS.Body for a list of what Matter accepts.
*
* @return {Phaser.Physics.Matter.TileBody} This TileBody object.
*/
setFromTileRectangle: function(options) {
if (options === void 0) {
options = {};
}
if (!HasValue(options, "isStatic")) {
options.isStatic = true;
}
if (!HasValue(options, "addToWorld")) {
options.addToWorld = true;
}
var bounds = this.tile.getBounds();
var cx = bounds.x + bounds.width / 2;
var cy = bounds.y + bounds.height / 2;
var body = Bodies.rectangle(cx, cy, bounds.width, bounds.height, options);
this.setBody(body, options.addToWorld);
return this;
},
/**
* Sets the current body from the collision group associated with the Tile. This is typically
* set up in Tiled's collision editor.
*
* Note: Matter doesn't support all shapes from Tiled. Rectangles and polygons are directly
* supported. Ellipses are converted into circle bodies. Polylines are treated as if they are
* closed polygons. If a tile has multiple shapes, a multi-part body will be created. Concave
* shapes are supported if poly-decomp library is included. Decomposition is not guaranteed to
* work for complex shapes (e.g. holes), so it's often best to manually decompose a concave
* polygon into multiple convex polygons yourself.
*
* @method Phaser.Physics.Matter.TileBody#setFromTileCollision
* @since 3.0.0
*
* @param {Phaser.Types.Physics.Matter.MatterBodyTileOptions} [options] - Options to be used when creating the Matter body. See MatterJS.Body for a list of what Matter accepts.
*
* @return {Phaser.Physics.Matter.TileBody} This TileBody object.
*/
setFromTileCollision: function(options) {
if (options === void 0) {
options = {};
}
if (!HasValue(options, "isStatic")) {
options.isStatic = true;
}
if (!HasValue(options, "addToWorld")) {
options.addToWorld = true;
}
var sx = this.tile.tilemapLayer.scaleX;
var sy = this.tile.tilemapLayer.scaleY;
var tileX = this.tile.getLeft();
var tileY = this.tile.getTop();
var collisionGroup = this.tile.getCollisionGroup();
var collisionObjects = GetFastValue(collisionGroup, "objects", []);
var parts = [];
for (var i = 0; i < collisionObjects.length; i++) {
var object = collisionObjects[i];
var ox = tileX + object.x * sx;
var oy = tileY + object.y * sy;
var ow = object.width * sx;
var oh = object.height * sy;
var body = null;
if (object.rectangle) {
body = Bodies.rectangle(ox + ow / 2, oy + oh / 2, ow, oh, options);
} else if (object.ellipse) {
body = Bodies.circle(ox + ow / 2, oy + oh / 2, ow / 2, options);
} else if (object.polygon || object.polyline) {
var originalPoints = object.polygon ? object.polygon : object.polyline;
var points = originalPoints.map(function(p) {
return { x: p.x * sx, y: p.y * sy };
});
var vertices = Vertices.create(points);
var center = Vertices.centre(vertices);
ox += center.x;
oy += center.y;
body = Bodies.fromVertices(ox, oy, vertices, options);
}
if (body) {
parts.push(body);
}
}
if (parts.length === 1) {
this.setBody(parts[0], options.addToWorld);
} else if (parts.length > 1) {
var tempOptions = DeepCopy(options);
tempOptions.parts = parts;
this.setBody(Body.create(tempOptions), tempOptions.addToWorld);
}
return this;
},
/**
* Sets the current body to the given body. This will remove the previous body, if one already
* exists.
*
* @method Phaser.Physics.Matter.TileBody#setBody
* @since 3.0.0
*
* @param {MatterJS.BodyType} body - The new Matter body to use.
* @param {boolean} [addToWorld=true] - Whether or not to add the body to the Matter world.
*
* @return {Phaser.Physics.Matter.TileBody} This TileBody object.
*/
setBody: function(body, addToWorld) {
if (addToWorld === void 0) {
addToWorld = true;
}
if (this.body) {
this.removeBody();
}
this.body = body;
this.body.gameObject = this;
if (addToWorld) {
this.world.add(this.body);
}
return this;
},
/**
* Removes the current body from the TileBody and from the Matter world
*
* @method Phaser.Physics.Matter.TileBody#removeBody
* @since 3.0.0
*
* @return {Phaser.Physics.Matter.TileBody} This TileBody object.
*/
removeBody: function() {
if (this.body) {
this.world.remove(this.body);
this.body.gameObject = void 0;
this.body = void 0;
}
return this;
},
/**
* Removes the current body from the tile and the world.
*
* @method Phaser.Physics.Matter.TileBody#destroy
* @since 3.0.0
*
* @return {Phaser.Physics.Matter.TileBody} This TileBody object.
*/
destroy: function() {
this.removeBody();
this.tile.physics.matterBody = void 0;
this.removeAllListeners();
}
});
module2.exports = MatterTileBody;
}
),
/***/
19496: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Bodies = __webpack_require__2(66280);
var Body = __webpack_require__2(22562);
var Common = __webpack_require__2(53402);
var GetFastValue = __webpack_require__2(95540);
var Vertices = __webpack_require__2(41598);
var PhysicsEditorParser = {
/**
* Parses a body element exported by PhysicsEditor.
*
* @function Phaser.Physics.Matter.PhysicsEditorParser.parseBody
* @since 3.10.0
*
* @param {number} x - The horizontal world location of the body.
* @param {number} y - The vertical world location of the body.
* @param {object} config - The body configuration and fixture (child body) definitions, as exported by PhysicsEditor.
* @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation.
*
* @return {MatterJS.BodyType} A compound Matter JS Body.
*/
parseBody: function(x, y, config, options) {
if (options === void 0) {
options = {};
}
var fixtureConfigs = GetFastValue(config, "fixtures", []);
var fixtures = [];
for (var fc = 0; fc < fixtureConfigs.length; fc++) {
var fixtureParts = this.parseFixture(fixtureConfigs[fc]);
for (var i = 0; i < fixtureParts.length; i++) {
fixtures.push(fixtureParts[i]);
}
}
var matterConfig = Common.clone(config, true);
Common.extend(matterConfig, options, true);
delete matterConfig.fixtures;
delete matterConfig.type;
var body = Body.create(matterConfig);
Body.setParts(body, fixtures);
Body.setPosition(body, { x, y });
return body;
},
/**
* Parses an element of the "fixtures" list exported by PhysicsEditor
*
* @function Phaser.Physics.Matter.PhysicsEditorParser.parseFixture
* @since 3.10.0
*
* @param {object} fixtureConfig - The fixture object to parse.
*
* @return {MatterJS.BodyType[]} - An array of Matter JS Bodies.
*/
parseFixture: function(fixtureConfig) {
var matterConfig = Common.extend({}, false, fixtureConfig);
delete matterConfig.circle;
delete matterConfig.vertices;
var fixtures;
if (fixtureConfig.circle) {
var x = GetFastValue(fixtureConfig.circle, "x");
var y = GetFastValue(fixtureConfig.circle, "y");
var r = GetFastValue(fixtureConfig.circle, "radius");
fixtures = [Bodies.circle(x, y, r, matterConfig)];
} else if (fixtureConfig.vertices) {
fixtures = this.parseVertices(fixtureConfig.vertices, matterConfig);
}
return fixtures;
},
/**
* Parses the "vertices" lists exported by PhysicsEditor.
*
* @function Phaser.Physics.Matter.PhysicsEditorParser.parseVertices
* @since 3.10.0
*
* @param {array} vertexSets - The vertex lists to parse.
* @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation.
*
* @return {MatterJS.BodyType[]} - An array of Matter JS Bodies.
*/
parseVertices: function(vertexSets, options) {
if (options === void 0) {
options = {};
}
var parts = [];
for (var v = 0; v < vertexSets.length; v++) {
Vertices.clockwiseSort(vertexSets[v]);
parts.push(Body.create(Common.extend({
position: Vertices.centre(vertexSets[v]),
vertices: vertexSets[v]
}, options)));
}
return Bodies.flagCoincidentParts(parts);
}
};
module2.exports = PhysicsEditorParser;
}
),
/***/
85791: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Bodies = __webpack_require__2(66280);
var Body = __webpack_require__2(22562);
var PhysicsJSONParser = {
/**
* Parses a body element from the given JSON data.
*
* @function Phaser.Physics.Matter.PhysicsJSONParser.parseBody
* @since 3.22.0
*
* @param {number} x - The horizontal world location of the body.
* @param {number} y - The vertical world location of the body.
* @param {object} config - The body configuration data.
* @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation.
*
* @return {MatterJS.BodyType} A Matter JS Body.
*/
parseBody: function(x, y, config, options) {
if (options === void 0) {
options = {};
}
var body;
var vertexSets = config.vertices;
if (vertexSets.length === 1) {
options.vertices = vertexSets[0];
body = Body.create(options);
Bodies.flagCoincidentParts(body.parts);
} else {
var parts = [];
for (var i = 0; i < vertexSets.length; i++) {
var part = Body.create({
vertices: vertexSets[i]
});
parts.push(part);
}
Bodies.flagCoincidentParts(parts);
options.parts = parts;
body = Body.create(options);
}
body.label = config.label;
Body.setPosition(body, { x, y });
return body;
}
};
module2.exports = PhysicsJSONParser;
}
),
/***/
98713: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Bounds = __webpack_require__2(15647);
var Class = __webpack_require__2(83419);
var Composite = __webpack_require__2(69351);
var Constraint = __webpack_require__2(48140);
var Detector = __webpack_require__2(81388);
var Events = __webpack_require__2(1121);
var InputEvents = __webpack_require__2(8214);
var Merge = __webpack_require__2(46975);
var Sleeping = __webpack_require__2(53614);
var Vector2 = __webpack_require__2(26099);
var Vertices = __webpack_require__2(41598);
var PointerConstraint = new Class({
initialize: function PointerConstraint2(scene, world, options) {
if (options === void 0) {
options = {};
}
var defaults = {
label: "Pointer Constraint",
pointA: { x: 0, y: 0 },
pointB: { x: 0, y: 0 },
length: 0.01,
stiffness: 0.1,
angularStiffness: 1,
collisionFilter: {
category: 1,
mask: 4294967295,
group: 0
}
};
this.scene = scene;
this.world = world;
this.camera = null;
this.pointer = null;
this.active = true;
this.position = new Vector2();
this.body = null;
this.part = null;
this.constraint = Constraint.create(Merge(options, defaults));
this.world.on(Events.BEFORE_UPDATE, this.update, this);
scene.sys.input.on(InputEvents.POINTER_DOWN, this.onDown, this);
scene.sys.input.on(InputEvents.POINTER_UP, this.onUp, this);
},
/**
* A Pointer has been pressed down onto the Scene.
*
* If this Constraint doesn't have an active Pointer then a hit test is set to
* run against all active bodies in the world during the _next_ call to `update`.
* If a body is found, it is bound to this constraint and the drag begins.
*
* @method Phaser.Physics.Matter.PointerConstraint#onDown
* @since 3.0.0
*
* @param {Phaser.Input.Pointer} pointer - A reference to the Pointer that was pressed.
*/
onDown: function(pointer) {
if (!this.pointer) {
this.pointer = pointer;
this.camera = pointer.camera;
}
},
/**
* A Pointer has been released from the Scene. If it was the one this constraint was using, it's cleared.
*
* @method Phaser.Physics.Matter.PointerConstraint#onUp
* @since 3.22.0
*
* @param {Phaser.Input.Pointer} pointer - A reference to the Pointer that was pressed.
*/
onUp: function(pointer) {
if (pointer === this.pointer) {
this.pointer = null;
}
},
/**
* Scans all active bodies in the current Matter World to see if any of them
* are hit by the Pointer. The _first one_ found to hit is set as the active contraint
* body.
*
* @method Phaser.Physics.Matter.PointerConstraint#getBody
* @fires Phaser.Physics.Matter.Events#DRAG_START
* @since 3.16.2
*
* @return {boolean} `true` if a body was found and set, otherwise `false`.
*/
getBody: function(pointer) {
var pos = this.position;
var constraint = this.constraint;
this.camera.getWorldPoint(pointer.x, pointer.y, pos);
var bodies = Composite.allBodies(this.world.localWorld);
for (var i = 0; i < bodies.length; i++) {
var body = bodies[i];
if (!body.ignorePointer && Bounds.contains(body.bounds, pos) && Detector.canCollide(body.collisionFilter, constraint.collisionFilter)) {
if (this.hitTestBody(body, pos)) {
this.world.emit(Events.DRAG_START, body, this.part, this);
return true;
}
}
}
return false;
},
/**
* Scans the current body to determine if a part of it was clicked on.
* If a part is found the body is set as the `constraint.bodyB` property,
* as well as the `body` property of this class. The part is also set.
*
* @method Phaser.Physics.Matter.PointerConstraint#hitTestBody
* @since 3.16.2
*
* @param {MatterJS.BodyType} body - The Matter Body to check.
* @param {Phaser.Math.Vector2} position - A translated hit test position.
*
* @return {boolean} `true` if a part of the body was hit, otherwise `false`.
*/
hitTestBody: function(body, position) {
var constraint = this.constraint;
var partsLength = body.parts.length;
var start = partsLength > 1 ? 1 : 0;
for (var i = start; i < partsLength; i++) {
var part = body.parts[i];
if (Vertices.contains(part.vertices, position)) {
constraint.pointA = position;
constraint.pointB = { x: position.x - body.position.x, y: position.y - body.position.y };
constraint.bodyB = body;
constraint.angleB = body.angle;
Sleeping.set(body, false);
this.part = part;
this.body = body;
return true;
}
}
return false;
},
/**
* Internal update handler. Called in the Matter BEFORE_UPDATE step.
*
* @method Phaser.Physics.Matter.PointerConstraint#update
* @fires Phaser.Physics.Matter.Events#DRAG
* @since 3.0.0
*/
update: function() {
var pointer = this.pointer;
var body = this.body;
if (!this.active || !pointer) {
if (body) {
this.stopDrag();
}
return;
}
if (!pointer.isDown && body) {
this.stopDrag();
return;
} else if (pointer.isDown) {
if (!this.camera || !body && !this.getBody(pointer)) {
return;
}
body = this.body;
var pos = this.position;
var constraint = this.constraint;
this.camera.getWorldPoint(pointer.x, pointer.y, pos);
constraint.pointA.x = pos.x;
constraint.pointA.y = pos.y;
Sleeping.set(body, false);
this.world.emit(Events.DRAG, body, this);
}
},
/**
* Stops the Pointer Constraint from dragging the body any further.
*
* This is called automatically if the Pointer is released while actively
* dragging a body. Or, you can call it manually to release a body from a
* constraint without having to first release the pointer.
*
* @method Phaser.Physics.Matter.PointerConstraint#stopDrag
* @fires Phaser.Physics.Matter.Events#DRAG_END
* @since 3.16.2
*/
stopDrag: function() {
var body = this.body;
var constraint = this.constraint;
constraint.bodyB = null;
constraint.pointB = null;
this.pointer = null;
this.body = null;
this.part = null;
if (body) {
this.world.emit(Events.DRAG_END, body, this);
}
},
/**
* Destroys this Pointer Constraint instance and all of its references.
*
* @method Phaser.Physics.Matter.PointerConstraint#destroy
* @since 3.0.0
*/
destroy: function() {
this.world.removeConstraint(this.constraint);
this.pointer = null;
this.constraint = null;
this.body = null;
this.part = null;
this.world.off(Events.BEFORE_UPDATE, this.update);
this.scene.sys.input.off(InputEvents.POINTER_DOWN, this.onDown, this);
this.scene.sys.input.off(InputEvents.POINTER_UP, this.onUp, this);
}
});
module2.exports = PointerConstraint;
}
),
/***/
68243: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Bodies = __webpack_require__2(66280);
var Body = __webpack_require__2(22562);
var Class = __webpack_require__2(83419);
var Common = __webpack_require__2(53402);
var Composite = __webpack_require__2(69351);
var Engine = __webpack_require__2(48413);
var EventEmitter = __webpack_require__2(50792);
var Events = __webpack_require__2(1121);
var GetFastValue = __webpack_require__2(95540);
var GetValue = __webpack_require__2(35154);
var MatterBody = __webpack_require__2(22562);
var MatterEvents = __webpack_require__2(35810);
var MatterTileBody = __webpack_require__2(73834);
var MatterWorld = __webpack_require__2(4372);
var MatterRunner = __webpack_require__2(13037);
var Vector = __webpack_require__2(31725);
var World = new Class({
Extends: EventEmitter,
initialize: function World2(scene, config) {
EventEmitter.call(this);
this.scene = scene;
this.engine = Engine.create(config);
this.localWorld = this.engine.world;
var gravity = GetValue(config, "gravity", null);
if (gravity) {
this.setGravity(gravity.x, gravity.y, gravity.scale);
} else if (gravity === false) {
this.setGravity(0, 0, 0);
}
this.walls = { left: null, right: null, top: null, bottom: null };
this.enabled = GetValue(config, "enabled", true);
this.getDelta = GetValue(config, "getDelta", this.update60Hz);
var runnerConfig = GetFastValue(config, "runner", {});
var hasFPS = GetFastValue(runnerConfig, "fps", false);
var fps = GetFastValue(runnerConfig, "fps", 60);
var delta = GetFastValue(runnerConfig, "delta", 1e3 / fps);
var deltaMin = GetFastValue(runnerConfig, "deltaMin", 1e3 / fps);
var deltaMax = GetFastValue(runnerConfig, "deltaMax", 1e3 / (fps * 0.5));
if (!hasFPS) {
fps = 1e3 / delta;
}
this.runner = {
fps,
deltaSampleSize: GetFastValue(runnerConfig, "deltaSampleSize", 60),
counterTimestamp: 0,
frameCounter: 0,
deltaHistory: [],
timePrev: null,
timeScalePrev: 1,
frameRequestId: null,
timeBuffer: 0,
isFixed: GetFastValue(runnerConfig, "isFixed", false),
delta,
deltaMin,
deltaMax
};
this.autoUpdate = GetValue(config, "autoUpdate", true);
var debugConfig = GetValue(config, "debug", false);
this.drawDebug = typeof debugConfig === "object" ? true : debugConfig;
this.debugGraphic;
this.debugConfig = {
showAxes: GetFastValue(debugConfig, "showAxes", false),
showAngleIndicator: GetFastValue(debugConfig, "showAngleIndicator", false),
angleColor: GetFastValue(debugConfig, "angleColor", 15208787),
showBroadphase: GetFastValue(debugConfig, "showBroadphase", false),
broadphaseColor: GetFastValue(debugConfig, "broadphaseColor", 16757760),
showBounds: GetFastValue(debugConfig, "showBounds", false),
boundsColor: GetFastValue(debugConfig, "boundsColor", 16777215),
showVelocity: GetFastValue(debugConfig, "showVelocity", false),
velocityColor: GetFastValue(debugConfig, "velocityColor", 44783),
showCollisions: GetFastValue(debugConfig, "showCollisions", false),
collisionColor: GetFastValue(debugConfig, "collisionColor", 16094476),
showSeparations: GetFastValue(debugConfig, "showSeparations", false),
separationColor: GetFastValue(debugConfig, "separationColor", 16753920),
showBody: GetFastValue(debugConfig, "showBody", true),
showStaticBody: GetFastValue(debugConfig, "showStaticBody", true),
showInternalEdges: GetFastValue(debugConfig, "showInternalEdges", false),
renderFill: GetFastValue(debugConfig, "renderFill", false),
renderLine: GetFastValue(debugConfig, "renderLine", true),
fillColor: GetFastValue(debugConfig, "fillColor", 1075465),
fillOpacity: GetFastValue(debugConfig, "fillOpacity", 1),
lineColor: GetFastValue(debugConfig, "lineColor", 2678297),
lineOpacity: GetFastValue(debugConfig, "lineOpacity", 1),
lineThickness: GetFastValue(debugConfig, "lineThickness", 1),
staticFillColor: GetFastValue(debugConfig, "staticFillColor", 857979),
staticLineColor: GetFastValue(debugConfig, "staticLineColor", 1255396),
showSleeping: GetFastValue(debugConfig, "showSleeping", false),
staticBodySleepOpacity: GetFastValue(debugConfig, "staticBodySleepOpacity", 0.7),
sleepFillColor: GetFastValue(debugConfig, "sleepFillColor", 4605510),
sleepLineColor: GetFastValue(debugConfig, "sleepLineColor", 10066585),
showSensors: GetFastValue(debugConfig, "showSensors", true),
sensorFillColor: GetFastValue(debugConfig, "sensorFillColor", 857979),
sensorLineColor: GetFastValue(debugConfig, "sensorLineColor", 1255396),
showPositions: GetFastValue(debugConfig, "showPositions", true),
positionSize: GetFastValue(debugConfig, "positionSize", 4),
positionColor: GetFastValue(debugConfig, "positionColor", 14697178),
showJoint: GetFastValue(debugConfig, "showJoint", true),
jointColor: GetFastValue(debugConfig, "jointColor", 14737474),
jointLineOpacity: GetFastValue(debugConfig, "jointLineOpacity", 1),
jointLineThickness: GetFastValue(debugConfig, "jointLineThickness", 2),
pinSize: GetFastValue(debugConfig, "pinSize", 4),
pinColor: GetFastValue(debugConfig, "pinColor", 4382944),
springColor: GetFastValue(debugConfig, "springColor", 14697184),
anchorColor: GetFastValue(debugConfig, "anchorColor", 15724527),
anchorSize: GetFastValue(debugConfig, "anchorSize", 4),
showConvexHulls: GetFastValue(debugConfig, "showConvexHulls", false),
hullColor: GetFastValue(debugConfig, "hullColor", 14091216)
};
if (this.drawDebug) {
this.createDebugGraphic();
}
this.setEventsProxy();
if (GetFastValue(config, "setBounds", false)) {
var boundsConfig = config["setBounds"];
if (typeof boundsConfig === "boolean") {
this.setBounds();
} else {
var x = GetFastValue(boundsConfig, "x", 0);
var y = GetFastValue(boundsConfig, "y", 0);
var width = GetFastValue(boundsConfig, "width", scene.sys.scale.width);
var height = GetFastValue(boundsConfig, "height", scene.sys.scale.height);
var thickness = GetFastValue(boundsConfig, "thickness", 64);
var left = GetFastValue(boundsConfig, "left", true);
var right = GetFastValue(boundsConfig, "right", true);
var top = GetFastValue(boundsConfig, "top", true);
var bottom = GetFastValue(boundsConfig, "bottom", true);
this.setBounds(x, y, width, height, thickness, left, right, top, bottom);
}
}
},
/**
* Sets the debug render style for the children of the given Matter Composite.
*
* Composites themselves do not render, but they can contain bodies, constraints and other composites that may do.
* So the children of this composite are passed to the `setBodyRenderStyle`, `setCompositeRenderStyle` and
* `setConstraintRenderStyle` methods accordingly.
*
* @method Phaser.Physics.Matter.World#setCompositeRenderStyle
* @since 3.22.0
*
* @param {MatterJS.CompositeType} composite - The Matter Composite to set the render style on.
*
* @return {this} This Matter World instance for method chaining.
*/
setCompositeRenderStyle: function(composite) {
var bodies = composite.bodies;
var constraints = composite.constraints;
var composites = composite.composites;
var i;
var obj;
var render;
for (i = 0; i < bodies.length; i++) {
obj = bodies[i];
render = obj.render;
this.setBodyRenderStyle(obj, render.lineColor, render.lineOpacity, render.lineThickness, render.fillColor, render.fillOpacity);
}
for (i = 0; i < constraints.length; i++) {
obj = constraints[i];
render = obj.render;
this.setConstraintRenderStyle(obj, render.lineColor, render.lineOpacity, render.lineThickness, render.pinSize, render.anchorColor, render.anchorSize);
}
for (i = 0; i < composites.length; i++) {
obj = composites[i];
this.setCompositeRenderStyle(obj);
}
return this;
},
/**
* Sets the debug render style for the given Matter Body.
*
* If you are using this on a Phaser Game Object, such as a Matter Sprite, then pass in the body property
* to this method, not the Game Object itself.
*
* If you wish to skip a parameter, so it retains its current value, pass `false` for it.
*
* If you wish to reset the Body render colors to the defaults found in the World Debug Config, then call
* this method with just the `body` parameter provided and no others.
*
* @method Phaser.Physics.Matter.World#setBodyRenderStyle
* @since 3.22.0
*
* @param {MatterJS.BodyType} body - The Matter Body to set the render style on.
* @param {number} [lineColor] - The line color. If `null` it will use the World Debug Config value.
* @param {number} [lineOpacity] - The line opacity, between 0 and 1. If `null` it will use the World Debug Config value.
* @param {number} [lineThickness] - The line thickness. If `null` it will use the World Debug Config value.
* @param {number} [fillColor] - The fill color. If `null` it will use the World Debug Config value.
* @param {number} [fillOpacity] - The fill opacity, between 0 and 1. If `null` it will use the World Debug Config value.
*
* @return {this} This Matter World instance for method chaining.
*/
setBodyRenderStyle: function(body, lineColor, lineOpacity, lineThickness, fillColor, fillOpacity) {
var render = body.render;
var config = this.debugConfig;
if (!render) {
return this;
}
if (lineColor === void 0 || lineColor === null) {
lineColor = body.isStatic ? config.staticLineColor : config.lineColor;
}
if (lineOpacity === void 0 || lineOpacity === null) {
lineOpacity = config.lineOpacity;
}
if (lineThickness === void 0 || lineThickness === null) {
lineThickness = config.lineThickness;
}
if (fillColor === void 0 || fillColor === null) {
fillColor = body.isStatic ? config.staticFillColor : config.fillColor;
}
if (fillOpacity === void 0 || fillOpacity === null) {
fillOpacity = config.fillOpacity;
}
if (lineColor !== false) {
render.lineColor = lineColor;
}
if (lineOpacity !== false) {
render.lineOpacity = lineOpacity;
}
if (lineThickness !== false) {
render.lineThickness = lineThickness;
}
if (fillColor !== false) {
render.fillColor = fillColor;
}
if (fillOpacity !== false) {
render.fillOpacity = fillOpacity;
}
return this;
},
/**
* Sets the debug render style for the given Matter Constraint.
*
* If you are using this on a Phaser Game Object, then pass in the body property
* to this method, not the Game Object itself.
*
* If you wish to skip a parameter, so it retains its current value, pass `false` for it.
*
* If you wish to reset the Constraint render colors to the defaults found in the World Debug Config, then call
* this method with just the `constraint` parameter provided and no others.
*
* @method Phaser.Physics.Matter.World#setConstraintRenderStyle
* @since 3.22.0
*
* @param {MatterJS.ConstraintType} constraint - The Matter Constraint to set the render style on.
* @param {number} [lineColor] - The line color. If `null` it will use the World Debug Config value.
* @param {number} [lineOpacity] - The line opacity, between 0 and 1. If `null` it will use the World Debug Config value.
* @param {number} [lineThickness] - The line thickness. If `null` it will use the World Debug Config value.
* @param {number} [pinSize] - If this constraint is a pin, this sets the size of the pin circle. If `null` it will use the World Debug Config value.
* @param {number} [anchorColor] - The color used when rendering this constraints anchors. If `null` it will use the World Debug Config value.
* @param {number} [anchorSize] - The size of the anchor circle, if this constraint has anchors. If `null` it will use the World Debug Config value.
*
* @return {this} This Matter World instance for method chaining.
*/
setConstraintRenderStyle: function(constraint, lineColor, lineOpacity, lineThickness, pinSize, anchorColor, anchorSize) {
var render = constraint.render;
var config = this.debugConfig;
if (!render) {
return this;
}
if (lineColor === void 0 || lineColor === null) {
var type = render.type;
if (type === "line") {
lineColor = config.jointColor;
} else if (type === "pin") {
lineColor = config.pinColor;
} else if (type === "spring") {
lineColor = config.springColor;
}
}
if (lineOpacity === void 0 || lineOpacity === null) {
lineOpacity = config.jointLineOpacity;
}
if (lineThickness === void 0 || lineThickness === null) {
lineThickness = config.jointLineThickness;
}
if (pinSize === void 0 || pinSize === null) {
pinSize = config.pinSize;
}
if (anchorColor === void 0 || anchorColor === null) {
anchorColor = config.anchorColor;
}
if (anchorSize === void 0 || anchorSize === null) {
anchorSize = config.anchorSize;
}
if (lineColor !== false) {
render.lineColor = lineColor;
}
if (lineOpacity !== false) {
render.lineOpacity = lineOpacity;
}
if (lineThickness !== false) {
render.lineThickness = lineThickness;
}
if (pinSize !== false) {
render.pinSize = pinSize;
}
if (anchorColor !== false) {
render.anchorColor = anchorColor;
}
if (anchorSize !== false) {
render.anchorSize = anchorSize;
}
return this;
},
/**
* This internal method acts as a proxy between all of the Matter JS events and then re-emits them
* via this class.
*
* @method Phaser.Physics.Matter.World#setEventsProxy
* @since 3.0.0
*/
setEventsProxy: function() {
var _this = this;
var engine = this.engine;
var world = this.localWorld;
if (this.drawDebug) {
MatterEvents.on(world, "compositeModified", function(composite) {
_this.setCompositeRenderStyle(composite);
});
MatterEvents.on(world, "beforeAdd", function(event) {
var objects = [].concat(event.object);
for (var i = 0; i < objects.length; i++) {
var obj = objects[i];
var render = obj.render;
if (obj.type === "body") {
_this.setBodyRenderStyle(obj, render.lineColor, render.lineOpacity, render.lineThickness, render.fillColor, render.fillOpacity);
} else if (obj.type === "composite") {
_this.setCompositeRenderStyle(obj);
} else if (obj.type === "constraint") {
_this.setConstraintRenderStyle(obj, render.lineColor, render.lineOpacity, render.lineThickness, render.pinSize, render.anchorColor, render.anchorSize);
}
}
});
}
MatterEvents.on(world, "beforeAdd", function(event) {
_this.emit(Events.BEFORE_ADD, event);
});
MatterEvents.on(world, "afterAdd", function(event) {
_this.emit(Events.AFTER_ADD, event);
});
MatterEvents.on(world, "beforeRemove", function(event) {
_this.emit(Events.BEFORE_REMOVE, event);
});
MatterEvents.on(world, "afterRemove", function(event) {
_this.emit(Events.AFTER_REMOVE, event);
});
MatterEvents.on(engine, "beforeUpdate", function(event) {
_this.emit(Events.BEFORE_UPDATE, event);
});
MatterEvents.on(engine, "afterUpdate", function(event) {
_this.emit(Events.AFTER_UPDATE, event);
});
MatterEvents.on(engine, "collisionStart", function(event) {
var pairs = event.pairs;
var bodyA;
var bodyB;
if (pairs.length > 0) {
pairs.map(function(pair) {
bodyA = pair.bodyA;
bodyB = pair.bodyB;
if (bodyA.gameObject) {
bodyA.gameObject.emit("collide", bodyA, bodyB, pair);
}
if (bodyB.gameObject) {
bodyB.gameObject.emit("collide", bodyB, bodyA, pair);
}
MatterEvents.trigger(bodyA, "onCollide", { pair });
MatterEvents.trigger(bodyB, "onCollide", { pair });
if (bodyA.onCollideCallback) {
bodyA.onCollideCallback(pair);
}
if (bodyB.onCollideCallback) {
bodyB.onCollideCallback(pair);
}
if (bodyA.onCollideWith[bodyB.id]) {
bodyA.onCollideWith[bodyB.id](bodyB, pair);
}
if (bodyB.onCollideWith[bodyA.id]) {
bodyB.onCollideWith[bodyA.id](bodyA, pair);
}
});
}
_this.emit(Events.COLLISION_START, event, bodyA, bodyB);
});
MatterEvents.on(engine, "collisionActive", function(event) {
var pairs = event.pairs;
var bodyA;
var bodyB;
if (pairs.length > 0) {
pairs.map(function(pair) {
bodyA = pair.bodyA;
bodyB = pair.bodyB;
if (bodyA.gameObject) {
bodyA.gameObject.emit("collideActive", bodyA, bodyB, pair);
}
if (bodyB.gameObject) {
bodyB.gameObject.emit("collideActive", bodyB, bodyA, pair);
}
MatterEvents.trigger(bodyA, "onCollideActive", { pair });
MatterEvents.trigger(bodyB, "onCollideActive", { pair });
if (bodyA.onCollideActiveCallback) {
bodyA.onCollideActiveCallback(pair);
}
if (bodyB.onCollideActiveCallback) {
bodyB.onCollideActiveCallback(pair);
}
});
}
_this.emit(Events.COLLISION_ACTIVE, event, bodyA, bodyB);
});
MatterEvents.on(engine, "collisionEnd", function(event) {
var pairs = event.pairs;
var bodyA;
var bodyB;
if (pairs.length > 0) {
pairs.map(function(pair) {
bodyA = pair.bodyA;
bodyB = pair.bodyB;
if (bodyA.gameObject) {
bodyA.gameObject.emit("collideEnd", bodyA, bodyB, pair);
}
if (bodyB.gameObject) {
bodyB.gameObject.emit("collideEnd", bodyB, bodyA, pair);
}
MatterEvents.trigger(bodyA, "onCollideEnd", { pair });
MatterEvents.trigger(bodyB, "onCollideEnd", { pair });
if (bodyA.onCollideEndCallback) {
bodyA.onCollideEndCallback(pair);
}
if (bodyB.onCollideEndCallback) {
bodyB.onCollideEndCallback(pair);
}
});
}
_this.emit(Events.COLLISION_END, event, bodyA, bodyB);
});
},
/**
* Sets the bounds of the Physics world to match the given world pixel dimensions.
*
* You can optionally set which 'walls' to create: left, right, top or bottom.
* If none of the walls are given it will default to use the walls settings it had previously.
* I.e. if you previously told it to not have the left or right walls, and you then adjust the world size
* the newly created bounds will also not have the left and right walls.
* Explicitly state them in the parameters to override this.
*
* @method Phaser.Physics.Matter.World#setBounds
* @since 3.0.0
*
* @param {number} [x=0] - The x coordinate of the top-left corner of the bounds.
* @param {number} [y=0] - The y coordinate of the top-left corner of the bounds.
* @param {number} [width] - The width of the bounds.
* @param {number} [height] - The height of the bounds.
* @param {number} [thickness=64] - The thickness of each wall, in pixels.
* @param {boolean} [left=true] - If true will create the left bounds wall.
* @param {boolean} [right=true] - If true will create the right bounds wall.
* @param {boolean} [top=true] - If true will create the top bounds wall.
* @param {boolean} [bottom=true] - If true will create the bottom bounds wall.
*
* @return {Phaser.Physics.Matter.World} This Matter World object.
*/
setBounds: function(x, y, width, height, thickness, left, right, top, bottom) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (width === void 0) {
width = this.scene.sys.scale.width;
}
if (height === void 0) {
height = this.scene.sys.scale.height;
}
if (thickness === void 0) {
thickness = 64;
}
if (left === void 0) {
left = true;
}
if (right === void 0) {
right = true;
}
if (top === void 0) {
top = true;
}
if (bottom === void 0) {
bottom = true;
}
this.updateWall(left, "left", x - thickness, y - thickness, thickness, height + thickness * 2);
this.updateWall(right, "right", x + width, y - thickness, thickness, height + thickness * 2);
this.updateWall(top, "top", x, y - thickness, width, thickness);
this.updateWall(bottom, "bottom", x, y + height, width, thickness);
return this;
},
/**
* Updates the 4 rectangle bodies that were created, if `setBounds` was set in the Matter config, to use
* the new positions and sizes. This method is usually only called internally via the `setBounds` method.
*
* @method Phaser.Physics.Matter.World#updateWall
* @since 3.0.0
*
* @param {boolean} add - `true` if the walls are being added or updated, `false` to remove them from the world.
* @param {string} [position] - Either `left`, `right`, `top` or `bottom`. Only optional if `add` is `false`.
* @param {number} [x] - The horizontal position to place the walls at. Only optional if `add` is `false`.
* @param {number} [y] - The vertical position to place the walls at. Only optional if `add` is `false`.
* @param {number} [width] - The width of the walls, in pixels. Only optional if `add` is `false`.
* @param {number} [height] - The height of the walls, in pixels. Only optional if `add` is `false`.
*/
updateWall: function(add, position, x, y, width, height) {
var wall = this.walls[position];
if (add) {
if (wall) {
MatterWorld.remove(this.localWorld, wall);
}
x += width / 2;
y += height / 2;
this.walls[position] = this.create(x, y, width, height, { isStatic: true, friction: 0, frictionStatic: 0 });
} else {
if (wall) {
MatterWorld.remove(this.localWorld, wall);
}
this.walls[position] = null;
}
},
/**
* Creates a Phaser.GameObjects.Graphics object that is used to render all of the debug bodies and joints to.
*
* This method is called automatically by the constructor, if debugging has been enabled.
*
* The created Graphics object is automatically added to the Scene at 0x0 and given a depth of `Number.MAX_VALUE`,
* so it renders above all else in the Scene.
*
* The Graphics object is assigned to the `debugGraphic` property of this class and `drawDebug` is enabled.
*
* @method Phaser.Physics.Matter.World#createDebugGraphic
* @since 3.0.0
*
* @return {Phaser.GameObjects.Graphics} The newly created Graphics object.
*/
createDebugGraphic: function() {
var graphic = this.scene.sys.add.graphics({ x: 0, y: 0 });
graphic.setDepth(Number.MAX_VALUE);
this.debugGraphic = graphic;
this.drawDebug = true;
return graphic;
},
/**
* Sets the world gravity and gravity scale to 0.
*
* @method Phaser.Physics.Matter.World#disableGravity
* @since 3.0.0
*
* @return {this} This Matter World object.
*/
disableGravity: function() {
this.localWorld.gravity.x = 0;
this.localWorld.gravity.y = 0;
this.localWorld.gravity.scale = 0;
return this;
},
/**
* Sets the worlds gravity to the values given.
*
* Gravity effects all bodies in the world, unless they have the `ignoreGravity` flag set.
*
* @method Phaser.Physics.Matter.World#setGravity
* @since 3.0.0
*
* @param {number} [x=0] - The world gravity x component.
* @param {number} [y=1] - The world gravity y component.
* @param {number} [scale=0.001] - The gravity scale factor.
*
* @return {this} This Matter World object.
*/
setGravity: function(x, y, scale) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 1;
}
if (scale === void 0) {
scale = 1e-3;
}
this.localWorld.gravity.x = x;
this.localWorld.gravity.y = y;
this.localWorld.gravity.scale = scale;
return this;
},
/**
* Creates a rectangle Matter body and adds it to the world.
*
* @method Phaser.Physics.Matter.World#create
* @since 3.0.0
*
* @param {number} x - The horizontal position of the body in the world.
* @param {number} y - The vertical position of the body in the world.
* @param {number} width - The width of the body.
* @param {number} height - The height of the body.
* @param {object} options - Optional Matter configuration object.
*
* @return {MatterJS.BodyType} The Matter.js body that was created.
*/
create: function(x, y, width, height, options) {
var body = Bodies.rectangle(x, y, width, height, options);
MatterWorld.add(this.localWorld, body);
return body;
},
/**
* Adds a Matter JS object, or array of objects, to the world.
*
* The objects should be valid Matter JS entities, such as a Body, Composite or Constraint.
*
* Triggers `beforeAdd` and `afterAdd` events.
*
* @method Phaser.Physics.Matter.World#add
* @since 3.0.0
*
* @param {(object|object[])} object - Can be single object, or an array, and can be a body, composite or constraint.
*
* @return {this} This Matter World object.
*/
add: function(object) {
MatterWorld.add(this.localWorld, object);
return this;
},
/**
* Removes a Matter JS object, or array of objects, from the world.
*
* The objects should be valid Matter JS entities, such as a Body, Composite or Constraint.
*
* Triggers `beforeRemove` and `afterRemove` events.
*
* @method Phaser.Physics.Matter.World#remove
* @since 3.0.0
*
* @param {(object|object[])} object - Can be single object, or an array, and can be a body, composite or constraint.
* @param {boolean} [deep=false] - Optionally search the objects children and recursively remove those as well.
*
* @return {this} This Matter World object.
*/
remove: function(object, deep) {
if (!Array.isArray(object)) {
object = [object];
}
for (var i = 0; i < object.length; i++) {
var entity = object[i];
var body = entity.body ? entity.body : entity;
Composite.remove(this.localWorld, body, deep);
}
return this;
},
/**
* Removes a Matter JS constraint, or array of constraints, from the world.
*
* Triggers `beforeRemove` and `afterRemove` events.
*
* @method Phaser.Physics.Matter.World#removeConstraint
* @since 3.0.0
*
* @param {(MatterJS.ConstraintType|MatterJS.ConstraintType[])} constraint - A Matter JS Constraint, or an array of constraints, to be removed.
* @param {boolean} [deep=false] - Optionally search the objects children and recursively remove those as well.
*
* @return {this} This Matter World object.
*/
removeConstraint: function(constraint, deep) {
Composite.remove(this.localWorld, constraint, deep);
return this;
},
/**
* Adds `MatterTileBody` instances for all the colliding tiles within the given tilemap layer.
*
* Set the appropriate tiles in your layer to collide before calling this method!
*
* If you modify the map after calling this method, i.e. via a function like `putTileAt` then
* you should call the `Phaser.Physics.Matter.World.convertTiles` function directly, passing
* it an array of the tiles you've added to your map.
*
* @method Phaser.Physics.Matter.World#convertTilemapLayer
* @since 3.0.0
*
* @param {Phaser.Tilemaps.TilemapLayer} tilemapLayer - An array of tiles.
* @param {object} [options] - Options to be passed to the MatterTileBody constructor. {@see Phaser.Physics.Matter.TileBody}
*
* @return {this} This Matter World object.
*/
convertTilemapLayer: function(tilemapLayer, options) {
var layerData = tilemapLayer.layer;
var tiles = tilemapLayer.getTilesWithin(0, 0, layerData.width, layerData.height, { isColliding: true });
this.convertTiles(tiles, options);
return this;
},
/**
* Creates `MatterTileBody` instances for all of the given tiles. This creates bodies regardless of whether the
* tiles are set to collide or not, or if they have a body already, or not.
*
* If you wish to pass an array of tiles that may already have bodies, you should filter the array before hand.
*
* @method Phaser.Physics.Matter.World#convertTiles
* @since 3.0.0
*
* @param {Phaser.Tilemaps.Tile[]} tiles - An array of tiles.
* @param {object} [options] - Options to be passed to the MatterTileBody constructor. {@see Phaser.Physics.Matter.TileBody}
*
* @return {this} This Matter World object.
*/
convertTiles: function(tiles, options) {
if (tiles.length === 0) {
return this;
}
for (var i = 0; i < tiles.length; i++) {
new MatterTileBody(this, tiles[i], options);
}
return this;
},
/**
* Returns the next unique group index for which bodies will collide.
* If `isNonColliding` is `true`, returns the next unique group index for which bodies will not collide.
*
* @method Phaser.Physics.Matter.World#nextGroup
* @since 3.0.0
*
* @param {boolean} [isNonColliding=false] - If `true`, returns the next unique group index for which bodies will _not_ collide.
*
* @return {number} Unique category bitfield
*/
nextGroup: function(isNonColliding) {
return MatterBody.nextGroup(isNonColliding);
},
/**
* Returns the next unique category bitfield (starting after the initial default category 0x0001).
* There are 32 available.
*
* @method Phaser.Physics.Matter.World#nextCategory
* @since 3.0.0
*
* @return {number} Unique category bitfield
*/
nextCategory: function() {
return MatterBody.nextCategory();
},
/**
* Pauses this Matter World instance and sets `enabled` to `false`.
*
* A paused world will not run any simulations for the duration it is paused.
*
* @method Phaser.Physics.Matter.World#pause
* @fires Phaser.Physics.Matter.Events#PAUSE
* @since 3.0.0
*
* @return {this} This Matter World object.
*/
pause: function() {
this.enabled = false;
this.emit(Events.PAUSE);
return this;
},
/**
* Resumes this Matter World instance from a paused state and sets `enabled` to `true`.
*
* @method Phaser.Physics.Matter.World#resume
* @fires Phaser.Physics.Matter.Events#RESUME
* @since 3.0.0
*
* @return {this} This Matter World object.
*/
resume: function() {
this.enabled = true;
this.runner.timeLastTick = Common.now();
this.emit(Events.RESUME);
return this;
},
/**
* The internal update method. This is called automatically by the parent Scene.
*
* Moves the simulation forward in time by delta ms. Uses `World.correction` value as an optional number that
* specifies the time correction factor to apply to the update. This can help improve the accuracy of the
* simulation in cases where delta is changing between updates. The value of correction is defined as `delta / lastDelta`,
* i.e. the percentage change of delta over the last step. Therefore the value is always 1 (no correction) when
* delta is constant (or when no correction is desired, which is the default).
* See the paper on Time Corrected Verlet for more information.
*
* Triggers `beforeUpdate` and `afterUpdate` events. Triggers `collisionStart`, `collisionActive` and `collisionEnd` events.
*
* If the World is paused, `update` is still run, but exits early and does not update the Matter Engine.
*
* @method Phaser.Physics.Matter.World#update
* @since 3.0.0
*
* @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout.
* @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
*/
update: function(time) {
if (!this.enabled || !this.autoUpdate) {
return;
}
var engine = this.engine;
var runner = this.runner;
var tickStartTime = Common.now(), engineDelta = runner.delta, updateCount = 0;
var frameDelta = time - runner.timeLastTick;
if (!frameDelta || !runner.timeLastTick || frameDelta > Math.max(MatterRunner._maxFrameDelta, runner.maxFrameTime)) {
frameDelta = runner.frameDelta || MatterRunner._frameDeltaFallback;
}
if (runner.frameDeltaSmoothing) {
runner.frameDeltaHistory.push(frameDelta);
runner.frameDeltaHistory = runner.frameDeltaHistory.slice(-runner.frameDeltaHistorySize);
var deltaHistorySorted = runner.frameDeltaHistory.slice(0).sort();
var deltaHistoryWindow = runner.frameDeltaHistory.slice(
deltaHistorySorted.length * MatterRunner._smoothingLowerBound,
deltaHistorySorted.length * MatterRunner._smoothingUpperBound
);
var frameDeltaSmoothed = MatterRunner._mean(deltaHistoryWindow);
frameDelta = frameDeltaSmoothed || frameDelta;
}
if (runner.frameDeltaSnapping) {
frameDelta = 1e3 / Math.round(1e3 / frameDelta);
}
runner.frameDelta = frameDelta;
runner.timeLastTick = time;
runner.timeBuffer += runner.frameDelta;
runner.timeBuffer = Common.clamp(
runner.timeBuffer,
0,
runner.frameDelta + engineDelta * MatterRunner._timeBufferMargin
);
runner.lastUpdatesDeferred = 0;
var maxUpdates = runner.maxUpdates || Math.ceil(runner.maxFrameTime / engineDelta);
var updateStartTime = Common.now();
while (engineDelta > 0 && runner.timeBuffer >= engineDelta * MatterRunner._timeBufferMargin) {
Engine.update(engine, engineDelta);
runner.timeBuffer -= engineDelta;
updateCount += 1;
var elapsedTimeTotal = Common.now() - tickStartTime, elapsedTimeUpdates = Common.now() - updateStartTime, elapsedNextEstimate = elapsedTimeTotal + MatterRunner._elapsedNextEstimate * elapsedTimeUpdates / updateCount;
if (updateCount >= maxUpdates || elapsedNextEstimate > runner.maxFrameTime) {
runner.lastUpdatesDeferred = Math.round(Math.max(0, runner.timeBuffer / engineDelta - MatterRunner._timeBufferMargin));
break;
}
}
},
/**
* Manually advances the physics simulation by one iteration.
*
* You can optionally pass in the `delta` and `correction` values to be used by Engine.update.
* If undefined they use the Matter defaults of 60Hz and no correction.
*
* Calling `step` directly bypasses any checks of `enabled` or `autoUpdate`.
*
* It also ignores any custom `getDelta` functions, as you should be passing the delta
* value in to this call.
*
* You can adjust the number of iterations that Engine.update performs internally.
* Use the Scene Matter Physics config object to set the following properties:
*
* positionIterations (defaults to 6)
* velocityIterations (defaults to 4)
* constraintIterations (defaults to 2)
*
* Adjusting these values can help performance in certain situations, depending on the physics requirements
* of your game.
*
* @method Phaser.Physics.Matter.World#step
* @since 3.4.0
*
* @param {number} [delta=16.666] - The delta value.
*/
step: function(delta) {
Engine.update(this.engine, delta);
},
/**
* Runs the Matter Engine.update at a fixed timestep of 60Hz.
*
* @method Phaser.Physics.Matter.World#update60Hz
* @since 3.4.0
*
* @return {number} The delta value to be passed to Engine.update.
*/
update60Hz: function() {
return 1e3 / 60;
},
/**
* Runs the Matter Engine.update at a fixed timestep of 30Hz.
*
* @method Phaser.Physics.Matter.World#update30Hz
* @since 3.4.0
*
* @return {number} The delta value to be passed to Engine.update.
*/
update30Hz: function() {
return 1e3 / 30;
},
/**
* Returns `true` if the given body can be found within the World.
*
* @method Phaser.Physics.Matter.World#has
* @since 3.22.0
*
* @param {(MatterJS.Body|Phaser.GameObjects.GameObject)} body - The Matter Body, or Game Object, to search for within the world.
*
* @return {MatterJS.BodyType[]} An array of all the Matter JS Bodies in this World.
*/
has: function(body) {
var src = body.hasOwnProperty("body") ? body.body : body;
return Composite.get(this.localWorld, src.id, src.type) !== null;
},
/**
* Returns all the bodies in the Matter World, including all bodies in children, recursively.
*
* @method Phaser.Physics.Matter.World#getAllBodies
* @since 3.22.0
*
* @return {MatterJS.BodyType[]} An array of all the Matter JS Bodies in this World.
*/
getAllBodies: function() {
return Composite.allBodies(this.localWorld);
},
/**
* Returns all the constraints in the Matter World, including all constraints in children, recursively.
*
* @method Phaser.Physics.Matter.World#getAllConstraints
* @since 3.22.0
*
* @return {MatterJS.ConstraintType[]} An array of all the Matter JS Constraints in this World.
*/
getAllConstraints: function() {
return Composite.allConstraints(this.localWorld);
},
/**
* Returns all the composites in the Matter World, including all composites in children, recursively.
*
* @method Phaser.Physics.Matter.World#getAllComposites
* @since 3.22.0
*
* @return {MatterJS.CompositeType[]} An array of all the Matter JS Composites in this World.
*/
getAllComposites: function() {
return Composite.allComposites(this.localWorld);
},
/**
* Handles the rendering of bodies and debug information to the debug Graphics object, if enabled.
*
* This method is called automatically by the Scene after all processing has taken place.
*
* @method Phaser.Physics.Matter.World#postUpdate
* @private
* @since 3.0.0
*/
postUpdate: function() {
if (!this.drawDebug) {
return;
}
var config = this.debugConfig;
var engine = this.engine;
var graphics = this.debugGraphic;
var bodies = Composite.allBodies(this.localWorld);
this.debugGraphic.clear();
if (config.showBroadphase && engine.broadphase.controller) {
this.renderGrid(engine.broadphase, graphics, config.broadphaseColor, 0.5);
}
if (config.showBounds) {
this.renderBodyBounds(bodies, graphics, config.boundsColor, 0.5);
}
if (config.showBody || config.showStaticBody) {
this.renderBodies(bodies);
}
if (config.showJoint) {
this.renderJoints();
}
if (config.showAxes || config.showAngleIndicator) {
this.renderBodyAxes(bodies, graphics, config.showAxes, config.angleColor, 0.5);
}
if (config.showVelocity) {
this.renderBodyVelocity(bodies, graphics, config.velocityColor, 1, 2);
}
if (config.showSeparations) {
this.renderSeparations(engine.pairs.list, graphics, config.separationColor);
}
if (config.showCollisions) {
this.renderCollisions(engine.pairs.list, graphics, config.collisionColor);
}
},
/**
* Renders the Engine Broadphase Controller Grid to the given Graphics instance.
*
* The debug renderer calls this method if the `showBroadphase` config value is set.
*
* This method is used internally by the Matter Debug Renderer, but is also exposed publically should
* you wish to render the Grid to your own Graphics instance.
*
* @method Phaser.Physics.Matter.World#renderGrid
* @since 3.22.0
*
* @param {MatterJS.Grid} grid - The Matter Grid to be rendered.
* @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to.
* @param {number} lineColor - The line color.
* @param {number} lineOpacity - The line opacity, between 0 and 1.
*
* @return {this} This Matter World instance for method chaining.
*/
renderGrid: function(grid, graphics, lineColor, lineOpacity) {
graphics.lineStyle(1, lineColor, lineOpacity);
var bucketKeys = Common.keys(grid.buckets);
for (var i = 0; i < bucketKeys.length; i++) {
var bucketId = bucketKeys[i];
if (grid.buckets[bucketId].length < 2) {
continue;
}
var region = bucketId.split(/C|R/);
graphics.strokeRect(
parseInt(region[1], 10) * grid.bucketWidth,
parseInt(region[2], 10) * grid.bucketHeight,
grid.bucketWidth,
grid.bucketHeight
);
}
return this;
},
/**
* Renders the list of Pair separations to the given Graphics instance.
*
* The debug renderer calls this method if the `showSeparations` config value is set.
*
* This method is used internally by the Matter Debug Renderer, but is also exposed publically should
* you wish to render the Grid to your own Graphics instance.
*
* @method Phaser.Physics.Matter.World#renderSeparations
* @since 3.22.0
*
* @param {MatterJS.Pair[]} pairs - An array of Matter Pairs to be rendered.
* @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to.
* @param {number} lineColor - The line color.
*
* @return {this} This Matter World instance for method chaining.
*/
renderSeparations: function(pairs, graphics, lineColor) {
graphics.lineStyle(1, lineColor, 1);
for (var i = 0; i < pairs.length; i++) {
var pair = pairs[i];
if (!pair.isActive) {
continue;
}
var collision = pair.collision;
var bodyA = collision.bodyA;
var bodyB = collision.bodyB;
var posA = bodyA.position;
var posB = bodyB.position;
var penetration = collision.penetration;
var k = !bodyA.isStatic && !bodyB.isStatic ? 4 : 1;
if (bodyB.isStatic) {
k = 0;
}
graphics.lineBetween(
posB.x,
posB.y,
posB.x - penetration.x * k,
posB.y - penetration.y * k
);
k = !bodyA.isStatic && !bodyB.isStatic ? 4 : 1;
if (bodyA.isStatic) {
k = 0;
}
graphics.lineBetween(
posA.x,
posA.y,
posA.x - penetration.x * k,
posA.y - penetration.y * k
);
}
return this;
},
/**
* Renders the list of collision points and normals to the given Graphics instance.
*
* The debug renderer calls this method if the `showCollisions` config value is set.
*
* This method is used internally by the Matter Debug Renderer, but is also exposed publically should
* you wish to render the Grid to your own Graphics instance.
*
* @method Phaser.Physics.Matter.World#renderCollisions
* @since 3.22.0
*
* @param {MatterJS.Pair[]} pairs - An array of Matter Pairs to be rendered.
* @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to.
* @param {number} lineColor - The line color.
*
* @return {this} This Matter World instance for method chaining.
*/
renderCollisions: function(pairs, graphics, lineColor) {
graphics.lineStyle(1, lineColor, 0.5);
graphics.fillStyle(lineColor, 1);
var i;
var pair;
for (i = 0; i < pairs.length; i++) {
pair = pairs[i];
if (!pair.isActive) {
continue;
}
for (var j = 0; j < pair.contactCount; j++) {
var contact = pair.contacts[j];
var vertex = contact.vertex;
if (vertex) {
graphics.fillRect(vertex.x - 2, vertex.y - 2, 5, 5);
}
}
}
for (i = 0; i < pairs.length; i++) {
pair = pairs[i];
if (!pair.isActive) {
continue;
}
var collision = pair.collision;
var contacts = pair.contacts;
if (pair.contactCount > 0) {
var normalPosX = contacts[0].vertex.x;
var normalPosY = contacts[0].vertex.y;
if (pair.contactCount === 2) {
normalPosX = (contacts[0].vertex.x + contacts[1].vertex.x) / 2;
normalPosY = (contacts[0].vertex.y + contacts[1].vertex.y) / 2;
}
if (collision.bodyB === collision.supports[0].body || collision.bodyA.isStatic) {
graphics.lineBetween(
normalPosX - collision.normal.x * 8,
normalPosY - collision.normal.y * 8,
normalPosX,
normalPosY
);
} else {
graphics.lineBetween(
normalPosX + collision.normal.x * 8,
normalPosY + collision.normal.y * 8,
normalPosX,
normalPosY
);
}
}
}
return this;
},
/**
* Renders the bounds of an array of Bodies to the given Graphics instance.
*
* If the body is a compound body, it will render the bounds for the parent compound.
*
* The debug renderer calls this method if the `showBounds` config value is set.
*
* This method is used internally by the Matter Debug Renderer, but is also exposed publically should
* you wish to render bounds to your own Graphics instance.
*
* @method Phaser.Physics.Matter.World#renderBodyBounds
* @since 3.22.0
*
* @param {array} bodies - An array of bodies from the localWorld.
* @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to.
* @param {number} lineColor - The line color.
* @param {number} lineOpacity - The line opacity, between 0 and 1.
*/
renderBodyBounds: function(bodies, graphics, lineColor, lineOpacity) {
graphics.lineStyle(1, lineColor, lineOpacity);
for (var i = 0; i < bodies.length; i++) {
var body = bodies[i];
if (!body.render.visible) {
continue;
}
var bounds = body.bounds;
if (bounds) {
graphics.strokeRect(
bounds.min.x,
bounds.min.y,
bounds.max.x - bounds.min.x,
bounds.max.y - bounds.min.y
);
} else {
var parts = body.parts;
for (var j = parts.length > 1 ? 1 : 0; j < parts.length; j++) {
var part = parts[j];
graphics.strokeRect(
part.bounds.min.x,
part.bounds.min.y,
part.bounds.max.x - part.bounds.min.x,
part.bounds.max.y - part.bounds.min.y
);
}
}
}
return this;
},
/**
* Renders either all axes, or a single axis indicator, for an array of Bodies, to the given Graphics instance.
*
* The debug renderer calls this method if the `showAxes` or `showAngleIndicator` config values are set.
*
* This method is used internally by the Matter Debug Renderer, but is also exposed publically should
* you wish to render bounds to your own Graphics instance.
*
* @method Phaser.Physics.Matter.World#renderBodyAxes
* @since 3.22.0
*
* @param {array} bodies - An array of bodies from the localWorld.
* @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to.
* @param {boolean} showAxes - If `true` it will render all body axes. If `false` it will render a single axis indicator.
* @param {number} lineColor - The line color.
* @param {number} lineOpacity - The line opacity, between 0 and 1.
*/
renderBodyAxes: function(bodies, graphics, showAxes, lineColor, lineOpacity) {
graphics.lineStyle(1, lineColor, lineOpacity);
for (var i = 0; i < bodies.length; i++) {
var body = bodies[i];
var parts = body.parts;
if (!body.render.visible) {
continue;
}
var part;
var j;
var k;
if (showAxes) {
for (j = parts.length > 1 ? 1 : 0; j < parts.length; j++) {
part = parts[j];
for (k = 0; k < part.axes.length; k++) {
var axis = part.axes[k];
graphics.lineBetween(
part.position.x,
part.position.y,
part.position.x + axis.x * 20,
part.position.y + axis.y * 20
);
}
}
} else {
for (j = parts.length > 1 ? 1 : 0; j < parts.length; j++) {
part = parts[j];
for (k = 0; k < part.axes.length; k++) {
graphics.lineBetween(
part.position.x,
part.position.y,
(part.vertices[0].x + part.vertices[part.vertices.length - 1].x) / 2,
(part.vertices[0].y + part.vertices[part.vertices.length - 1].y) / 2
);
}
}
}
}
return this;
},
/**
* Renders a velocity indicator for an array of Bodies, to the given Graphics instance.
*
* The debug renderer calls this method if the `showVelocity` config value is set.
*
* This method is used internally by the Matter Debug Renderer, but is also exposed publically should
* you wish to render bounds to your own Graphics instance.
*
* @method Phaser.Physics.Matter.World#renderBodyVelocity
* @since 3.22.0
*
* @param {array} bodies - An array of bodies from the localWorld.
* @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to.
* @param {number} lineColor - The line color.
* @param {number} lineOpacity - The line opacity, between 0 and 1.
* @param {number} lineThickness - The line thickness.
*/
renderBodyVelocity: function(bodies, graphics, lineColor, lineOpacity, lineThickness) {
graphics.lineStyle(lineThickness, lineColor, lineOpacity);
for (var i = 0; i < bodies.length; i++) {
var body = bodies[i];
if (!body.render.visible) {
continue;
}
graphics.lineBetween(
body.position.x,
body.position.y,
body.position.x + (body.position.x - body.positionPrev.x) * 2,
body.position.y + (body.position.y - body.positionPrev.y) * 2
);
}
return this;
},
/**
* Renders the given array of Bodies to the debug graphics instance.
*
* Called automatically by the `postUpdate` method.
*
* @method Phaser.Physics.Matter.World#renderBodies
* @private
* @since 3.14.0
*
* @param {array} bodies - An array of bodies from the localWorld.
*/
renderBodies: function(bodies) {
var graphics = this.debugGraphic;
var config = this.debugConfig;
var showBody = config.showBody;
var showStaticBody = config.showStaticBody;
var showSleeping = config.showSleeping;
var showInternalEdges = config.showInternalEdges;
var showConvexHulls = config.showConvexHulls;
var renderFill = config.renderFill;
var renderLine = config.renderLine;
var staticBodySleepOpacity = config.staticBodySleepOpacity;
var sleepFillColor = config.sleepFillColor;
var sleepLineColor = config.sleepLineColor;
var hullColor = config.hullColor;
for (var i = 0; i < bodies.length; i++) {
var body = bodies[i];
if (!body.render.visible) {
continue;
}
if (!showStaticBody && body.isStatic || !showBody && !body.isStatic) {
continue;
}
var lineColor = body.render.lineColor;
var lineOpacity = body.render.lineOpacity;
var lineThickness = body.render.lineThickness;
var fillColor = body.render.fillColor;
var fillOpacity = body.render.fillOpacity;
if (showSleeping && body.isSleeping) {
if (body.isStatic) {
lineOpacity *= staticBodySleepOpacity;
fillOpacity *= staticBodySleepOpacity;
} else {
lineColor = sleepLineColor;
fillColor = sleepFillColor;
}
}
if (!renderFill) {
fillColor = null;
}
if (!renderLine) {
lineColor = null;
}
this.renderBody(body, graphics, showInternalEdges, lineColor, lineOpacity, lineThickness, fillColor, fillOpacity);
var partsLength = body.parts.length;
if (showConvexHulls && partsLength > 1) {
this.renderConvexHull(body, graphics, hullColor, lineThickness);
}
}
},
/**
* Renders a single Matter Body to the given Phaser Graphics Game Object.
*
* This method is used internally by the Matter Debug Renderer, but is also exposed publically should
* you wish to render a Body to your own Graphics instance.
*
* If you don't wish to render a line around the body, set the `lineColor` parameter to `null`.
* Equally, if you don't wish to render a fill, set the `fillColor` parameter to `null`.
*
* @method Phaser.Physics.Matter.World#renderBody
* @since 3.22.0
*
* @param {MatterJS.BodyType} body - The Matter Body to be rendered.
* @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to.
* @param {boolean} showInternalEdges - Render internal edges of the polygon?
* @param {number} [lineColor] - The line color.
* @param {number} [lineOpacity] - The line opacity, between 0 and 1.
* @param {number} [lineThickness=1] - The line thickness.
* @param {number} [fillColor] - The fill color.
* @param {number} [fillOpacity] - The fill opacity, between 0 and 1.
*
* @return {this} This Matter World instance for method chaining.
*/
renderBody: function(body, graphics, showInternalEdges, lineColor, lineOpacity, lineThickness, fillColor, fillOpacity) {
if (lineColor === void 0) {
lineColor = null;
}
if (lineOpacity === void 0) {
lineOpacity = null;
}
if (lineThickness === void 0) {
lineThickness = 1;
}
if (fillColor === void 0) {
fillColor = null;
}
if (fillOpacity === void 0) {
fillOpacity = null;
}
var config = this.debugConfig;
var sensorFillColor = config.sensorFillColor;
var sensorLineColor = config.sensorLineColor;
var parts = body.parts;
var partsLength = parts.length;
for (var k = partsLength > 1 ? 1 : 0; k < partsLength; k++) {
var part = parts[k];
var render = part.render;
var opacity = render.opacity;
if (!render.visible || opacity === 0 || part.isSensor && !config.showSensors) {
continue;
}
var circleRadius = part.circleRadius;
graphics.beginPath();
if (part.isSensor) {
if (fillColor !== null) {
graphics.fillStyle(sensorFillColor, fillOpacity * opacity);
}
if (lineColor !== null) {
graphics.lineStyle(lineThickness, sensorLineColor, lineOpacity * opacity);
}
} else {
if (fillColor !== null) {
graphics.fillStyle(fillColor, fillOpacity * opacity);
}
if (lineColor !== null) {
graphics.lineStyle(lineThickness, lineColor, lineOpacity * opacity);
}
}
if (circleRadius) {
graphics.arc(part.position.x, part.position.y, circleRadius, 0, 2 * Math.PI);
} else {
var vertices = part.vertices;
var vertLength = vertices.length;
graphics.moveTo(vertices[0].x, vertices[0].y);
for (var j = 1; j < vertLength; j++) {
var vert = vertices[j];
if (!vertices[j - 1].isInternal || showInternalEdges) {
graphics.lineTo(vert.x, vert.y);
} else {
graphics.moveTo(vert.x, vert.y);
}
if (j < vertLength && vert.isInternal && !showInternalEdges) {
var nextIndex = (j + 1) % vertLength;
graphics.moveTo(vertices[nextIndex].x, vertices[nextIndex].y);
}
}
graphics.closePath();
}
if (fillColor !== null) {
graphics.fillPath();
}
if (lineColor !== null) {
graphics.strokePath();
}
}
if (config.showPositions && !body.isStatic) {
var px = body.position.x;
var py = body.position.y;
var hs = Math.ceil(config.positionSize / 2);
graphics.fillStyle(config.positionColor, 1);
graphics.fillRect(px - hs, py - hs, config.positionSize, config.positionSize);
}
return this;
},
/**
* Renders the Convex Hull for a single Matter Body to the given Phaser Graphics Game Object.
*
* This method is used internally by the Matter Debug Renderer, but is also exposed publically should
* you wish to render a Body hull to your own Graphics instance.
*
* @method Phaser.Physics.Matter.World#renderConvexHull
* @since 3.22.0
*
* @param {MatterJS.BodyType} body - The Matter Body to be rendered.
* @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to.
* @param {number} hullColor - The color used to render the hull.
* @param {number} [lineThickness=1] - The hull line thickness.
*
* @return {this} This Matter World instance for method chaining.
*/
renderConvexHull: function(body, graphics, hullColor, lineThickness) {
if (lineThickness === void 0) {
lineThickness = 1;
}
var parts = body.parts;
var partsLength = parts.length;
if (partsLength > 1) {
var verts = body.vertices;
graphics.lineStyle(lineThickness, hullColor);
graphics.beginPath();
graphics.moveTo(verts[0].x, verts[0].y);
for (var v = 1; v < verts.length; v++) {
graphics.lineTo(verts[v].x, verts[v].y);
}
graphics.lineTo(verts[0].x, verts[0].y);
graphics.strokePath();
}
return this;
},
/**
* Renders all of the constraints in the world (unless they are specifically set to invisible).
*
* Called automatically by the `postUpdate` method.
*
* @method Phaser.Physics.Matter.World#renderJoints
* @private
* @since 3.14.0
*/
renderJoints: function() {
var graphics = this.debugGraphic;
var constraints = Composite.allConstraints(this.localWorld);
for (var i = 0; i < constraints.length; i++) {
var config = constraints[i].render;
var lineColor = config.lineColor;
var lineOpacity = config.lineOpacity;
var lineThickness = config.lineThickness;
var pinSize = config.pinSize;
var anchorColor = config.anchorColor;
var anchorSize = config.anchorSize;
this.renderConstraint(constraints[i], graphics, lineColor, lineOpacity, lineThickness, pinSize, anchorColor, anchorSize);
}
},
/**
* Renders a single Matter Constraint, such as a Pin or a Spring, to the given Phaser Graphics Game Object.
*
* This method is used internally by the Matter Debug Renderer, but is also exposed publically should
* you wish to render a Constraint to your own Graphics instance.
*
* @method Phaser.Physics.Matter.World#renderConstraint
* @since 3.22.0
*
* @param {MatterJS.ConstraintType} constraint - The Matter Constraint to render.
* @param {Phaser.GameObjects.Graphics} graphics - The Graphics object to render to.
* @param {number} lineColor - The line color.
* @param {number} lineOpacity - The line opacity, between 0 and 1.
* @param {number} lineThickness - The line thickness.
* @param {number} pinSize - If this constraint is a pin, this sets the size of the pin circle.
* @param {number} anchorColor - The color used when rendering this constraints anchors. Set to `null` to not render anchors.
* @param {number} anchorSize - The size of the anchor circle, if this constraint has anchors and is rendering them.
*
* @return {this} This Matter World instance for method chaining.
*/
renderConstraint: function(constraint, graphics, lineColor, lineOpacity, lineThickness, pinSize, anchorColor, anchorSize) {
var render = constraint.render;
if (!render.visible || !constraint.pointA || !constraint.pointB) {
return this;
}
graphics.lineStyle(lineThickness, lineColor, lineOpacity);
var bodyA = constraint.bodyA;
var bodyB = constraint.bodyB;
var start;
var end;
if (bodyA) {
start = Vector.add(bodyA.position, constraint.pointA);
} else {
start = constraint.pointA;
}
if (render.type === "pin") {
graphics.strokeCircle(start.x, start.y, pinSize);
} else {
if (bodyB) {
end = Vector.add(bodyB.position, constraint.pointB);
} else {
end = constraint.pointB;
}
graphics.beginPath();
graphics.moveTo(start.x, start.y);
if (render.type === "spring") {
var delta = Vector.sub(end, start);
var normal = Vector.perp(Vector.normalise(delta));
var coils = Math.ceil(Common.clamp(constraint.length / 5, 12, 20));
var offset;
for (var j = 1; j < coils; j += 1) {
offset = j % 2 === 0 ? 1 : -1;
graphics.lineTo(
start.x + delta.x * (j / coils) + normal.x * offset * 4,
start.y + delta.y * (j / coils) + normal.y * offset * 4
);
}
}
graphics.lineTo(end.x, end.y);
}
graphics.strokePath();
if (render.anchors && anchorSize > 0) {
graphics.fillStyle(anchorColor);
graphics.fillCircle(start.x, start.y, anchorSize);
graphics.fillCircle(end.x, end.y, anchorSize);
}
return this;
},
/**
* Resets the internal collision IDs that Matter.JS uses for Body collision groups.
*
* You should call this before destroying your game if you need to restart the game
* again on the same page, without first reloading the page. Or, if you wish to
* consistently destroy a Scene that contains Matter.js and then run it again
* later in the same game.
*
* @method Phaser.Physics.Matter.World#resetCollisionIDs
* @since 3.17.0
*/
resetCollisionIDs: function() {
Body._nextCollidingGroupId = 1;
Body._nextNonCollidingGroupId = -1;
Body._nextCategory = 1;
return this;
},
/**
* Will remove all Matter physics event listeners and clear the matter physics world,
* engine and any debug graphics, if any.
*
* @method Phaser.Physics.Matter.World#shutdown
* @since 3.0.0
*/
shutdown: function() {
MatterEvents.off(this.engine);
this.removeAllListeners();
MatterWorld.clear(this.localWorld, false);
Engine.clear(this.engine);
if (this.drawDebug) {
this.debugGraphic.destroy();
}
},
/**
* Will remove all Matter physics event listeners and clear the matter physics world,
* engine and any debug graphics, if any.
*
* After destroying the world it cannot be re-used again.
*
* @method Phaser.Physics.Matter.World#destroy
* @since 3.0.0
*/
destroy: function() {
this.shutdown();
}
});
module2.exports = World;
}
),
/***/
70410: (
/***/
(module2) => {
var Bounce = {
/**
* Sets the restitution on the physics object.
*
* @method Phaser.Physics.Matter.Components.Bounce#setBounce
* @since 3.0.0
*
* @param {number} value - A Number that defines the restitution (elasticity) of the body. The value is always positive and is in the range (0, 1). A value of 0 means collisions may be perfectly inelastic and no bouncing may occur. A value of 0.8 means the body may bounce back with approximately 80% of its kinetic energy. Note that collision response is based on pairs of bodies, and that restitution values are combined with the following formula: `Math.max(bodyA.restitution, bodyB.restitution)`
*
* @return {this} This Game Object instance.
*/
setBounce: function(value) {
this.body.restitution = value;
return this;
}
};
module2.exports = Bounce;
}
),
/***/
66968: (
/***/
(module2) => {
var Collision = {
/**
* Sets the collision category of this Game Object's Matter Body. This number must be a power of two between 2^0 (= 1) and 2^31.
* Two bodies with different collision groups (see {@link #setCollisionGroup}) will only collide if their collision
* categories are included in their collision masks (see {@link #setCollidesWith}).
*
* @method Phaser.Physics.Matter.Components.Collision#setCollisionCategory
* @since 3.0.0
*
* @param {number} value - Unique category bitfield.
*
* @return {this} This Game Object instance.
*/
setCollisionCategory: function(value) {
this.body.collisionFilter.category = value;
return this;
},
/**
* Sets the collision group of this Game Object's Matter Body. If this is zero or two Matter Bodies have different values,
* they will collide according to the usual rules (see {@link #setCollisionCategory} and {@link #setCollisionGroup}).
* If two Matter Bodies have the same positive value, they will always collide; if they have the same negative value,
* they will never collide.
*
* @method Phaser.Physics.Matter.Components.Collision#setCollisionGroup
* @since 3.0.0
*
* @param {number} value - Unique group index.
*
* @return {this} This Game Object instance.
*/
setCollisionGroup: function(value) {
this.body.collisionFilter.group = value;
return this;
},
/**
* Sets the collision mask for this Game Object's Matter Body. Two Matter Bodies with different collision groups will only
* collide if each one includes the other's category in its mask based on a bitwise AND, i.e. `(categoryA & maskB) !== 0`
* and `(categoryB & maskA) !== 0` are both true.
*
* @method Phaser.Physics.Matter.Components.Collision#setCollidesWith
* @since 3.0.0
*
* @param {(number|number[])} categories - A unique category bitfield, or an array of them.
*
* @return {this} This Game Object instance.
*/
setCollidesWith: function(categories) {
var flags = 0;
if (!Array.isArray(categories)) {
flags = categories;
} else {
for (var i = 0; i < categories.length; i++) {
flags |= categories[i];
}
}
this.body.collisionFilter.mask = flags;
return this;
},
/**
* The callback is sent a `Phaser.Types.Physics.Matter.MatterCollisionData` object.
*
* This does not change the bodies collision category, group or filter. Those must be set in addition
* to the callback.
*
* @method Phaser.Physics.Matter.Components.Collision#setOnCollide
* @since 3.22.0
*
* @param {function} callback - The callback to invoke when this body starts colliding with another.
*
* @return {this} This Game Object instance.
*/
setOnCollide: function(callback) {
this.body.onCollideCallback = callback;
return this;
},
/**
* The callback is sent a `Phaser.Types.Physics.Matter.MatterCollisionData` object.
*
* This does not change the bodies collision category, group or filter. Those must be set in addition
* to the callback.
*
* @method Phaser.Physics.Matter.Components.Collision#setOnCollideEnd
* @since 3.22.0
*
* @param {function} callback - The callback to invoke when this body stops colliding with another.
*
* @return {this} This Game Object instance.
*/
setOnCollideEnd: function(callback) {
this.body.onCollideEndCallback = callback;
return this;
},
/**
* The callback is sent a `Phaser.Types.Physics.Matter.MatterCollisionData` object.
*
* This does not change the bodies collision category, group or filter. Those must be set in addition
* to the callback.
*
* @method Phaser.Physics.Matter.Components.Collision#setOnCollideActive
* @since 3.22.0
*
* @param {function} callback - The callback to invoke for the duration of this body colliding with another.
*
* @return {this} This Game Object instance.
*/
setOnCollideActive: function(callback) {
this.body.onCollideActiveCallback = callback;
return this;
},
/**
* The callback is sent a reference to the other body, along with a `Phaser.Types.Physics.Matter.MatterCollisionData` object.
*
* This does not change the bodies collision category, group or filter. Those must be set in addition
* to the callback.
*
* @method Phaser.Physics.Matter.Components.Collision#setOnCollideWith
* @since 3.22.0
*
* @param {(MatterJS.Body|MatterJS.Body[])} body - The body, or an array of bodies, to test for collisions with.
* @param {function} callback - The callback to invoke when this body collides with the given body or bodies.
*
* @return {this} This Game Object instance.
*/
setOnCollideWith: function(body, callback) {
if (!Array.isArray(body)) {
body = [body];
}
for (var i = 0; i < body.length; i++) {
var src = body[i].hasOwnProperty("body") ? body[i].body : body[i];
this.body.setOnCollideWith(src, callback);
}
return this;
}
};
module2.exports = Collision;
}
),
/***/
51607: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Body = __webpack_require__2(22562);
var Force = {
// force = vec2 / point
/**
* Applies a force to a body.
*
* @method Phaser.Physics.Matter.Components.Force#applyForce
* @since 3.0.0
*
* @param {Phaser.Math.Vector2} force - A Vector that specifies the force to apply.
*
* @return {this} This Game Object instance.
*/
applyForce: function(force) {
this._tempVec2.set(this.body.position.x, this.body.position.y);
Body.applyForce(this.body, this._tempVec2, force);
return this;
},
/**
* Applies a force to a body from a given position.
*
* @method Phaser.Physics.Matter.Components.Force#applyForceFrom
* @since 3.0.0
*
* @param {Phaser.Math.Vector2} position - The position in which the force comes from.
* @param {Phaser.Math.Vector2} force - A Vector that specifies the force to apply.
*
* @return {this} This Game Object instance.
*/
applyForceFrom: function(position, force) {
Body.applyForce(this.body, position, force);
return this;
},
/**
* Apply thrust to the forward position of the body.
*
* Use very small values, such as 0.1, depending on the mass and required speed.
*
* @method Phaser.Physics.Matter.Components.Force#thrust
* @since 3.0.0
*
* @param {number} speed - A speed value to be applied to a directional force.
*
* @return {this} This Game Object instance.
*/
thrust: function(speed) {
var angle = this.body.angle;
this._tempVec2.set(speed * Math.cos(angle), speed * Math.sin(angle));
Body.applyForce(this.body, { x: this.body.position.x, y: this.body.position.y }, this._tempVec2);
return this;
},
/**
* Apply thrust to the left position of the body.
*
* Use very small values, such as 0.1, depending on the mass and required speed.
*
* @method Phaser.Physics.Matter.Components.Force#thrustLeft
* @since 3.0.0
*
* @param {number} speed - A speed value to be applied to a directional force.
*
* @return {this} This Game Object instance.
*/
thrustLeft: function(speed) {
var angle = this.body.angle - Math.PI / 2;
this._tempVec2.set(speed * Math.cos(angle), speed * Math.sin(angle));
Body.applyForce(this.body, { x: this.body.position.x, y: this.body.position.y }, this._tempVec2);
return this;
},
/**
* Apply thrust to the right position of the body.
*
* Use very small values, such as 0.1, depending on the mass and required speed.
*
* @method Phaser.Physics.Matter.Components.Force#thrustRight
* @since 3.0.0
*
* @param {number} speed - A speed value to be applied to a directional force.
*
* @return {this} This Game Object instance.
*/
thrustRight: function(speed) {
var angle = this.body.angle + Math.PI / 2;
this._tempVec2.set(speed * Math.cos(angle), speed * Math.sin(angle));
Body.applyForce(this.body, { x: this.body.position.x, y: this.body.position.y }, this._tempVec2);
return this;
},
/**
* Apply thrust to the back position of the body.
*
* Use very small values, such as 0.1, depending on the mass and required speed.
*
* @method Phaser.Physics.Matter.Components.Force#thrustBack
* @since 3.0.0
*
* @param {number} speed - A speed value to be applied to a directional force.
*
* @return {this} This Game Object instance.
*/
thrustBack: function(speed) {
var angle = this.body.angle - Math.PI;
this._tempVec2.set(speed * Math.cos(angle), speed * Math.sin(angle));
Body.applyForce(this.body, { x: this.body.position.x, y: this.body.position.y }, this._tempVec2);
return this;
}
};
module2.exports = Force;
}
),
/***/
5436: (
/***/
(module2) => {
var Friction = {
/**
* Sets new friction values for this Game Object's Matter Body.
*
* @method Phaser.Physics.Matter.Components.Friction#setFriction
* @since 3.0.0
*
* @param {number} value - The new friction of the body, between 0 and 1, where 0 allows the Body to slide indefinitely, while 1 allows it to stop almost immediately after a force is applied.
* @param {number} [air] - If provided, the new air resistance of the Body. The higher the value, the faster the Body will slow as it moves through space. 0 means the body has no air resistance.
* @param {number} [fstatic] - If provided, the new static friction of the Body. The higher the value (e.g. 10), the more force it will take to initially get the Body moving when it is nearly stationary. 0 means the body will never "stick" when it is nearly stationary.
*
* @return {this} This Game Object instance.
*/
setFriction: function(value, air, fstatic) {
this.body.friction = value;
if (air !== void 0) {
this.body.frictionAir = air;
}
if (fstatic !== void 0) {
this.body.frictionStatic = fstatic;
}
return this;
},
/**
* Sets a new air resistance for this Game Object's Matter Body.
* A value of 0 means the Body will never slow as it moves through space.
* The higher the value, the faster a Body slows when moving through space.
*
* @method Phaser.Physics.Matter.Components.Friction#setFrictionAir
* @since 3.0.0
*
* @param {number} value - The new air resistance for the Body.
*
* @return {this} This Game Object instance.
*/
setFrictionAir: function(value) {
this.body.frictionAir = value;
return this;
},
/**
* Sets a new static friction for this Game Object's Matter Body.
* A value of 0 means the Body will never "stick" when it is nearly stationary.
* The higher the value (e.g. 10), the more force it will take to initially get the Body moving when it is nearly stationary.
*
* @method Phaser.Physics.Matter.Components.Friction#setFrictionStatic
* @since 3.0.0
*
* @param {number} value - The new static friction for the Body.
*
* @return {this} This Game Object instance.
*/
setFrictionStatic: function(value) {
this.body.frictionStatic = value;
return this;
}
};
module2.exports = Friction;
}
),
/***/
39858: (
/***/
(module2) => {
var Gravity = {
/**
* A togglable function for ignoring world gravity in real-time on the current body.
*
* @method Phaser.Physics.Matter.Components.Gravity#setIgnoreGravity
* @since 3.0.0
*
* @param {boolean} value - Set to true to ignore the effect of world gravity, or false to not ignore it.
*
* @return {this} This Game Object instance.
*/
setIgnoreGravity: function(value) {
this.body.ignoreGravity = value;
return this;
}
};
module2.exports = Gravity;
}
),
/***/
37302: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Body = __webpack_require__2(22562);
var Vector2 = __webpack_require__2(26099);
var Mass = {
/**
* Sets the mass of the Game Object's Matter Body.
*
* @method Phaser.Physics.Matter.Components.Mass#setMass
* @since 3.0.0
*
* @param {number} value - The new mass of the body.
*
* @return {this} This Game Object instance.
*/
setMass: function(value) {
Body.setMass(this.body, value);
return this;
},
/**
* Sets density of the body.
*
* @method Phaser.Physics.Matter.Components.Mass#setDensity
* @since 3.0.0
*
* @param {number} value - The new density of the body.
*
* @return {this} This Game Object instance.
*/
setDensity: function(value) {
Body.setDensity(this.body, value);
return this;
},
/**
* The body's center of mass.
*
* Calling this creates a new `Vector2 each time to avoid mutation.
*
* If you only need to read the value and won't change it, you can get it from `GameObject.body.centerOfMass`.
*
* @name Phaser.Physics.Matter.Components.Mass#centerOfMass
* @type {Phaser.Math.Vector2}
* @readonly
* @since 3.10.0
*
* @return {Phaser.Math.Vector2} The center of mass.
*/
centerOfMass: {
get: function() {
return new Vector2(this.body.centerOfMass.x, this.body.centerOfMass.y);
}
}
};
module2.exports = Mass;
}
),
/***/
39132: (
/***/
(module2) => {
var Sensor = {
/**
* Set the body belonging to this Game Object to be a sensor.
* Sensors trigger collision events, but don't react with colliding body physically.
*
* @method Phaser.Physics.Matter.Components.Sensor#setSensor
* @since 3.0.0
*
* @param {boolean} value - `true` to set the body as a sensor, or `false` to disable it.
*
* @return {this} This Game Object instance.
*/
setSensor: function(value) {
this.body.isSensor = value;
return this;
},
/**
* Is the body belonging to this Game Object a sensor or not?
*
* @method Phaser.Physics.Matter.Components.Sensor#isSensor
* @since 3.0.0
*
* @return {boolean} `true` if the body is a sensor, otherwise `false`.
*/
isSensor: function() {
return this.body.isSensor;
}
};
module2.exports = Sensor;
}
),
/***/
57772: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Bodies = __webpack_require__2(66280);
var Body = __webpack_require__2(22562);
var FuzzyEquals = __webpack_require__2(43855);
var GetFastValue = __webpack_require__2(95540);
var PhysicsEditorParser = __webpack_require__2(19496);
var PhysicsJSONParser = __webpack_require__2(85791);
var Vertices = __webpack_require__2(41598);
var SetBody = {
/**
* Set this Game Objects Matter physics body to be a rectangle shape.
*
* Calling this methods resets all previous properties you may have set on the body, including
* plugins, mass, friction, collision categories, etc. So be sure to re-apply these as needed.
*
* @method Phaser.Physics.Matter.Components.SetBody#setRectangle
* @since 3.0.0
*
* @param {number} width - Width of the rectangle.
* @param {number} height - Height of the rectangle.
* @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation.
*
* @return {this} This Game Object instance.
*/
setRectangle: function(width, height, options) {
return this.setBody({ type: "rectangle", width, height }, options);
},
/**
* Set this Game Objects Matter physics body to be a circle shape.
*
* Calling this methods resets all previous properties you may have set on the body, including
* plugins, mass, friction, collision categories, etc. So be sure to re-apply these as needed.
*
* @method Phaser.Physics.Matter.Components.SetBody#setCircle
* @since 3.0.0
*
* @param {number} radius - The radius of the circle.
* @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation.
*
* @return {this} This Game Object instance.
*/
setCircle: function(radius, options) {
return this.setBody({ type: "circle", radius }, options);
},
/**
* Set this Game Objects Matter physics body to be a polygon shape.
*
* Calling this methods resets all previous properties you may have set on the body, including
* plugins, mass, friction, collision categories, etc. So be sure to re-apply these as needed.
*
* @method Phaser.Physics.Matter.Components.SetBody#setPolygon
* @since 3.0.0
*
* @param {number} radius - The "radius" of the polygon, i.e. the distance from its center to any vertex. This is also the radius of its circumcircle.
* @param {number} sides - The number of sides the polygon will have.
* @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation.
*
* @return {this} This Game Object instance.
*/
setPolygon: function(radius, sides, options) {
return this.setBody({ type: "polygon", sides, radius }, options);
},
/**
* Set this Game Objects Matter physics body to be a trapezoid shape.
*
* Calling this methods resets all previous properties you may have set on the body, including
* plugins, mass, friction, collision categories, etc. So be sure to re-apply these as needed.
*
* @method Phaser.Physics.Matter.Components.SetBody#setTrapezoid
* @since 3.0.0
*
* @param {number} width - The width of the trapezoid Body.
* @param {number} height - The height of the trapezoid Body.
* @param {number} slope - The slope of the trapezoid. 0 creates a rectangle, while 1 creates a triangle. Positive values make the top side shorter, while negative values make the bottom side shorter.
* @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation.
*
* @return {this} This Game Object instance.
*/
setTrapezoid: function(width, height, slope, options) {
return this.setBody({ type: "trapezoid", width, height, slope }, options);
},
/**
* Set this Game Object to use the given existing Matter Body.
*
* The body is first removed from the world before being added to this Game Object.
*
* @method Phaser.Physics.Matter.Components.SetBody#setExistingBody
* @since 3.0.0
*
* @param {MatterJS.BodyType} body - The Body this Game Object should use.
* @param {boolean} [addToWorld=true] - Should the body be immediately added to the World?
*
* @return {this} This Game Object instance.
*/
setExistingBody: function(body, addToWorld) {
if (addToWorld === void 0) {
addToWorld = true;
}
if (this.body) {
this.world.remove(this.body, true);
}
this.body = body;
for (var i = 0; i < body.parts.length; i++) {
body.parts[i].gameObject = this;
}
var _this = this;
body.destroy = function destroy() {
_this.world.remove(_this.body, true);
_this.body.gameObject = null;
};
if (addToWorld) {
if (this.world.has(body)) {
this.world.remove(body, true);
}
this.world.add(body);
}
if (this._originComponent) {
var rx = body.render.sprite.xOffset;
var ry = body.render.sprite.yOffset;
var comx = body.centerOfMass.x;
var comy = body.centerOfMass.y;
if (FuzzyEquals(comx, 0.5) && FuzzyEquals(comy, 0.5)) {
this.setOrigin(rx + 0.5, ry + 0.5);
} else {
var cx = body.centerOffset.x;
var cy = body.centerOffset.y;
this.setOrigin(rx + cx / this.displayWidth, ry + cy / this.displayHeight);
}
}
return this;
},
/**
* Set this Game Object to create and use a new Body based on the configuration object given.
*
* Calling this methods resets all previous properties you may have set on the body, including
* plugins, mass, friction, collision categories, etc. So be sure to re-apply these as needed.
*
* @method Phaser.Physics.Matter.Components.SetBody#setBody
* @since 3.0.0
*
* @param {(string|Phaser.Types.Physics.Matter.MatterSetBodyConfig)} config - Either a string, such as `circle`, or a Matter Set Body Configuration object.
* @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation.
*
* @return {this} This Game Object instance.
*/
setBody: function(config, options) {
if (!config) {
return this;
}
var body;
if (typeof config === "string") {
config = { type: config };
}
var shapeType = GetFastValue(config, "type", "rectangle");
var bodyX = GetFastValue(config, "x", this._tempVec2.x);
var bodyY = GetFastValue(config, "y", this._tempVec2.y);
var bodyWidth = GetFastValue(config, "width", this.width);
var bodyHeight = GetFastValue(config, "height", this.height);
switch (shapeType) {
case "rectangle":
body = Bodies.rectangle(bodyX, bodyY, bodyWidth, bodyHeight, options);
break;
case "circle":
var radius = GetFastValue(config, "radius", Math.max(bodyWidth, bodyHeight) / 2);
var maxSides = GetFastValue(config, "maxSides", 25);
body = Bodies.circle(bodyX, bodyY, radius, options, maxSides);
break;
case "trapezoid":
var slope = GetFastValue(config, "slope", 0.5);
body = Bodies.trapezoid(bodyX, bodyY, bodyWidth, bodyHeight, slope, options);
break;
case "polygon":
var sides = GetFastValue(config, "sides", 5);
var pRadius = GetFastValue(config, "radius", Math.max(bodyWidth, bodyHeight) / 2);
body = Bodies.polygon(bodyX, bodyY, sides, pRadius, options);
break;
case "fromVertices":
case "fromVerts":
var verts = GetFastValue(config, "verts", null);
if (verts) {
if (typeof verts === "string") {
verts = Vertices.fromPath(verts);
}
if (this.body && !this.body.hasOwnProperty("temp")) {
Body.setVertices(this.body, verts);
body = this.body;
} else {
var flagInternal = GetFastValue(config, "flagInternal", false);
var removeCollinear = GetFastValue(config, "removeCollinear", 0.01);
var minimumArea = GetFastValue(config, "minimumArea", 10);
body = Bodies.fromVertices(bodyX, bodyY, verts, options, flagInternal, removeCollinear, minimumArea);
}
}
break;
case "fromPhysicsEditor":
body = PhysicsEditorParser.parseBody(bodyX, bodyY, config, options);
break;
case "fromPhysicsTracer":
body = PhysicsJSONParser.parseBody(bodyX, bodyY, config, options);
break;
}
if (body) {
this.setExistingBody(body, config.addToWorld);
}
return this;
}
};
module2.exports = SetBody;
}
),
/***/
38083: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Events = __webpack_require__2(1121);
var Sleeping = __webpack_require__2(53614);
var MatterEvents = __webpack_require__2(35810);
var Sleep = {
/**
* Sets this Body to sleep.
*
* @method Phaser.Physics.Matter.Components.Sleep#setToSleep
* @since 3.22.0
*
* @return {this} This Game Object instance.
*/
setToSleep: function() {
Sleeping.set(this.body, true);
return this;
},
/**
* Wakes this Body if asleep.
*
* @method Phaser.Physics.Matter.Components.Sleep#setAwake
* @since 3.22.0
*
* @return {this} This Game Object instance.
*/
setAwake: function() {
Sleeping.set(this.body, false);
return this;
},
/**
* Sets the number of updates in which this body must have near-zero velocity before it is set as sleeping (if sleeping is enabled by the engine).
*
* @method Phaser.Physics.Matter.Components.Sleep#setSleepThreshold
* @since 3.0.0
*
* @param {number} [value=60] - A `Number` that defines the number of updates in which this body must have near-zero velocity before it is set as sleeping.
*
* @return {this} This Game Object instance.
*/
setSleepThreshold: function(value) {
if (value === void 0) {
value = 60;
}
this.body.sleepThreshold = value;
return this;
},
/**
* Enable sleep and wake events for this body.
*
* By default when a body goes to sleep, or wakes up, it will not emit any events.
*
* The events are emitted by the Matter World instance and can be listened to via
* the `SLEEP_START` and `SLEEP_END` events.
*
* @method Phaser.Physics.Matter.Components.Sleep#setSleepEvents
* @since 3.0.0
*
* @param {boolean} start - `true` if you want the sleep start event to be emitted for this body.
* @param {boolean} end - `true` if you want the sleep end event to be emitted for this body.
*
* @return {this} This Game Object instance.
*/
setSleepEvents: function(start, end) {
this.setSleepStartEvent(start);
this.setSleepEndEvent(end);
return this;
},
/**
* Enables or disables the Sleep Start event for this body.
*
* @method Phaser.Physics.Matter.Components.Sleep#setSleepStartEvent
* @since 3.0.0
*
* @param {boolean} value - `true` to enable the sleep event, or `false` to disable it.
*
* @return {this} This Game Object instance.
*/
setSleepStartEvent: function(value) {
if (value) {
var world = this.world;
MatterEvents.on(this.body, "sleepStart", function(event) {
world.emit(Events.SLEEP_START, event, this);
});
} else {
MatterEvents.off(this.body, "sleepStart");
}
return this;
},
/**
* Enables or disables the Sleep End event for this body.
*
* @method Phaser.Physics.Matter.Components.Sleep#setSleepEndEvent
* @since 3.0.0
*
* @param {boolean} value - `true` to enable the sleep event, or `false` to disable it.
*
* @return {this} This Game Object instance.
*/
setSleepEndEvent: function(value) {
if (value) {
var world = this.world;
MatterEvents.on(this.body, "sleepEnd", function(event) {
world.emit(Events.SLEEP_END, event, this);
});
} else {
MatterEvents.off(this.body, "sleepEnd");
}
return this;
}
};
module2.exports = Sleep;
}
),
/***/
90556: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Body = __webpack_require__2(22562);
var Static = {
/**
* Changes the physics body to be either static `true` or dynamic `false`.
*
* @method Phaser.Physics.Matter.Components.Static#setStatic
* @since 3.0.0
*
* @param {boolean} value - `true` to set the body as being static, or `false` to make it dynamic.
*
* @return {this} This Game Object instance.
*/
setStatic: function(value) {
Body.setStatic(this.body, value);
return this;
},
/**
* Returns `true` if the body is static, otherwise `false` for a dynamic body.
*
* @method Phaser.Physics.Matter.Components.Static#isStatic
* @since 3.0.0
*
* @return {boolean} `true` if the body is static, otherwise `false`.
*/
isStatic: function() {
return this.body.isStatic;
}
};
module2.exports = Static;
}
),
/***/
85436: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Body = __webpack_require__2(22562);
var MATH_CONST = __webpack_require__2(36383);
var WrapAngle = __webpack_require__2(86554);
var WrapAngleDegrees = __webpack_require__2(30954);
var _FLAG = 4;
var Transform = {
/**
* The x position of this Game Object.
*
* @name Phaser.Physics.Matter.Components.Transform#x
* @type {number}
* @since 3.0.0
*/
x: {
get: function() {
return this.body.position.x;
},
set: function(value) {
this._tempVec2.set(value, this.y);
Body.setPosition(this.body, this._tempVec2);
}
},
/**
* The y position of this Game Object.
*
* @name Phaser.Physics.Matter.Components.Transform#y
* @type {number}
* @since 3.0.0
*/
y: {
get: function() {
return this.body.position.y;
},
set: function(value) {
this._tempVec2.set(this.x, value);
Body.setPosition(this.body, this._tempVec2);
}
},
/**
* The horizontal scale of this Game Object.
*
* @name Phaser.Physics.Matter.Components.Transform#scaleX
* @type {number}
* @since 3.0.0
*/
scaleX: {
get: function() {
return this._scaleX;
},
set: function(value) {
var factorX = 1 / this._scaleX;
var factorY = 1 / this._scaleY;
this._scaleX = value;
if (this._scaleX === 0) {
this.renderFlags &= ~_FLAG;
} else {
this.renderFlags |= _FLAG;
}
Body.scale(this.body, factorX, factorY);
Body.scale(this.body, value, this._scaleY);
}
},
/**
* The vertical scale of this Game Object.
*
* @name Phaser.Physics.Matter.Components.Transform#scaleY
* @type {number}
* @since 3.0.0
*/
scaleY: {
get: function() {
return this._scaleY;
},
set: function(value) {
var factorX = 1 / this._scaleX;
var factorY = 1 / this._scaleY;
this._scaleY = value;
if (this._scaleY === 0) {
this.renderFlags &= ~_FLAG;
} else {
this.renderFlags |= _FLAG;
}
Body.scale(this.body, factorX, factorY);
Body.scale(this.body, this._scaleX, value);
}
},
/**
* Use `angle` to set or get rotation of the physics body associated to this GameObject.
* Unlike rotation, when using set the value can be in degrees, which will be converted to radians internally.
*
* @name Phaser.Physics.Matter.Components.Transform#angle
* @type {number}
* @since 3.0.0
*/
angle: {
get: function() {
return WrapAngleDegrees(this.body.angle * MATH_CONST.RAD_TO_DEG);
},
set: function(value) {
this.rotation = WrapAngleDegrees(value) * MATH_CONST.DEG_TO_RAD;
}
},
/**
* Use `rotation` to set or get the rotation of the physics body associated with this GameObject.
* The value when set must be in radians.
*
* @name Phaser.Physics.Matter.Components.Transform#rotation
* @type {number}
* @since 3.0.0
*/
rotation: {
get: function() {
return this.body.angle;
},
set: function(value) {
this._rotation = WrapAngle(value);
Body.setAngle(this.body, this._rotation);
}
},
/**
* Sets the position of the physics body along x and y axes.
* Both the parameters to this function are optional and if not passed any they default to 0.
* Velocity, angle, force etc. are unchanged.
*
* @method Phaser.Physics.Matter.Components.Transform#setPosition
* @since 3.0.0
*
* @param {number} [x=0] - The horizontal position of the body.
* @param {number} [y=x] - The vertical position of the body.
*
* @return {this} This Game Object instance.
*/
setPosition: function(x, y) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = x;
}
this._tempVec2.set(x, y);
Body.setPosition(this.body, this._tempVec2);
return this;
},
/**
* Immediately sets the angle of the Body.
* Angular velocity, position, force etc. are unchanged.
*
* @method Phaser.Physics.Matter.Components.Transform#setRotation
* @since 3.0.0
*
* @param {number} [radians=0] - The angle of the body, in radians.
*
* @return {this} This Game Object instance.
*/
setRotation: function(radians) {
if (radians === void 0) {
radians = 0;
}
this._rotation = WrapAngle(radians);
Body.setAngle(this.body, radians);
return this;
},
/**
* Setting fixed rotation sets the Body inertia to Infinity, which stops it
* from being able to rotate when forces are applied to it.
*
* @method Phaser.Physics.Matter.Components.Transform#setFixedRotation
* @since 3.0.0
*
* @return {this} This Game Object instance.
*/
setFixedRotation: function() {
Body.setInertia(this.body, Infinity);
return this;
},
/**
* Immediately sets the angle of the Body.
* Angular velocity, position, force etc. are unchanged.
*
* @method Phaser.Physics.Matter.Components.Transform#setAngle
* @since 3.0.0
*
* @param {number} [degrees=0] - The angle to set, in degrees.
*
* @return {this} This Game Object instance.
*/
setAngle: function(degrees) {
if (degrees === void 0) {
degrees = 0;
}
this.angle = degrees;
Body.setAngle(this.body, this.rotation);
return this;
},
/**
* Sets the scale of this Game Object.
*
* @method Phaser.Physics.Matter.Components.Transform#setScale
* @since 3.0.0
*
* @param {number} [x=1] - The horizontal scale of this Game Object.
* @param {number} [y=x] - The vertical scale of this Game Object. If not set it will use the x value.
* @param {Phaser.Math.Vector2} [point] - The point (Vector2) from which scaling will occur.
*
* @return {this} This Game Object instance.
*/
setScale: function(x, y, point) {
if (x === void 0) {
x = 1;
}
if (y === void 0) {
y = x;
}
var factorX = 1 / this._scaleX;
var factorY = 1 / this._scaleY;
this._scaleX = x;
this._scaleY = y;
Body.scale(this.body, factorX, factorY, point);
Body.scale(this.body, x, y, point);
return this;
}
};
module2.exports = Transform;
}
),
/***/
42081: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Body = __webpack_require__2(22562);
var Velocity = {
/**
* Sets the horizontal velocity of the physics body.
*
* @method Phaser.Physics.Matter.Components.Velocity#setVelocityX
* @since 3.0.0
*
* @param {number} x - The horizontal velocity value.
*
* @return {this} This Game Object instance.
*/
setVelocityX: function(x) {
this._tempVec2.set(x, this.body.velocity.y);
Body.setVelocity(this.body, this._tempVec2);
return this;
},
/**
* Sets vertical velocity of the physics body.
*
* @method Phaser.Physics.Matter.Components.Velocity#setVelocityY
* @since 3.0.0
*
* @param {number} y - The vertical velocity value.
*
* @return {this} This Game Object instance.
*/
setVelocityY: function(y) {
this._tempVec2.set(this.body.velocity.x, y);
Body.setVelocity(this.body, this._tempVec2);
return this;
},
/**
* Sets both the horizontal and vertical velocity of the physics body.
*
* @method Phaser.Physics.Matter.Components.Velocity#setVelocity
* @since 3.0.0
*
* @param {number} x - The horizontal velocity value.
* @param {number} [y=x] - The vertical velocity value, it can be either positive or negative. If not given, it will be the same as the `x` value.
*
* @return {this} This Game Object instance.
*/
setVelocity: function(x, y) {
this._tempVec2.set(x, y);
Body.setVelocity(this.body, this._tempVec2);
return this;
},
/**
* Gets the current linear velocity of the physics body.
*
* @method Phaser.Physics.Matter.Components.Velocity#getVelocity
* @since 3.60.0
*
* @return {Phaser.Types.Math.Vector2Like} The current linear velocity of the body.
*/
getVelocity: function() {
return Body.getVelocity(this.body);
},
/**
* Sets the angular velocity of the body instantly.
* Position, angle, force etc. are unchanged.
*
* @method Phaser.Physics.Matter.Components.Velocity#setAngularVelocity
* @since 3.0.0
*
* @param {number} velocity - The angular velocity.
*
* @return {this} This Game Object instance.
*/
setAngularVelocity: function(velocity) {
Body.setAngularVelocity(this.body, velocity);
return this;
},
/**
* Gets the current rotational velocity of the body.
*
* @method Phaser.Physics.Matter.Components.Velocity#getAngularVelocity
* @since 3.60.0
*
* @return {number} The current angular velocity of the body.
*/
getAngularVelocity: function() {
return Body.getAngularVelocity(this.body);
},
/**
* Sets the current rotational speed of the body.
* Direction is maintained. Affects body angular velocity.
*
* @method Phaser.Physics.Matter.Components.Velocity#setAngularSpeed
* @since 3.60.0
*
* @param {number} speed - The angular speed.
*
* @return {this} This Game Object instance.
*/
setAngularSpeed: function(speed) {
Body.setAngularSpeed(this.body, speed);
return this;
},
/**
* Gets the current rotational speed of the body.
* Equivalent to the magnitude of its angular velocity.
*
* @method Phaser.Physics.Matter.Components.Velocity#getAngularSpeed
* @since 3.60.0
*
* @return {number} The current angular velocity of the body.
*/
getAngularSpeed: function() {
return Body.getAngularSpeed(this.body);
}
};
module2.exports = Velocity;
}
),
/***/
31884: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Bounce: __webpack_require__2(70410),
Collision: __webpack_require__2(66968),
Force: __webpack_require__2(51607),
Friction: __webpack_require__2(5436),
Gravity: __webpack_require__2(39858),
Mass: __webpack_require__2(37302),
Sensor: __webpack_require__2(39132),
SetBody: __webpack_require__2(57772),
Sleep: __webpack_require__2(38083),
Static: __webpack_require__2(90556),
Transform: __webpack_require__2(85436),
Velocity: __webpack_require__2(42081)
};
}
),
/***/
85608: (
/***/
(module2) => {
module2.exports = "afteradd";
}
),
/***/
1213: (
/***/
(module2) => {
module2.exports = "afterremove";
}
),
/***/
25968: (
/***/
(module2) => {
module2.exports = "afterupdate";
}
),
/***/
67205: (
/***/
(module2) => {
module2.exports = "beforeadd";
}
),
/***/
39438: (
/***/
(module2) => {
module2.exports = "beforeremove";
}
),
/***/
44823: (
/***/
(module2) => {
module2.exports = "beforeupdate";
}
),
/***/
92593: (
/***/
(module2) => {
module2.exports = "collisionactive";
}
),
/***/
60128: (
/***/
(module2) => {
module2.exports = "collisionend";
}
),
/***/
76861: (
/***/
(module2) => {
module2.exports = "collisionstart";
}
),
/***/
92362: (
/***/
(module2) => {
module2.exports = "dragend";
}
),
/***/
76408: (
/***/
(module2) => {
module2.exports = "drag";
}
),
/***/
93971: (
/***/
(module2) => {
module2.exports = "dragstart";
}
),
/***/
5656: (
/***/
(module2) => {
module2.exports = "pause";
}
),
/***/
47861: (
/***/
(module2) => {
module2.exports = "resume";
}
),
/***/
79099: (
/***/
(module2) => {
module2.exports = "sleepend";
}
),
/***/
35906: (
/***/
(module2) => {
module2.exports = "sleepstart";
}
),
/***/
1121: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
AFTER_ADD: __webpack_require__2(85608),
AFTER_REMOVE: __webpack_require__2(1213),
AFTER_UPDATE: __webpack_require__2(25968),
BEFORE_ADD: __webpack_require__2(67205),
BEFORE_REMOVE: __webpack_require__2(39438),
BEFORE_UPDATE: __webpack_require__2(44823),
COLLISION_ACTIVE: __webpack_require__2(92593),
COLLISION_END: __webpack_require__2(60128),
COLLISION_START: __webpack_require__2(76861),
DRAG_END: __webpack_require__2(92362),
DRAG: __webpack_require__2(76408),
DRAG_START: __webpack_require__2(93971),
PAUSE: __webpack_require__2(5656),
RESUME: __webpack_require__2(47861),
SLEEP_END: __webpack_require__2(79099),
SLEEP_START: __webpack_require__2(35906)
};
}
),
/***/
3875: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
BodyBounds: __webpack_require__2(68174),
Components: __webpack_require__2(31884),
Events: __webpack_require__2(1121),
Factory: __webpack_require__2(28137),
MatterGameObject: __webpack_require__2(75803),
Image: __webpack_require__2(23181),
Matter: __webpack_require__2(19933),
MatterPhysics: __webpack_require__2(42045),
PolyDecomp: __webpack_require__2(55973),
Sprite: __webpack_require__2(34803),
TileBody: __webpack_require__2(73834),
PhysicsEditorParser: __webpack_require__2(19496),
PhysicsJSONParser: __webpack_require__2(85791),
PointerConstraint: __webpack_require__2(98713),
World: __webpack_require__2(68243)
};
}
),
/***/
22562: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Body = {};
module2.exports = Body;
var Vertices = __webpack_require__2(41598);
var Vector = __webpack_require__2(31725);
var Sleeping = __webpack_require__2(53614);
var Common = __webpack_require__2(53402);
var Bounds = __webpack_require__2(15647);
var Axes = __webpack_require__2(66615);
(function() {
Body._timeCorrection = true;
Body._inertiaScale = 4;
Body._nextCollidingGroupId = 1;
Body._nextNonCollidingGroupId = -1;
Body._nextCategory = 1;
Body._baseDelta = 1e3 / 60;
Body.create = function(options) {
var defaults = {
id: Common.nextId(),
type: "body",
label: "Body",
parts: [],
plugin: {},
attractors: options.attractors || [],
wrapBounds: null,
angle: 0,
vertices: null,
// Phaser change: no point calling fromPath if they pass in vertices anyway
position: { x: 0, y: 0 },
force: { x: 0, y: 0 },
torque: 0,
positionImpulse: { x: 0, y: 0 },
constraintImpulse: { x: 0, y: 0, angle: 0 },
totalContacts: 0,
speed: 0,
angularSpeed: 0,
velocity: { x: 0, y: 0 },
angularVelocity: 0,
isSensor: false,
isStatic: false,
isSleeping: false,
motion: 0,
sleepThreshold: 60,
density: 1e-3,
restitution: 0,
friction: 0.1,
frictionStatic: 0.5,
frictionAir: 0.01,
collisionFilter: {
category: 1,
mask: 4294967295,
group: 0
},
slop: 0.05,
timeScale: 1,
events: null,
bounds: null,
chamfer: null,
circleRadius: 0,
positionPrev: null,
anglePrev: 0,
parent: null,
axes: null,
area: 0,
mass: 0,
inverseMass: 0,
inertia: 0,
deltaTime: 1e3 / 60,
inverseInertia: 0,
_original: null,
render: {
visible: true,
opacity: 1,
sprite: {
xOffset: 0,
yOffset: 0
},
fillColor: null,
// custom Phaser property
fillOpacity: null,
// custom Phaser property
lineColor: null,
// custom Phaser property
lineOpacity: null,
// custom Phaser property
lineThickness: null
// custom Phaser property
},
gameObject: null,
// custom Phaser property
scale: { x: 1, y: 1 },
// custom Phaser property
centerOfMass: { x: 0, y: 0 },
// custom Phaser property (float, 0 - 1)
centerOffset: { x: 0, y: 0 },
// custom Phaser property (pixel values)
gravityScale: { x: 1, y: 1 },
// custom Phaser property
ignoreGravity: false,
// custom Phaser property
ignorePointer: false,
// custom Phaser property
onCollideCallback: null,
// custom Phaser property
onCollideEndCallback: null,
// custom Phaser property
onCollideActiveCallback: null,
// custom Phaser property
onCollideWith: {}
// custom Phaser property
};
if (!options.hasOwnProperty("position") && options.hasOwnProperty("vertices")) {
options.position = Vertices.centre(options.vertices);
} else if (!options.hasOwnProperty("vertices")) {
defaults.vertices = Vertices.fromPath("L 0 0 L 40 0 L 40 40 L 0 40");
}
var body = Common.extend(defaults, options);
_initProperties(body, options);
body.setOnCollideWith = function(body2, callback) {
if (callback) {
this.onCollideWith[body2.id] = callback;
} else {
delete this.onCollideWith[body2.id];
}
return this;
};
return body;
};
Body.nextGroup = function(isNonColliding) {
if (isNonColliding)
return Body._nextNonCollidingGroupId--;
return Body._nextCollidingGroupId++;
};
Body.nextCategory = function() {
Body._nextCategory = Body._nextCategory << 1;
return Body._nextCategory;
};
var _initProperties = function(body, options) {
options = options || {};
Body.set(body, {
bounds: body.bounds || Bounds.create(body.vertices),
positionPrev: body.positionPrev || Vector.clone(body.position),
anglePrev: body.anglePrev || body.angle,
vertices: body.vertices,
parts: body.parts || [body],
isStatic: body.isStatic,
isSleeping: body.isSleeping,
parent: body.parent || body
});
Vertices.rotate(body.vertices, body.angle, body.position);
Axes.rotate(body.axes, body.angle);
Bounds.update(body.bounds, body.vertices, body.velocity);
Body.set(body, {
axes: options.axes || body.axes,
area: options.area || body.area,
mass: options.mass || body.mass,
inertia: options.inertia || body.inertia
});
if (body.parts.length === 1) {
var bounds = body.bounds;
var centerOfMass = body.centerOfMass;
var centerOffset = body.centerOffset;
var bodyWidth = bounds.max.x - bounds.min.x;
var bodyHeight = bounds.max.y - bounds.min.y;
centerOfMass.x = -(bounds.min.x - body.position.x) / bodyWidth;
centerOfMass.y = -(bounds.min.y - body.position.y) / bodyHeight;
centerOffset.x = bodyWidth * centerOfMass.x;
centerOffset.y = bodyHeight * centerOfMass.y;
}
};
Body.set = function(body, settings, value) {
var property;
if (typeof settings === "string") {
property = settings;
settings = {};
settings[property] = value;
}
for (property in settings) {
if (!Object.prototype.hasOwnProperty.call(settings, property))
continue;
value = settings[property];
switch (property) {
case "isStatic":
Body.setStatic(body, value);
break;
case "isSleeping":
Sleeping.set(body, value);
break;
case "mass":
Body.setMass(body, value);
break;
case "density":
Body.setDensity(body, value);
break;
case "inertia":
Body.setInertia(body, value);
break;
case "vertices":
Body.setVertices(body, value);
break;
case "position":
Body.setPosition(body, value);
break;
case "angle":
Body.setAngle(body, value);
break;
case "velocity":
Body.setVelocity(body, value);
break;
case "angularVelocity":
Body.setAngularVelocity(body, value);
break;
case "speed":
Body.setSpeed(body, value);
break;
case "angularSpeed":
Body.setAngularSpeed(body, value);
break;
case "parts":
Body.setParts(body, value);
break;
case "centre":
Body.setCentre(body, value);
break;
default:
body[property] = value;
}
}
};
Body.setStatic = function(body, isStatic) {
for (var i = 0; i < body.parts.length; i++) {
var part = body.parts[i];
if (isStatic) {
if (!part.isStatic) {
part._original = {
restitution: part.restitution,
friction: part.friction,
mass: part.mass,
inertia: part.inertia,
density: part.density,
inverseMass: part.inverseMass,
inverseInertia: part.inverseInertia
};
}
part.restitution = 0;
part.friction = 1;
part.mass = part.inertia = part.density = Infinity;
part.inverseMass = part.inverseInertia = 0;
part.positionPrev.x = part.position.x;
part.positionPrev.y = part.position.y;
part.anglePrev = part.angle;
part.angularVelocity = 0;
part.speed = 0;
part.angularSpeed = 0;
part.motion = 0;
} else if (part._original) {
part.restitution = part._original.restitution;
part.friction = part._original.friction;
part.mass = part._original.mass;
part.inertia = part._original.inertia;
part.density = part._original.density;
part.inverseMass = part._original.inverseMass;
part.inverseInertia = part._original.inverseInertia;
part._original = null;
}
part.isStatic = isStatic;
}
};
Body.setMass = function(body, mass) {
var moment = body.inertia / (body.mass / 6);
body.inertia = moment * (mass / 6);
body.inverseInertia = 1 / body.inertia;
body.mass = mass;
body.inverseMass = 1 / body.mass;
body.density = body.mass / body.area;
};
Body.setDensity = function(body, density) {
Body.setMass(body, density * body.area);
body.density = density;
};
Body.setInertia = function(body, inertia) {
body.inertia = inertia;
body.inverseInertia = 1 / body.inertia;
};
Body.setVertices = function(body, vertices) {
if (vertices[0].body === body) {
body.vertices = vertices;
} else {
body.vertices = Vertices.create(vertices, body);
}
body.axes = Axes.fromVertices(body.vertices);
body.area = Vertices.area(body.vertices);
Body.setMass(body, body.density * body.area);
var centre = Vertices.centre(body.vertices);
Vertices.translate(body.vertices, centre, -1);
Body.setInertia(body, Body._inertiaScale * Vertices.inertia(body.vertices, body.mass));
Vertices.translate(body.vertices, body.position);
Bounds.update(body.bounds, body.vertices, body.velocity);
};
Body.setParts = function(body, parts, autoHull) {
var i;
parts = parts.slice(0);
body.parts.length = 0;
body.parts.push(body);
body.parent = body;
for (i = 0; i < parts.length; i++) {
var part = parts[i];
if (part !== body) {
part.parent = body;
body.parts.push(part);
}
}
if (body.parts.length === 1)
return;
autoHull = typeof autoHull !== "undefined" ? autoHull : true;
if (autoHull) {
var vertices = [];
for (i = 0; i < parts.length; i++) {
vertices = vertices.concat(parts[i].vertices);
}
Vertices.clockwiseSort(vertices);
var hull = Vertices.hull(vertices), hullCentre = Vertices.centre(hull);
Body.setVertices(body, hull);
Vertices.translate(body.vertices, hullCentre);
}
var total = Body._totalProperties(body);
var cx = total.centre.x;
var cy = total.centre.y;
var bounds = body.bounds;
var centerOfMass = body.centerOfMass;
var centerOffset = body.centerOffset;
Bounds.update(bounds, body.vertices, body.velocity);
centerOfMass.x = -(bounds.min.x - cx) / (bounds.max.x - bounds.min.x);
centerOfMass.y = -(bounds.min.y - cy) / (bounds.max.y - bounds.min.y);
centerOffset.x = cx;
centerOffset.y = cy;
body.area = total.area;
body.parent = body;
body.position.x = cx;
body.position.y = cy;
body.positionPrev.x = cx;
body.positionPrev.y = cy;
Body.setMass(body, total.mass);
Body.setInertia(body, total.inertia);
Body.setPosition(body, total.centre);
};
Body.setCentre = function(body, centre, relative) {
if (!relative) {
body.positionPrev.x = centre.x - (body.position.x - body.positionPrev.x);
body.positionPrev.y = centre.y - (body.position.y - body.positionPrev.y);
body.position.x = centre.x;
body.position.y = centre.y;
} else {
body.positionPrev.x += centre.x;
body.positionPrev.y += centre.y;
body.position.x += centre.x;
body.position.y += centre.y;
}
};
Body.setPosition = function(body, position, updateVelocity) {
var delta = Vector.sub(position, body.position);
if (updateVelocity) {
body.positionPrev.x = body.position.x;
body.positionPrev.y = body.position.y;
body.velocity.x = delta.x;
body.velocity.y = delta.y;
body.speed = Vector.magnitude(delta);
} else {
body.positionPrev.x += delta.x;
body.positionPrev.y += delta.y;
}
for (var i = 0; i < body.parts.length; i++) {
var part = body.parts[i];
part.position.x += delta.x;
part.position.y += delta.y;
Vertices.translate(part.vertices, delta);
Bounds.update(part.bounds, part.vertices, body.velocity);
}
};
Body.setAngle = function(body, angle, updateVelocity) {
var delta = angle - body.angle;
if (updateVelocity) {
body.anglePrev = body.angle;
body.angularVelocity = delta;
body.angularSpeed = Math.abs(delta);
} else {
body.anglePrev += delta;
}
for (var i = 0; i < body.parts.length; i++) {
var part = body.parts[i];
part.angle += delta;
Vertices.rotate(part.vertices, delta, body.position);
Axes.rotate(part.axes, delta);
Bounds.update(part.bounds, part.vertices, body.velocity);
if (i > 0) {
Vector.rotateAbout(part.position, delta, body.position, part.position);
}
}
};
Body.setVelocity = function(body, velocity) {
var timeScale = body.deltaTime / Body._baseDelta;
body.positionPrev.x = body.position.x - velocity.x * timeScale;
body.positionPrev.y = body.position.y - velocity.y * timeScale;
body.velocity.x = (body.position.x - body.positionPrev.x) / timeScale;
body.velocity.y = (body.position.y - body.positionPrev.y) / timeScale;
body.speed = Vector.magnitude(body.velocity);
};
Body.getVelocity = function(body) {
var timeScale = Body._baseDelta / body.deltaTime;
return {
x: (body.position.x - body.positionPrev.x) * timeScale,
y: (body.position.y - body.positionPrev.y) * timeScale
};
};
Body.getSpeed = function(body) {
return Vector.magnitude(Body.getVelocity(body));
};
Body.setSpeed = function(body, speed) {
Body.setVelocity(body, Vector.mult(Vector.normalise(Body.getVelocity(body)), speed));
};
Body.setAngularVelocity = function(body, velocity) {
var timeScale = body.deltaTime / Body._baseDelta;
body.anglePrev = body.angle - velocity * timeScale;
body.angularVelocity = (body.angle - body.anglePrev) / timeScale;
body.angularSpeed = Math.abs(body.angularVelocity);
};
Body.getAngularVelocity = function(body) {
return (body.angle - body.anglePrev) * Body._baseDelta / body.deltaTime;
};
Body.getAngularSpeed = function(body) {
return Math.abs(Body.getAngularVelocity(body));
};
Body.setAngularSpeed = function(body, speed) {
Body.setAngularVelocity(body, Common.sign(Body.getAngularVelocity(body)) * speed);
};
Body.translate = function(body, translation, updateVelocity) {
Body.setPosition(body, Vector.add(body.position, translation), updateVelocity);
};
Body.rotate = function(body, rotation, point, updateVelocity) {
if (!point) {
Body.setAngle(body, body.angle + rotation, updateVelocity);
} else {
var cos = Math.cos(rotation), sin = Math.sin(rotation), dx = body.position.x - point.x, dy = body.position.y - point.y;
Body.setPosition(body, {
x: point.x + (dx * cos - dy * sin),
y: point.y + (dx * sin + dy * cos)
}, updateVelocity);
Body.setAngle(body, body.angle + rotation, updateVelocity);
}
};
Body.scale = function(body, scaleX, scaleY, point) {
var totalArea = 0, totalInertia = 0;
point = point || body.position;
var wasFixedRotation = body.inertia === Infinity ? true : false;
for (var i = 0; i < body.parts.length; i++) {
var part = body.parts[i];
part.scale.x = scaleX;
part.scale.y = scaleY;
Vertices.scale(part.vertices, scaleX, scaleY, point);
part.axes = Axes.fromVertices(part.vertices);
part.area = Vertices.area(part.vertices);
Body.setMass(part, body.density * part.area);
Vertices.translate(part.vertices, { x: -part.position.x, y: -part.position.y });
Body.setInertia(part, Body._inertiaScale * Vertices.inertia(part.vertices, part.mass));
Vertices.translate(part.vertices, { x: part.position.x, y: part.position.y });
if (i > 0) {
totalArea += part.area;
totalInertia += part.inertia;
}
part.position.x = point.x + (part.position.x - point.x) * scaleX;
part.position.y = point.y + (part.position.y - point.y) * scaleY;
Bounds.update(part.bounds, part.vertices, body.velocity);
}
if (body.parts.length > 1) {
body.area = totalArea;
if (!body.isStatic) {
Body.setMass(body, body.density * totalArea);
Body.setInertia(body, totalInertia);
}
}
if (body.circleRadius) {
if (scaleX === scaleY) {
body.circleRadius *= scaleX;
} else {
body.circleRadius = null;
}
}
if (wasFixedRotation) {
Body.setInertia(body, Infinity);
}
};
Body.update = function(body, deltaTime) {
deltaTime = (typeof deltaTime !== "undefined" ? deltaTime : 1e3 / 60) * body.timeScale;
var deltaTimeSquared = deltaTime * deltaTime, correction = Body._timeCorrection ? deltaTime / (body.deltaTime || deltaTime) : 1;
var frictionAir = 1 - body.frictionAir * (deltaTime / Common._baseDelta), velocityPrevX = (body.position.x - body.positionPrev.x) * correction, velocityPrevY = (body.position.y - body.positionPrev.y) * correction;
body.velocity.x = velocityPrevX * frictionAir + body.force.x / body.mass * deltaTimeSquared;
body.velocity.y = velocityPrevY * frictionAir + body.force.y / body.mass * deltaTimeSquared;
body.positionPrev.x = body.position.x;
body.positionPrev.y = body.position.y;
body.position.x += body.velocity.x;
body.position.y += body.velocity.y;
body.deltaTime = deltaTime;
body.angularVelocity = (body.angle - body.anglePrev) * frictionAir * correction + body.torque / body.inertia * deltaTimeSquared;
body.anglePrev = body.angle;
body.angle += body.angularVelocity;
body.speed = Vector.magnitude(body.velocity);
body.angularSpeed = Math.abs(body.angularVelocity);
for (var i = 0; i < body.parts.length; i++) {
var part = body.parts[i];
Vertices.translate(part.vertices, body.velocity);
if (i > 0) {
part.position.x += body.velocity.x;
part.position.y += body.velocity.y;
}
if (body.angularVelocity !== 0) {
Vertices.rotate(part.vertices, body.angularVelocity, body.position);
Axes.rotate(part.axes, body.angularVelocity);
if (i > 0) {
Vector.rotateAbout(part.position, body.angularVelocity, body.position, part.position);
}
}
Bounds.update(part.bounds, part.vertices, body.velocity);
}
};
Body.updateVelocities = function(body) {
var timeScale = Body._baseDelta / body.deltaTime, bodyVelocity = body.velocity;
bodyVelocity.x = (body.position.x - body.positionPrev.x) * timeScale;
bodyVelocity.y = (body.position.y - body.positionPrev.y) * timeScale;
body.speed = Math.sqrt(bodyVelocity.x * bodyVelocity.x + bodyVelocity.y * bodyVelocity.y);
body.angularVelocity = (body.angle - body.anglePrev) * timeScale;
body.angularSpeed = Math.abs(body.angularVelocity);
};
Body.applyForce = function(body, position, force) {
var offset = { x: position.x - body.position.x, y: position.y - body.position.y };
body.force.x += force.x;
body.force.y += force.y;
body.torque += offset.x * force.y - offset.y * force.x;
};
Body._totalProperties = function(body) {
var properties = {
mass: 0,
area: 0,
inertia: 0,
centre: { x: 0, y: 0 }
};
for (var i = body.parts.length === 1 ? 0 : 1; i < body.parts.length; i++) {
var part = body.parts[i], mass = part.mass !== Infinity ? part.mass : 1;
properties.mass += mass;
properties.area += part.area;
properties.inertia += part.inertia;
properties.centre = Vector.add(properties.centre, Vector.mult(part.position, mass));
}
properties.centre = Vector.div(properties.centre, properties.mass);
return properties;
};
Body.wrap = function(body, bounds) {
var translation = Bounds.wrap(body.bounds, bounds);
if (translation) {
Body.translate(body, translation);
}
return translation;
};
})();
}
),
/***/
69351: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Composite = {};
module2.exports = Composite;
var Events = __webpack_require__2(35810);
var Common = __webpack_require__2(53402);
var Bounds = __webpack_require__2(15647);
var Body = __webpack_require__2(22562);
(function() {
Composite.create = function(options) {
return Common.extend({
id: Common.nextId(),
type: "composite",
parent: null,
isModified: false,
bodies: [],
constraints: [],
composites: [],
label: "Composite",
plugin: {},
wrapBounds: null,
cache: {
allBodies: null,
allConstraints: null,
allComposites: null
}
}, options);
};
Composite.setModified = function(composite, isModified, updateParents, updateChildren) {
Events.trigger(composite, "compositeModified", composite);
composite.isModified = isModified;
if (isModified && composite.cache) {
composite.cache.allBodies = null;
composite.cache.allConstraints = null;
composite.cache.allComposites = null;
}
if (updateParents && composite.parent) {
Composite.setModified(composite.parent, isModified, updateParents, updateChildren);
}
if (updateChildren) {
for (var i = 0; i < composite.composites.length; i++) {
var childComposite = composite.composites[i];
Composite.setModified(childComposite, isModified, updateParents, updateChildren);
}
}
};
Composite.add = function(composite, object) {
var objects = [].concat(object);
Events.trigger(composite, "beforeAdd", { object });
for (var i = 0; i < objects.length; i++) {
var obj = objects[i];
switch (obj.type) {
case "body":
if (obj.parent !== obj) {
Common.warn("Composite.add: skipped adding a compound body part (you must add its parent instead)");
break;
}
Composite.addBody(composite, obj);
break;
case "constraint":
Composite.addConstraint(composite, obj);
break;
case "composite":
Composite.addComposite(composite, obj);
break;
case "mouseConstraint":
Composite.addConstraint(composite, obj.constraint);
break;
}
}
Events.trigger(composite, "afterAdd", { object });
return composite;
};
Composite.remove = function(composite, object, deep) {
var objects = [].concat(object);
Events.trigger(composite, "beforeRemove", { object });
for (var i = 0; i < objects.length; i++) {
var obj = objects[i];
switch (obj.type) {
case "body":
Composite.removeBody(composite, obj, deep);
break;
case "constraint":
Composite.removeConstraint(composite, obj, deep);
break;
case "composite":
Composite.removeComposite(composite, obj, deep);
break;
case "mouseConstraint":
Composite.removeConstraint(composite, obj.constraint);
break;
}
}
Events.trigger(composite, "afterRemove", { object });
return composite;
};
Composite.addComposite = function(compositeA, compositeB) {
compositeA.composites.push(compositeB);
compositeB.parent = compositeA;
Composite.setModified(compositeA, true, true, false);
return compositeA;
};
Composite.removeComposite = function(compositeA, compositeB, deep) {
var position = Common.indexOf(compositeA.composites, compositeB);
if (position !== -1) {
var bodies = Composite.allBodies(compositeB);
Composite.removeCompositeAt(compositeA, position);
for (var i = 0; i < bodies.length; i++) {
bodies[i].sleepCounter = 0;
}
}
if (deep) {
for (var i = 0; i < compositeA.composites.length; i++) {
Composite.removeComposite(compositeA.composites[i], compositeB, true);
}
}
return compositeA;
};
Composite.removeCompositeAt = function(composite, position) {
composite.composites.splice(position, 1);
Composite.setModified(composite, true, true, false);
return composite;
};
Composite.addBody = function(composite, body) {
composite.bodies.push(body);
Composite.setModified(composite, true, true, false);
return composite;
};
Composite.removeBody = function(composite, body, deep) {
var position = Common.indexOf(composite.bodies, body);
if (position !== -1) {
Composite.removeBodyAt(composite, position);
body.sleepCounter = 0;
}
if (deep) {
for (var i = 0; i < composite.composites.length; i++) {
Composite.removeBody(composite.composites[i], body, true);
}
}
return composite;
};
Composite.removeBodyAt = function(composite, position) {
composite.bodies.splice(position, 1);
Composite.setModified(composite, true, true, false);
return composite;
};
Composite.addConstraint = function(composite, constraint) {
composite.constraints.push(constraint);
Composite.setModified(composite, true, true, false);
return composite;
};
Composite.removeConstraint = function(composite, constraint, deep) {
var position = Common.indexOf(composite.constraints, constraint);
if (position !== -1) {
Composite.removeConstraintAt(composite, position);
}
if (deep) {
for (var i = 0; i < composite.composites.length; i++) {
Composite.removeConstraint(composite.composites[i], constraint, true);
}
}
return composite;
};
Composite.removeConstraintAt = function(composite, position) {
composite.constraints.splice(position, 1);
Composite.setModified(composite, true, true, false);
return composite;
};
Composite.clear = function(composite, keepStatic, deep) {
if (deep) {
for (var i = 0; i < composite.composites.length; i++) {
Composite.clear(composite.composites[i], keepStatic, true);
}
}
if (keepStatic) {
composite.bodies = composite.bodies.filter(function(body) {
return body.isStatic;
});
} else {
composite.bodies.length = 0;
}
composite.constraints.length = 0;
composite.composites.length = 0;
Composite.setModified(composite, true, true, false);
return composite;
};
Composite.allBodies = function(composite) {
if (composite.cache && composite.cache.allBodies) {
return composite.cache.allBodies;
}
var bodies = [].concat(composite.bodies);
for (var i = 0; i < composite.composites.length; i++)
bodies = bodies.concat(Composite.allBodies(composite.composites[i]));
if (composite.cache) {
composite.cache.allBodies = bodies;
}
return bodies;
};
Composite.allConstraints = function(composite) {
if (composite.cache && composite.cache.allConstraints) {
return composite.cache.allConstraints;
}
var constraints = [].concat(composite.constraints);
for (var i = 0; i < composite.composites.length; i++)
constraints = constraints.concat(Composite.allConstraints(composite.composites[i]));
if (composite.cache) {
composite.cache.allConstraints = constraints;
}
return constraints;
};
Composite.allComposites = function(composite) {
if (composite.cache && composite.cache.allComposites) {
return composite.cache.allComposites;
}
var composites = [].concat(composite.composites);
for (var i = 0; i < composite.composites.length; i++)
composites = composites.concat(Composite.allComposites(composite.composites[i]));
if (composite.cache) {
composite.cache.allComposites = composites;
}
return composites;
};
Composite.get = function(composite, id, type) {
var objects, object;
switch (type) {
case "body":
objects = Composite.allBodies(composite);
break;
case "constraint":
objects = Composite.allConstraints(composite);
break;
case "composite":
objects = Composite.allComposites(composite).concat(composite);
break;
}
if (!objects)
return null;
object = objects.filter(function(object2) {
return object2.id.toString() === id.toString();
});
return object.length === 0 ? null : object[0];
};
Composite.move = function(compositeA, objects, compositeB) {
Composite.remove(compositeA, objects);
Composite.add(compositeB, objects);
return compositeA;
};
Composite.rebase = function(composite) {
var objects = Composite.allBodies(composite).concat(Composite.allConstraints(composite)).concat(Composite.allComposites(composite));
for (var i = 0; i < objects.length; i++) {
objects[i].id = Common.nextId();
}
return composite;
};
Composite.translate = function(composite, translation, recursive) {
var bodies = recursive ? Composite.allBodies(composite) : composite.bodies;
for (var i = 0; i < bodies.length; i++) {
Body.translate(bodies[i], translation);
}
return composite;
};
Composite.rotate = function(composite, rotation, point, recursive) {
var cos = Math.cos(rotation), sin = Math.sin(rotation), bodies = recursive ? Composite.allBodies(composite) : composite.bodies;
for (var i = 0; i < bodies.length; i++) {
var body = bodies[i], dx = body.position.x - point.x, dy = body.position.y - point.y;
Body.setPosition(body, {
x: point.x + (dx * cos - dy * sin),
y: point.y + (dx * sin + dy * cos)
});
Body.rotate(body, rotation);
}
return composite;
};
Composite.scale = function(composite, scaleX, scaleY, point, recursive) {
var bodies = recursive ? Composite.allBodies(composite) : composite.bodies;
for (var i = 0; i < bodies.length; i++) {
var body = bodies[i], dx = body.position.x - point.x, dy = body.position.y - point.y;
Body.setPosition(body, {
x: point.x + dx * scaleX,
y: point.y + dy * scaleY
});
Body.scale(body, scaleX, scaleY);
}
return composite;
};
Composite.bounds = function(composite) {
var bodies = Composite.allBodies(composite), vertices = [];
for (var i = 0; i < bodies.length; i += 1) {
var body = bodies[i];
vertices.push(body.bounds.min, body.bounds.max);
}
return Bounds.create(vertices);
};
Composite.wrap = function(composite, bounds) {
var translation = Bounds.wrap(
Composite.bounds(composite),
bounds
);
if (translation) {
Composite.translate(composite, translation);
}
return translation;
};
})();
}
),
/***/
4372: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var World = {};
module2.exports = World;
var Composite = __webpack_require__2(69351);
(function() {
World.create = Composite.create;
World.add = Composite.add;
World.remove = Composite.remove;
World.clear = Composite.clear;
World.addComposite = Composite.addComposite;
World.addBody = Composite.addBody;
World.addConstraint = Composite.addConstraint;
})();
}
),
/***/
52284: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Collision = {};
module2.exports = Collision;
var Vertices = __webpack_require__2(41598);
var Pair = __webpack_require__2(4506);
(function() {
var _supports = [];
var _overlapAB = {
overlap: 0,
axis: null
};
var _overlapBA = {
overlap: 0,
axis: null
};
Collision.create = function(bodyA, bodyB) {
return {
pair: null,
collided: false,
bodyA,
bodyB,
parentA: bodyA.parent,
parentB: bodyB.parent,
depth: 0,
normal: { x: 0, y: 0 },
tangent: { x: 0, y: 0 },
penetration: { x: 0, y: 0 },
supports: [null, null],
supportCount: 0
};
};
Collision.collides = function(bodyA, bodyB, pairs) {
Collision._overlapAxes(_overlapAB, bodyA.vertices, bodyB.vertices, bodyA.axes);
if (_overlapAB.overlap <= 0) {
return null;
}
Collision._overlapAxes(_overlapBA, bodyB.vertices, bodyA.vertices, bodyB.axes);
if (_overlapBA.overlap <= 0) {
return null;
}
var pair = pairs && pairs.table[Pair.id(bodyA, bodyB)], collision;
if (!pair) {
collision = Collision.create(bodyA, bodyB);
collision.collided = true;
collision.bodyA = bodyA.id < bodyB.id ? bodyA : bodyB;
collision.bodyB = bodyA.id < bodyB.id ? bodyB : bodyA;
collision.parentA = collision.bodyA.parent;
collision.parentB = collision.bodyB.parent;
} else {
collision = pair.collision;
}
bodyA = collision.bodyA;
bodyB = collision.bodyB;
var minOverlap;
if (_overlapAB.overlap < _overlapBA.overlap) {
minOverlap = _overlapAB;
} else {
minOverlap = _overlapBA;
}
var normal = collision.normal, tangent = collision.tangent, penetration = collision.penetration, supports = collision.supports, depth = minOverlap.overlap, minAxis = minOverlap.axis, normalX = minAxis.x, normalY = minAxis.y, deltaX = bodyB.position.x - bodyA.position.x, deltaY = bodyB.position.y - bodyA.position.y;
if (normalX * deltaX + normalY * deltaY >= 0) {
normalX = -normalX;
normalY = -normalY;
}
normal.x = normalX;
normal.y = normalY;
tangent.x = -normalY;
tangent.y = normalX;
penetration.x = normalX * depth;
penetration.y = normalY * depth;
collision.depth = depth;
var supportsB = Collision._findSupports(bodyA, bodyB, normal, 1), supportCount = 0;
if (Vertices.contains(bodyA.vertices, supportsB[0])) {
supports[supportCount++] = supportsB[0];
}
if (Vertices.contains(bodyA.vertices, supportsB[1])) {
supports[supportCount++] = supportsB[1];
}
if (supportCount < 2) {
var supportsA = Collision._findSupports(bodyB, bodyA, normal, -1);
if (Vertices.contains(bodyB.vertices, supportsA[0])) {
supports[supportCount++] = supportsA[0];
}
if (supportCount < 2 && Vertices.contains(bodyB.vertices, supportsA[1])) {
supports[supportCount++] = supportsA[1];
}
}
if (supportCount === 0) {
supports[supportCount++] = supportsB[0];
}
collision.supportCount = supportCount;
return collision;
};
Collision._overlapAxes = function(result, verticesA, verticesB, axes) {
var verticesALength = verticesA.length, verticesBLength = verticesB.length, verticesAX = verticesA[0].x, verticesAY = verticesA[0].y, verticesBX = verticesB[0].x, verticesBY = verticesB[0].y, axesLength = axes.length, overlapMin = Number.MAX_VALUE, overlapAxisNumber = 0, overlap, overlapAB, overlapBA, dot, i, j;
for (i = 0; i < axesLength; i++) {
var axis = axes[i], axisX = axis.x, axisY = axis.y, minA = verticesAX * axisX + verticesAY * axisY, minB = verticesBX * axisX + verticesBY * axisY, maxA = minA, maxB = minB;
for (j = 1; j < verticesALength; j += 1) {
dot = verticesA[j].x * axisX + verticesA[j].y * axisY;
if (dot > maxA) {
maxA = dot;
} else if (dot < minA) {
minA = dot;
}
}
for (j = 1; j < verticesBLength; j += 1) {
dot = verticesB[j].x * axisX + verticesB[j].y * axisY;
if (dot > maxB) {
maxB = dot;
} else if (dot < minB) {
minB = dot;
}
}
overlapAB = maxA - minB;
overlapBA = maxB - minA;
overlap = overlapAB < overlapBA ? overlapAB : overlapBA;
if (overlap < overlapMin) {
overlapMin = overlap;
overlapAxisNumber = i;
if (overlap <= 0) {
break;
}
}
}
result.axis = axes[overlapAxisNumber];
result.overlap = overlapMin;
};
Collision._findSupports = function(bodyA, bodyB, normal, direction) {
var vertices = bodyB.vertices, verticesLength = vertices.length, bodyAPositionX = bodyA.position.x, bodyAPositionY = bodyA.position.y, normalX = normal.x * direction, normalY = normal.y * direction, vertexA = vertices[0], vertexB = vertexA, nearestDistance = normalX * (bodyAPositionX - vertexB.x) + normalY * (bodyAPositionY - vertexB.y), vertexC, distance, j;
for (j = 1; j < verticesLength; j += 1) {
vertexB = vertices[j];
distance = normalX * (bodyAPositionX - vertexB.x) + normalY * (bodyAPositionY - vertexB.y);
if (distance < nearestDistance) {
nearestDistance = distance;
vertexA = vertexB;
}
}
vertexC = vertices[(verticesLength + vertexA.index - 1) % verticesLength];
nearestDistance = normalX * (bodyAPositionX - vertexC.x) + normalY * (bodyAPositionY - vertexC.y);
vertexB = vertices[(vertexA.index + 1) % verticesLength];
if (normalX * (bodyAPositionX - vertexB.x) + normalY * (bodyAPositionY - vertexB.y) < nearestDistance) {
_supports[0] = vertexA;
_supports[1] = vertexB;
return _supports;
}
_supports[0] = vertexA;
_supports[1] = vertexC;
return _supports;
};
})();
}
),
/***/
43424: (
/***/
(module2) => {
var Contact = {};
module2.exports = Contact;
(function() {
Contact.create = function(vertex) {
return {
vertex,
normalImpulse: 0,
tangentImpulse: 0
};
};
})();
}
),
/***/
81388: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Detector = {};
module2.exports = Detector;
var Common = __webpack_require__2(53402);
var Collision = __webpack_require__2(52284);
(function() {
Detector.create = function(options) {
var defaults = {
bodies: [],
collisions: [],
pairs: null
};
return Common.extend(defaults, options);
};
Detector.setBodies = function(detector, bodies) {
detector.bodies = bodies.slice(0);
};
Detector.clear = function(detector) {
detector.bodies = [];
detector.collisions = [];
};
Detector.collisions = function(detector) {
var pairs = detector.pairs, bodies = detector.bodies, bodiesLength = bodies.length, canCollide = Detector.canCollide, collides = Collision.collides, collisions = detector.collisions, collisionIndex = 0, i, j;
bodies.sort(Detector._compareBoundsX);
for (i = 0; i < bodiesLength; i++) {
var bodyA = bodies[i], boundsA = bodyA.bounds, boundXMax = bodyA.bounds.max.x, boundYMax = bodyA.bounds.max.y, boundYMin = bodyA.bounds.min.y, bodyAStatic = bodyA.isStatic || bodyA.isSleeping, partsALength = bodyA.parts.length, partsASingle = partsALength === 1;
for (j = i + 1; j < bodiesLength; j++) {
var bodyB = bodies[j], boundsB = bodyB.bounds;
if (boundsB.min.x > boundXMax) {
break;
}
if (boundYMax < boundsB.min.y || boundYMin > boundsB.max.y) {
continue;
}
if (bodyAStatic && (bodyB.isStatic || bodyB.isSleeping)) {
continue;
}
if (!canCollide(bodyA.collisionFilter, bodyB.collisionFilter)) {
continue;
}
var partsBLength = bodyB.parts.length;
if (partsASingle && partsBLength === 1) {
var collision = collides(bodyA, bodyB, pairs);
if (collision) {
collisions[collisionIndex++] = collision;
}
} else {
var partsAStart = partsALength > 1 ? 1 : 0, partsBStart = partsBLength > 1 ? 1 : 0;
for (var k = partsAStart; k < partsALength; k++) {
var partA = bodyA.parts[k], boundsA = partA.bounds;
for (var z = partsBStart; z < partsBLength; z++) {
var partB = bodyB.parts[z], boundsB = partB.bounds;
if (boundsA.min.x > boundsB.max.x || boundsA.max.x < boundsB.min.x || boundsA.max.y < boundsB.min.y || boundsA.min.y > boundsB.max.y) {
continue;
}
var collision = collides(partA, partB, pairs);
if (collision) {
collisions[collisionIndex++] = collision;
}
}
}
}
}
}
if (collisions.length !== collisionIndex) {
collisions.length = collisionIndex;
}
return collisions;
};
Detector.canCollide = function(filterA, filterB) {
if (filterA.group === filterB.group && filterA.group !== 0)
return filterA.group > 0;
return (filterA.mask & filterB.category) !== 0 && (filterB.mask & filterA.category) !== 0;
};
Detector._compareBoundsX = function(bodyA, bodyB) {
return bodyA.bounds.min.x - bodyB.bounds.min.x;
};
})();
}
),
/***/
4506: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Pair = {};
module2.exports = Pair;
var Contact = __webpack_require__2(43424);
(function() {
Pair.create = function(collision, timestamp) {
var bodyA = collision.bodyA, bodyB = collision.bodyB;
var pair = {
id: Pair.id(bodyA, bodyB),
bodyA,
bodyB,
collision,
contacts: [Contact.create(), Contact.create()],
contactCount: 0,
separation: 0,
isActive: true,
isSensor: bodyA.isSensor || bodyB.isSensor,
timeCreated: timestamp,
timeUpdated: timestamp,
inverseMass: 0,
friction: 0,
frictionStatic: 0,
restitution: 0,
slop: 0
};
Pair.update(pair, collision, timestamp);
return pair;
};
Pair.update = function(pair, collision, timestamp) {
var supports = collision.supports, supportCount = collision.supportCount, contacts = pair.contacts, parentA = collision.parentA, parentB = collision.parentB;
pair.isActive = true;
pair.timeUpdated = timestamp;
pair.collision = collision;
pair.separation = collision.depth;
pair.inverseMass = parentA.inverseMass + parentB.inverseMass;
pair.friction = parentA.friction < parentB.friction ? parentA.friction : parentB.friction;
pair.frictionStatic = parentA.frictionStatic > parentB.frictionStatic ? parentA.frictionStatic : parentB.frictionStatic;
pair.restitution = parentA.restitution > parentB.restitution ? parentA.restitution : parentB.restitution;
pair.slop = parentA.slop > parentB.slop ? parentA.slop : parentB.slop;
pair.contactCount = supportCount;
collision.pair = pair;
var supportA = supports[0], contactA = contacts[0], supportB = supports[1], contactB = contacts[1];
if (contactB.vertex === supportA || contactA.vertex === supportB) {
contacts[1] = contactA;
contacts[0] = contactA = contactB;
contactB = contacts[1];
}
contactA.vertex = supportA;
contactB.vertex = supportB;
};
Pair.setActive = function(pair, isActive, timestamp) {
if (isActive) {
pair.isActive = true;
pair.timeUpdated = timestamp;
} else {
pair.isActive = false;
pair.contactCount = 0;
}
};
Pair.id = function(bodyA, bodyB) {
return bodyA.id < bodyB.id ? bodyA.id.toString(36) + ":" + bodyB.id.toString(36) : bodyB.id.toString(36) + ":" + bodyA.id.toString(36);
};
})();
}
),
/***/
99561: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Pairs = {};
module2.exports = Pairs;
var Pair = __webpack_require__2(4506);
var Common = __webpack_require__2(53402);
(function() {
Pairs.create = function(options) {
return Common.extend({
table: {},
list: [],
collisionStart: [],
collisionActive: [],
collisionEnd: []
}, options);
};
Pairs.update = function(pairs, collisions, timestamp) {
var pairUpdate = Pair.update, pairCreate = Pair.create, pairSetActive = Pair.setActive, pairsTable = pairs.table, pairsList = pairs.list, pairsListLength = pairsList.length, pairsListIndex = pairsListLength, collisionStart = pairs.collisionStart, collisionEnd = pairs.collisionEnd, collisionActive = pairs.collisionActive, collisionsLength = collisions.length, collisionStartIndex = 0, collisionEndIndex = 0, collisionActiveIndex = 0, collision, pair, i;
for (i = 0; i < collisionsLength; i++) {
collision = collisions[i];
pair = collision.pair;
if (pair) {
if (pair.isActive) {
collisionActive[collisionActiveIndex++] = pair;
}
pairUpdate(pair, collision, timestamp);
} else {
pair = pairCreate(collision, timestamp);
pairsTable[pair.id] = pair;
collisionStart[collisionStartIndex++] = pair;
pairsList[pairsListIndex++] = pair;
}
}
pairsListIndex = 0;
pairsListLength = pairsList.length;
for (i = 0; i < pairsListLength; i++) {
pair = pairsList[i];
if (pair.timeUpdated >= timestamp) {
pairsList[pairsListIndex++] = pair;
} else {
pairSetActive(pair, false, timestamp);
if (pair.collision.bodyA.sleepCounter > 0 && pair.collision.bodyB.sleepCounter > 0) {
pairsList[pairsListIndex++] = pair;
} else {
collisionEnd[collisionEndIndex++] = pair;
delete pairsTable[pair.id];
}
}
}
if (pairsList.length !== pairsListIndex) {
pairsList.length = pairsListIndex;
}
if (collisionStart.length !== collisionStartIndex) {
collisionStart.length = collisionStartIndex;
}
if (collisionEnd.length !== collisionEndIndex) {
collisionEnd.length = collisionEndIndex;
}
if (collisionActive.length !== collisionActiveIndex) {
collisionActive.length = collisionActiveIndex;
}
};
Pairs.clear = function(pairs) {
pairs.table = {};
pairs.list.length = 0;
pairs.collisionStart.length = 0;
pairs.collisionActive.length = 0;
pairs.collisionEnd.length = 0;
return pairs;
};
})();
}
),
/***/
73296: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Query = {};
module2.exports = Query;
var Vector = __webpack_require__2(31725);
var Collision = __webpack_require__2(52284);
var Bounds = __webpack_require__2(15647);
var Bodies = __webpack_require__2(66280);
var Vertices = __webpack_require__2(41598);
(function() {
Query.collides = function(body, bodies) {
var collisions = [], bodiesLength = bodies.length, bounds = body.bounds, collides = Collision.collides, overlaps = Bounds.overlaps;
for (var i = 0; i < bodiesLength; i++) {
var bodyA = bodies[i], partsALength = bodyA.parts.length, partsAStart = partsALength === 1 ? 0 : 1;
if (body === bodyA) {
continue;
}
if (overlaps(bodyA.bounds, bounds)) {
for (var j = partsAStart; j < partsALength; j++) {
var part = bodyA.parts[j];
if (overlaps(part.bounds, bounds)) {
var collision = collides(part, body);
if (collision) {
collisions.push(collision);
break;
}
}
}
}
}
return collisions;
};
Query.ray = function(bodies, startPoint, endPoint, rayWidth) {
rayWidth = rayWidth || 1e-100;
var rayAngle = Vector.angle(startPoint, endPoint), rayLength = Vector.magnitude(Vector.sub(startPoint, endPoint)), rayX = (endPoint.x + startPoint.x) * 0.5, rayY = (endPoint.y + startPoint.y) * 0.5, ray = Bodies.rectangle(rayX, rayY, rayLength, rayWidth, { angle: rayAngle }), collisions = Query.collides(ray, bodies);
for (var i = 0; i < collisions.length; i += 1) {
var collision = collisions[i];
collision.body = collision.bodyB = collision.bodyA;
}
return collisions;
};
Query.region = function(bodies, bounds, outside) {
var result = [];
for (var i = 0; i < bodies.length; i++) {
var body = bodies[i], overlaps = Bounds.overlaps(body.bounds, bounds);
if (overlaps && !outside || !overlaps && outside)
result.push(body);
}
return result;
};
Query.point = function(bodies, point) {
var result = [];
for (var i = 0; i < bodies.length; i++) {
var body = bodies[i];
if (Bounds.contains(body.bounds, point)) {
for (var j = body.parts.length === 1 ? 0 : 1; j < body.parts.length; j++) {
var part = body.parts[j];
if (Bounds.contains(part.bounds, point) && Vertices.contains(part.vertices, point)) {
result.push(body);
break;
}
}
}
}
return result;
};
})();
}
),
/***/
66272: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Resolver = {};
module2.exports = Resolver;
var Vertices = __webpack_require__2(41598);
var Common = __webpack_require__2(53402);
var Bounds = __webpack_require__2(15647);
(function() {
Resolver._restingThresh = 2;
Resolver._restingThreshTangent = Math.sqrt(6);
Resolver._positionDampen = 0.9;
Resolver._positionWarming = 0.8;
Resolver._frictionNormalMultiplier = 5;
Resolver._frictionMaxStatic = Number.MAX_VALUE;
Resolver.preSolvePosition = function(pairs) {
var i, pair, contactCount, pairsLength = pairs.length;
for (i = 0; i < pairsLength; i++) {
pair = pairs[i];
if (!pair.isActive)
continue;
contactCount = pair.contactCount;
pair.collision.parentA.totalContacts += contactCount;
pair.collision.parentB.totalContacts += contactCount;
}
};
Resolver.solvePosition = function(pairs, delta, damping) {
var i, pair, collision, bodyA, bodyB, normal, contactShare, positionImpulse, positionDampen = Resolver._positionDampen * (damping || 1), slopDampen = Common.clamp(delta / Common._baseDelta, 0, 1), pairsLength = pairs.length;
for (i = 0; i < pairsLength; i++) {
pair = pairs[i];
if (!pair.isActive || pair.isSensor)
continue;
collision = pair.collision;
bodyA = collision.parentA;
bodyB = collision.parentB;
normal = collision.normal;
pair.separation = collision.depth + normal.x * (bodyB.positionImpulse.x - bodyA.positionImpulse.x) + normal.y * (bodyB.positionImpulse.y - bodyA.positionImpulse.y);
}
for (i = 0; i < pairsLength; i++) {
pair = pairs[i];
if (!pair.isActive || pair.isSensor)
continue;
collision = pair.collision;
bodyA = collision.parentA;
bodyB = collision.parentB;
normal = collision.normal;
positionImpulse = pair.separation - pair.slop * slopDampen;
if (bodyA.isStatic || bodyB.isStatic)
positionImpulse *= 2;
if (!(bodyA.isStatic || bodyA.isSleeping)) {
contactShare = positionDampen / bodyA.totalContacts;
bodyA.positionImpulse.x += normal.x * positionImpulse * contactShare;
bodyA.positionImpulse.y += normal.y * positionImpulse * contactShare;
}
if (!(bodyB.isStatic || bodyB.isSleeping)) {
contactShare = positionDampen / bodyB.totalContacts;
bodyB.positionImpulse.x -= normal.x * positionImpulse * contactShare;
bodyB.positionImpulse.y -= normal.y * positionImpulse * contactShare;
}
}
};
Resolver.postSolvePosition = function(bodies) {
var positionWarming = Resolver._positionWarming, bodiesLength = bodies.length, verticesTranslate = Vertices.translate, boundsUpdate = Bounds.update;
for (var i = 0; i < bodiesLength; i++) {
var body = bodies[i], positionImpulse = body.positionImpulse, positionImpulseX = positionImpulse.x, positionImpulseY = positionImpulse.y, velocity = body.velocity;
body.totalContacts = 0;
if (positionImpulseX !== 0 || positionImpulseY !== 0) {
for (var j = 0; j < body.parts.length; j++) {
var part = body.parts[j];
verticesTranslate(part.vertices, positionImpulse);
boundsUpdate(part.bounds, part.vertices, velocity);
part.position.x += positionImpulseX;
part.position.y += positionImpulseY;
}
body.positionPrev.x += positionImpulseX;
body.positionPrev.y += positionImpulseY;
if (positionImpulseX * velocity.x + positionImpulseY * velocity.y < 0) {
positionImpulse.x = 0;
positionImpulse.y = 0;
} else {
positionImpulse.x *= positionWarming;
positionImpulse.y *= positionWarming;
}
}
}
};
Resolver.preSolveVelocity = function(pairs) {
var pairsLength = pairs.length, i, j;
for (i = 0; i < pairsLength; i++) {
var pair = pairs[i];
if (!pair.isActive || pair.isSensor)
continue;
var contacts = pair.contacts, contactCount = pair.contactCount, collision = pair.collision, bodyA = collision.parentA, bodyB = collision.parentB, normal = collision.normal, tangent = collision.tangent;
for (j = 0; j < contactCount; j++) {
var contact = contacts[j], contactVertex = contact.vertex, normalImpulse = contact.normalImpulse, tangentImpulse = contact.tangentImpulse;
if (normalImpulse !== 0 || tangentImpulse !== 0) {
var impulseX = normal.x * normalImpulse + tangent.x * tangentImpulse, impulseY = normal.y * normalImpulse + tangent.y * tangentImpulse;
if (!(bodyA.isStatic || bodyA.isSleeping)) {
bodyA.positionPrev.x += impulseX * bodyA.inverseMass;
bodyA.positionPrev.y += impulseY * bodyA.inverseMass;
bodyA.anglePrev += bodyA.inverseInertia * ((contactVertex.x - bodyA.position.x) * impulseY - (contactVertex.y - bodyA.position.y) * impulseX);
}
if (!(bodyB.isStatic || bodyB.isSleeping)) {
bodyB.positionPrev.x -= impulseX * bodyB.inverseMass;
bodyB.positionPrev.y -= impulseY * bodyB.inverseMass;
bodyB.anglePrev -= bodyB.inverseInertia * ((contactVertex.x - bodyB.position.x) * impulseY - (contactVertex.y - bodyB.position.y) * impulseX);
}
}
}
}
};
Resolver.solveVelocity = function(pairs, delta) {
var timeScale = delta / Common._baseDelta, timeScaleSquared = timeScale * timeScale, timeScaleCubed = timeScaleSquared * timeScale, restingThresh = -Resolver._restingThresh * timeScale, restingThreshTangent = Resolver._restingThreshTangent, frictionNormalMultiplier = Resolver._frictionNormalMultiplier * timeScale, frictionMaxStatic = Resolver._frictionMaxStatic, pairsLength = pairs.length, tangentImpulse, maxFriction, i, j;
for (i = 0; i < pairsLength; i++) {
var pair = pairs[i];
if (!pair.isActive || pair.isSensor)
continue;
var collision = pair.collision, bodyA = collision.parentA, bodyB = collision.parentB, normalX = collision.normal.x, normalY = collision.normal.y, tangentX = collision.tangent.x, tangentY = collision.tangent.y, inverseMassTotal = pair.inverseMass, friction = pair.friction * pair.frictionStatic * frictionNormalMultiplier, contacts = pair.contacts, contactCount = pair.contactCount, contactShare = 1 / contactCount;
var bodyAVelocityX = bodyA.position.x - bodyA.positionPrev.x, bodyAVelocityY = bodyA.position.y - bodyA.positionPrev.y, bodyAAngularVelocity = bodyA.angle - bodyA.anglePrev, bodyBVelocityX = bodyB.position.x - bodyB.positionPrev.x, bodyBVelocityY = bodyB.position.y - bodyB.positionPrev.y, bodyBAngularVelocity = bodyB.angle - bodyB.anglePrev;
for (j = 0; j < contactCount; j++) {
var contact = contacts[j], contactVertex = contact.vertex;
var offsetAX = contactVertex.x - bodyA.position.x, offsetAY = contactVertex.y - bodyA.position.y, offsetBX = contactVertex.x - bodyB.position.x, offsetBY = contactVertex.y - bodyB.position.y;
var velocityPointAX = bodyAVelocityX - offsetAY * bodyAAngularVelocity, velocityPointAY = bodyAVelocityY + offsetAX * bodyAAngularVelocity, velocityPointBX = bodyBVelocityX - offsetBY * bodyBAngularVelocity, velocityPointBY = bodyBVelocityY + offsetBX * bodyBAngularVelocity;
var relativeVelocityX = velocityPointAX - velocityPointBX, relativeVelocityY = velocityPointAY - velocityPointBY;
var normalVelocity = normalX * relativeVelocityX + normalY * relativeVelocityY, tangentVelocity = tangentX * relativeVelocityX + tangentY * relativeVelocityY;
var normalOverlap = pair.separation + normalVelocity;
var normalForce = Math.min(normalOverlap, 1);
normalForce = normalOverlap < 0 ? 0 : normalForce;
var frictionLimit = normalForce * friction;
if (tangentVelocity < -frictionLimit || tangentVelocity > frictionLimit) {
maxFriction = tangentVelocity > 0 ? tangentVelocity : -tangentVelocity;
tangentImpulse = pair.friction * (tangentVelocity > 0 ? 1 : -1) * timeScaleCubed;
if (tangentImpulse < -maxFriction) {
tangentImpulse = -maxFriction;
} else if (tangentImpulse > maxFriction) {
tangentImpulse = maxFriction;
}
} else {
tangentImpulse = tangentVelocity;
maxFriction = frictionMaxStatic;
}
var oAcN = offsetAX * normalY - offsetAY * normalX, oBcN = offsetBX * normalY - offsetBY * normalX, share = contactShare / (inverseMassTotal + bodyA.inverseInertia * oAcN * oAcN + bodyB.inverseInertia * oBcN * oBcN);
var normalImpulse = (1 + pair.restitution) * normalVelocity * share;
tangentImpulse *= share;
if (normalVelocity < restingThresh) {
contact.normalImpulse = 0;
} else {
var contactNormalImpulse = contact.normalImpulse;
contact.normalImpulse += normalImpulse;
if (contact.normalImpulse > 0) contact.normalImpulse = 0;
normalImpulse = contact.normalImpulse - contactNormalImpulse;
}
if (tangentVelocity < -restingThreshTangent || tangentVelocity > restingThreshTangent) {
contact.tangentImpulse = 0;
} else {
var contactTangentImpulse = contact.tangentImpulse;
contact.tangentImpulse += tangentImpulse;
if (contact.tangentImpulse < -maxFriction) contact.tangentImpulse = -maxFriction;
if (contact.tangentImpulse > maxFriction) contact.tangentImpulse = maxFriction;
tangentImpulse = contact.tangentImpulse - contactTangentImpulse;
}
var impulseX = normalX * normalImpulse + tangentX * tangentImpulse, impulseY = normalY * normalImpulse + tangentY * tangentImpulse;
if (!(bodyA.isStatic || bodyA.isSleeping)) {
bodyA.positionPrev.x += impulseX * bodyA.inverseMass;
bodyA.positionPrev.y += impulseY * bodyA.inverseMass;
bodyA.anglePrev += (offsetAX * impulseY - offsetAY * impulseX) * bodyA.inverseInertia;
}
if (!(bodyB.isStatic || bodyB.isSleeping)) {
bodyB.positionPrev.x -= impulseX * bodyB.inverseMass;
bodyB.positionPrev.y -= impulseY * bodyB.inverseMass;
bodyB.anglePrev -= (offsetBX * impulseY - offsetBY * impulseX) * bodyB.inverseInertia;
}
}
}
};
})();
}
),
/***/
48140: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Constraint = {};
module2.exports = Constraint;
var Vertices = __webpack_require__2(41598);
var Vector = __webpack_require__2(31725);
var Sleeping = __webpack_require__2(53614);
var Bounds = __webpack_require__2(15647);
var Axes = __webpack_require__2(66615);
var Common = __webpack_require__2(53402);
(function() {
Constraint._warming = 0.4;
Constraint._torqueDampen = 1;
Constraint._minLength = 1e-6;
Constraint.create = function(options) {
var constraint = options;
if (constraint.bodyA && !constraint.pointA)
constraint.pointA = { x: 0, y: 0 };
if (constraint.bodyB && !constraint.pointB)
constraint.pointB = { x: 0, y: 0 };
var initialPointA = constraint.bodyA ? Vector.add(constraint.bodyA.position, constraint.pointA) : constraint.pointA, initialPointB = constraint.bodyB ? Vector.add(constraint.bodyB.position, constraint.pointB) : constraint.pointB, length = Vector.magnitude(Vector.sub(initialPointA, initialPointB));
constraint.length = typeof constraint.length !== "undefined" ? constraint.length : length;
constraint.id = constraint.id || Common.nextId();
constraint.label = constraint.label || "Constraint";
constraint.type = "constraint";
constraint.stiffness = constraint.stiffness || (constraint.length > 0 ? 1 : 0.7);
constraint.damping = constraint.damping || 0;
constraint.angularStiffness = constraint.angularStiffness || 0;
constraint.angleA = constraint.bodyA ? constraint.bodyA.angle : constraint.angleA;
constraint.angleB = constraint.bodyB ? constraint.bodyB.angle : constraint.angleB;
constraint.plugin = {};
var render = {
visible: true,
type: "line",
anchors: true,
lineColor: null,
// custom Phaser property
lineOpacity: null,
// custom Phaser property
lineThickness: null,
// custom Phaser property
pinSize: null,
// custom Phaser property
anchorColor: null,
// custom Phaser property
anchorSize: null
// custom Phaser property
};
if (constraint.length === 0 && constraint.stiffness > 0.1) {
render.type = "pin";
render.anchors = false;
} else if (constraint.stiffness < 0.9) {
render.type = "spring";
}
constraint.render = Common.extend(render, constraint.render);
return constraint;
};
Constraint.preSolveAll = function(bodies) {
for (var i = 0; i < bodies.length; i += 1) {
var body = bodies[i], impulse = body.constraintImpulse;
if (body.isStatic || impulse.x === 0 && impulse.y === 0 && impulse.angle === 0) {
continue;
}
body.position.x += impulse.x;
body.position.y += impulse.y;
body.angle += impulse.angle;
}
};
Constraint.solveAll = function(constraints, delta) {
var timeScale = Common.clamp(delta / Common._baseDelta, 0, 1);
for (var i = 0; i < constraints.length; i += 1) {
var constraint = constraints[i], fixedA = !constraint.bodyA || constraint.bodyA && constraint.bodyA.isStatic, fixedB = !constraint.bodyB || constraint.bodyB && constraint.bodyB.isStatic;
if (fixedA || fixedB) {
Constraint.solve(constraints[i], timeScale);
}
}
for (i = 0; i < constraints.length; i += 1) {
constraint = constraints[i];
fixedA = !constraint.bodyA || constraint.bodyA && constraint.bodyA.isStatic;
fixedB = !constraint.bodyB || constraint.bodyB && constraint.bodyB.isStatic;
if (!fixedA && !fixedB) {
Constraint.solve(constraints[i], timeScale);
}
}
};
Constraint.solve = function(constraint, timeScale) {
var bodyA = constraint.bodyA, bodyB = constraint.bodyB, pointA = constraint.pointA, pointB = constraint.pointB;
if (!bodyA && !bodyB)
return;
if (bodyA && !bodyA.isStatic) {
Vector.rotate(pointA, bodyA.angle - constraint.angleA, pointA);
constraint.angleA = bodyA.angle;
}
if (bodyB && !bodyB.isStatic) {
Vector.rotate(pointB, bodyB.angle - constraint.angleB, pointB);
constraint.angleB = bodyB.angle;
}
var pointAWorld = pointA, pointBWorld = pointB;
if (bodyA) pointAWorld = Vector.add(bodyA.position, pointA);
if (bodyB) pointBWorld = Vector.add(bodyB.position, pointB);
if (!pointAWorld || !pointBWorld)
return;
var delta = Vector.sub(pointAWorld, pointBWorld), currentLength = Vector.magnitude(delta);
if (currentLength < Constraint._minLength) {
currentLength = Constraint._minLength;
}
var difference = (currentLength - constraint.length) / currentLength, isRigid = constraint.stiffness >= 1 || constraint.length === 0, stiffness = isRigid ? constraint.stiffness * timeScale : constraint.stiffness * timeScale * timeScale, damping = constraint.damping * timeScale, force = Vector.mult(delta, difference * stiffness), massTotal = (bodyA ? bodyA.inverseMass : 0) + (bodyB ? bodyB.inverseMass : 0), inertiaTotal = (bodyA ? bodyA.inverseInertia : 0) + (bodyB ? bodyB.inverseInertia : 0), resistanceTotal = massTotal + inertiaTotal, torque, share, normal, normalVelocity, relativeVelocity;
if (damping > 0) {
var zero = Vector.create();
normal = Vector.div(delta, currentLength);
relativeVelocity = Vector.sub(
bodyB && Vector.sub(bodyB.position, bodyB.positionPrev) || zero,
bodyA && Vector.sub(bodyA.position, bodyA.positionPrev) || zero
);
normalVelocity = Vector.dot(normal, relativeVelocity);
}
if (bodyA && !bodyA.isStatic) {
share = bodyA.inverseMass / massTotal;
bodyA.constraintImpulse.x -= force.x * share;
bodyA.constraintImpulse.y -= force.y * share;
bodyA.position.x -= force.x * share;
bodyA.position.y -= force.y * share;
if (damping > 0) {
bodyA.positionPrev.x -= damping * normal.x * normalVelocity * share;
bodyA.positionPrev.y -= damping * normal.y * normalVelocity * share;
}
torque = Vector.cross(pointA, force) / resistanceTotal * Constraint._torqueDampen * bodyA.inverseInertia * (1 - constraint.angularStiffness);
bodyA.constraintImpulse.angle -= torque;
bodyA.angle -= torque;
}
if (bodyB && !bodyB.isStatic) {
share = bodyB.inverseMass / massTotal;
bodyB.constraintImpulse.x += force.x * share;
bodyB.constraintImpulse.y += force.y * share;
bodyB.position.x += force.x * share;
bodyB.position.y += force.y * share;
if (damping > 0) {
bodyB.positionPrev.x += damping * normal.x * normalVelocity * share;
bodyB.positionPrev.y += damping * normal.y * normalVelocity * share;
}
torque = Vector.cross(pointB, force) / resistanceTotal * Constraint._torqueDampen * bodyB.inverseInertia * (1 - constraint.angularStiffness);
bodyB.constraintImpulse.angle += torque;
bodyB.angle += torque;
}
};
Constraint.postSolveAll = function(bodies) {
for (var i = 0; i < bodies.length; i++) {
var body = bodies[i], impulse = body.constraintImpulse;
if (body.isStatic || impulse.x === 0 && impulse.y === 0 && impulse.angle === 0) {
continue;
}
Sleeping.set(body, false);
for (var j = 0; j < body.parts.length; j++) {
var part = body.parts[j];
Vertices.translate(part.vertices, impulse);
if (j > 0) {
part.position.x += impulse.x;
part.position.y += impulse.y;
}
if (impulse.angle !== 0) {
Vertices.rotate(part.vertices, impulse.angle, body.position);
Axes.rotate(part.axes, impulse.angle);
if (j > 0) {
Vector.rotateAbout(part.position, impulse.angle, body.position, part.position);
}
}
Bounds.update(part.bounds, part.vertices, body.velocity);
}
impulse.angle *= Constraint._warming;
impulse.x *= Constraint._warming;
impulse.y *= Constraint._warming;
}
};
Constraint.pointAWorld = function(constraint) {
return {
x: (constraint.bodyA ? constraint.bodyA.position.x : 0) + (constraint.pointA ? constraint.pointA.x : 0),
y: (constraint.bodyA ? constraint.bodyA.position.y : 0) + (constraint.pointA ? constraint.pointA.y : 0)
};
};
Constraint.pointBWorld = function(constraint) {
return {
x: (constraint.bodyB ? constraint.bodyB.position.x : 0) + (constraint.pointB ? constraint.pointB.x : 0),
y: (constraint.bodyB ? constraint.bodyB.position.y : 0) + (constraint.pointB ? constraint.pointB.y : 0)
};
};
Constraint.currentLength = function(constraint) {
var pointAX = (constraint.bodyA ? constraint.bodyA.position.x : 0) + (constraint.pointA ? constraint.pointA.x : 0);
var pointAY = (constraint.bodyA ? constraint.bodyA.position.y : 0) + (constraint.pointA ? constraint.pointA.y : 0);
var pointBX = (constraint.bodyB ? constraint.bodyB.position.x : 0) + (constraint.pointB ? constraint.pointB.x : 0);
var pointBY = (constraint.bodyB ? constraint.bodyB.position.y : 0) + (constraint.pointB ? constraint.pointB.y : 0);
var deltaX = pointAX - pointBX;
var deltaY = pointAY - pointBY;
return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
};
})();
}
),
/***/
53402: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Common = {};
module2.exports = Common;
(function() {
Common._baseDelta = 1e3 / 60;
Common._nextId = 0;
Common._seed = 0;
Common._nowStartTime = +/* @__PURE__ */ new Date();
Common._warnedOnce = {};
Common._decomp = null;
Common.extend = function(obj, deep) {
var argsStart, args, deepClone;
if (typeof deep === "boolean") {
argsStart = 2;
deepClone = deep;
} else {
argsStart = 1;
deepClone = true;
}
for (var i = argsStart; i < arguments.length; i++) {
var source = arguments[i];
if (source) {
for (var prop in source) {
if (deepClone && source[prop] && source[prop].constructor === Object) {
if (!obj[prop] || obj[prop].constructor === Object) {
obj[prop] = obj[prop] || {};
Common.extend(obj[prop], deepClone, source[prop]);
} else {
obj[prop] = source[prop];
}
} else {
obj[prop] = source[prop];
}
}
}
}
return obj;
};
Common.clone = function(obj, deep) {
return Common.extend({}, deep, obj);
};
Common.keys = function(obj) {
if (Object.keys)
return Object.keys(obj);
var keys = [];
for (var key in obj)
keys.push(key);
return keys;
};
Common.values = function(obj) {
var values = [];
if (Object.keys) {
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; i++) {
values.push(obj[keys[i]]);
}
return values;
}
for (var key in obj)
values.push(obj[key]);
return values;
};
Common.get = function(obj, path, begin, end) {
path = path.split(".").slice(begin, end);
for (var i = 0; i < path.length; i += 1) {
obj = obj[path[i]];
}
return obj;
};
Common.set = function(obj, path, val, begin, end) {
var parts = path.split(".").slice(begin, end);
Common.get(obj, path, 0, -1)[parts[parts.length - 1]] = val;
return val;
};
Common.shuffle = function(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Common.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
};
Common.choose = function(choices) {
return choices[Math.floor(Common.random() * choices.length)];
};
Common.isElement = function(obj) {
if (typeof HTMLElement !== "undefined") {
return obj instanceof HTMLElement;
}
return !!(obj && obj.nodeType && obj.nodeName);
};
Common.isArray = function(obj) {
return Object.prototype.toString.call(obj) === "[object Array]";
};
Common.isFunction = function(obj) {
return typeof obj === "function";
};
Common.isPlainObject = function(obj) {
return typeof obj === "object" && obj.constructor === Object;
};
Common.isString = function(obj) {
return toString.call(obj) === "[object String]";
};
Common.clamp = function(value, min, max) {
if (value < min)
return min;
if (value > max)
return max;
return value;
};
Common.sign = function(value) {
return value < 0 ? -1 : 1;
};
Common.now = function() {
if (typeof window !== "undefined" && window.performance) {
if (window.performance.now) {
return window.performance.now();
} else if (window.performance.webkitNow) {
return window.performance.webkitNow();
}
}
if (Date.now) {
return Date.now();
}
return /* @__PURE__ */ new Date() - Common._nowStartTime;
};
Common.random = function(min, max) {
min = typeof min !== "undefined" ? min : 0;
max = typeof max !== "undefined" ? max : 1;
return min + _seededRandom() * (max - min);
};
var _seededRandom = function() {
Common._seed = (Common._seed * 9301 + 49297) % 233280;
return Common._seed / 233280;
};
Common.colorToNumber = function(colorString) {
colorString = colorString.replace("#", "");
if (colorString.length == 3) {
colorString = colorString.charAt(0) + colorString.charAt(0) + colorString.charAt(1) + colorString.charAt(1) + colorString.charAt(2) + colorString.charAt(2);
}
return parseInt(colorString, 16);
};
Common.logLevel = 1;
Common.log = function() {
if (console && Common.logLevel > 0 && Common.logLevel <= 3) {
console.log.apply(console, ["matter-js:"].concat(Array.prototype.slice.call(arguments)));
}
};
Common.info = function() {
if (console && Common.logLevel > 0 && Common.logLevel <= 2) {
console.info.apply(console, ["matter-js:"].concat(Array.prototype.slice.call(arguments)));
}
};
Common.warn = function() {
if (console && Common.logLevel > 0 && Common.logLevel <= 3) {
console.warn.apply(console, ["matter-js:"].concat(Array.prototype.slice.call(arguments)));
}
};
Common.warnOnce = function() {
var message = Array.prototype.slice.call(arguments).join(" ");
if (!Common._warnedOnce[message]) {
Common.warn(message);
Common._warnedOnce[message] = true;
}
};
Common.deprecated = function(obj, prop, warning) {
obj[prop] = Common.chain(function() {
Common.warnOnce("🔅 deprecated 🔅", warning);
}, obj[prop]);
};
Common.nextId = function() {
return Common._nextId++;
};
Common.indexOf = function(haystack, needle) {
if (haystack.indexOf)
return haystack.indexOf(needle);
for (var i = 0; i < haystack.length; i++) {
if (haystack[i] === needle)
return i;
}
return -1;
};
Common.map = function(list, func) {
if (list.map) {
return list.map(func);
}
var mapped = [];
for (var i = 0; i < list.length; i += 1) {
mapped.push(func(list[i]));
}
return mapped;
};
Common.topologicalSort = function(graph) {
var result = [], visited = [], temp = [];
for (var node in graph) {
if (!visited[node] && !temp[node]) {
Common._topologicalSort(node, visited, temp, graph, result);
}
}
return result;
};
Common._topologicalSort = function(node, visited, temp, graph, result) {
var neighbors = graph[node] || [];
temp[node] = true;
for (var i = 0; i < neighbors.length; i += 1) {
var neighbor = neighbors[i];
if (temp[neighbor]) {
continue;
}
if (!visited[neighbor]) {
Common._topologicalSort(neighbor, visited, temp, graph, result);
}
}
temp[node] = false;
visited[node] = true;
result.push(node);
};
Common.chain = function() {
var funcs = [];
for (var i = 0; i < arguments.length; i += 1) {
var func = arguments[i];
if (func._chained) {
funcs.push.apply(funcs, func._chained);
} else {
funcs.push(func);
}
}
var chain = function() {
var lastResult, args = new Array(arguments.length);
for (var i2 = 0, l = arguments.length; i2 < l; i2++) {
args[i2] = arguments[i2];
}
for (i2 = 0; i2 < funcs.length; i2 += 1) {
var result = funcs[i2].apply(lastResult, args);
if (typeof result !== "undefined") {
lastResult = result;
}
}
return lastResult;
};
chain._chained = funcs;
return chain;
};
Common.chainPathBefore = function(base, path, func) {
return Common.set(base, path, Common.chain(
func,
Common.get(base, path)
));
};
Common.chainPathAfter = function(base, path, func) {
return Common.set(base, path, Common.chain(
Common.get(base, path),
func
));
};
Common.setDecomp = function(decomp) {
Common._decomp = decomp;
};
Common.getDecomp = function() {
var decomp = Common._decomp;
try {
if (!decomp && typeof window !== "undefined") {
decomp = window.decomp;
}
if (!decomp && typeof __webpack_require__2.g !== "undefined") {
decomp = __webpack_require__2.g.decomp;
}
} catch (e) {
decomp = null;
}
return decomp;
};
})();
}
),
/***/
48413: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Engine = {};
module2.exports = Engine;
var Sleeping = __webpack_require__2(53614);
var Resolver = __webpack_require__2(66272);
var Detector = __webpack_require__2(81388);
var Pairs = __webpack_require__2(99561);
var Events = __webpack_require__2(35810);
var Composite = __webpack_require__2(69351);
var Constraint = __webpack_require__2(48140);
var Common = __webpack_require__2(53402);
var Body = __webpack_require__2(22562);
(function() {
Engine._deltaMax = 1e3 / 60;
Engine.create = function(options) {
options = options || {};
var defaults = {
positionIterations: 6,
velocityIterations: 4,
constraintIterations: 2,
enableSleeping: false,
events: [],
plugin: {},
gravity: {
x: 0,
y: 1,
scale: 1e-3
},
timing: {
timestamp: 0,
timeScale: 1,
lastDelta: 0,
lastElapsed: 0,
lastUpdatesPerFrame: 0
}
};
var engine = Common.extend(defaults, options);
engine.world = options.world || Composite.create({ label: "World" });
engine.pairs = options.pairs || Pairs.create();
engine.detector = options.detector || Detector.create();
engine.detector.pairs = engine.pairs;
engine.grid = { buckets: [] };
engine.world.gravity = engine.gravity;
engine.broadphase = engine.grid;
engine.metrics = {};
return engine;
};
Engine.update = function(engine, delta) {
var startTime = Common.now();
var world = engine.world, detector = engine.detector, pairs = engine.pairs, timing = engine.timing, timestamp = timing.timestamp, i;
if (delta > Engine._deltaMax) {
Common.warnOnce(
"Matter.Engine.update: delta argument is recommended to be less than or equal to",
Engine._deltaMax.toFixed(3),
"ms."
);
}
delta = typeof delta !== "undefined" ? delta : Common._baseDelta;
delta *= timing.timeScale;
timing.timestamp += delta;
timing.lastDelta = delta;
var event = {
timestamp: timing.timestamp,
delta
};
Events.trigger(engine, "beforeUpdate", event);
var allBodies = Composite.allBodies(world), allConstraints = Composite.allConstraints(world), allComposites = Composite.allComposites(world);
if (world.isModified) {
Detector.setBodies(detector, allBodies);
Composite.setModified(world, false, false, true);
}
if (engine.enableSleeping)
Sleeping.update(allBodies, delta);
Engine._bodiesApplyGravity(allBodies, engine.gravity);
Engine.wrap(allBodies, allComposites);
Engine.attractors(allBodies);
if (delta > 0) {
Engine._bodiesUpdate(allBodies, delta);
}
Events.trigger(engine, "beforeSolve", event);
Constraint.preSolveAll(allBodies);
for (i = 0; i < engine.constraintIterations; i++) {
Constraint.solveAll(allConstraints, delta);
}
Constraint.postSolveAll(allBodies);
var collisions = Detector.collisions(detector);
Pairs.update(pairs, collisions, timestamp);
if (engine.enableSleeping)
Sleeping.afterCollisions(pairs.list);
if (pairs.collisionStart.length > 0) {
Events.trigger(engine, "collisionStart", {
pairs: pairs.collisionStart,
timestamp: timing.timestamp,
delta
});
}
var positionDamping = Common.clamp(20 / engine.positionIterations, 0, 1);
Resolver.preSolvePosition(pairs.list);
for (i = 0; i < engine.positionIterations; i++) {
Resolver.solvePosition(pairs.list, delta, positionDamping);
}
Resolver.postSolvePosition(allBodies);
Constraint.preSolveAll(allBodies);
for (i = 0; i < engine.constraintIterations; i++) {
Constraint.solveAll(allConstraints, delta);
}
Constraint.postSolveAll(allBodies);
Resolver.preSolveVelocity(pairs.list);
for (i = 0; i < engine.velocityIterations; i++) {
Resolver.solveVelocity(pairs.list, delta);
}
Engine._bodiesUpdateVelocities(allBodies);
if (pairs.collisionActive.length > 0) {
Events.trigger(engine, "collisionActive", {
pairs: pairs.collisionActive,
timestamp: timing.timestamp,
delta
});
}
if (pairs.collisionEnd.length > 0) {
Events.trigger(engine, "collisionEnd", {
pairs: pairs.collisionEnd,
timestamp: timing.timestamp,
delta
});
}
Engine._bodiesClearForces(allBodies);
Events.trigger(engine, "afterUpdate", event);
engine.timing.lastElapsed = Common.now() - startTime;
return engine;
};
Engine.merge = function(engineA, engineB) {
Common.extend(engineA, engineB);
if (engineB.world) {
engineA.world = engineB.world;
Engine.clear(engineA);
var bodies = Composite.allBodies(engineA.world);
for (var i = 0; i < bodies.length; i++) {
var body = bodies[i];
Sleeping.set(body, false);
body.id = Common.nextId();
}
}
};
Engine.clear = function(engine) {
Pairs.clear(engine.pairs);
Detector.clear(engine.detector);
};
Engine._bodiesClearForces = function(bodies) {
var bodiesLength = bodies.length;
for (var i = 0; i < bodiesLength; i++) {
var body = bodies[i];
body.force.x = 0;
body.force.y = 0;
body.torque = 0;
}
};
Engine._bodiesApplyGravity = function(bodies, gravity) {
var gravityScale = typeof gravity.scale !== "undefined" ? gravity.scale : 1e-3, bodiesLength = bodies.length;
if (gravity.x === 0 && gravity.y === 0 || gravityScale === 0) {
return;
}
for (var i = 0; i < bodiesLength; i++) {
var body = bodies[i];
if (body.ignoreGravity || body.isStatic || body.isSleeping)
continue;
body.force.y += body.mass * gravity.y * gravityScale;
body.force.x += body.mass * gravity.x * gravityScale;
}
};
Engine._bodiesUpdate = function(bodies, delta) {
var bodiesLength = bodies.length;
for (var i = 0; i < bodiesLength; i++) {
var body = bodies[i];
if (body.isStatic || body.isSleeping)
continue;
Body.update(body, delta);
}
};
Engine._bodiesUpdateVelocities = function(bodies) {
var bodiesLength = bodies.length;
for (var i = 0; i < bodiesLength; i++) {
Body.updateVelocities(bodies[i]);
}
};
Engine.wrap = function(bodies, composites) {
for (var i = 0; i < bodies.length; i += 1) {
var body = bodies[i];
if (body.wrapBounds !== null) {
Body.wrap(body, body.wrapBounds);
}
}
for (i = 0; i < composites.length; i += 1) {
var composite = composites[i];
if (composite.wrapBounds !== null) {
Composite.wrap(composite, composite.wrapBounds);
}
}
};
Engine.attractors = function(bodies) {
for (var i = 0; i < bodies.length; i++) {
var bodyA = bodies[i];
var attractors = bodyA.attractors;
if (attractors && attractors.length > 0) {
for (var j = 0; j < bodies.length; j++) {
var bodyB = bodies[j];
if (i !== j) {
for (var k = 0; k < attractors.length; k++) {
var attractor = attractors[k];
var forceVector = attractor;
if (Common.isFunction(attractor)) {
forceVector = attractor(bodyA, bodyB);
}
if (forceVector) {
Body.applyForce(bodyB, bodyB.position, forceVector);
}
}
}
}
}
}
};
})();
}
),
/***/
35810: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Events = {};
module2.exports = Events;
var Common = __webpack_require__2(53402);
(function() {
Events.on = function(object, eventNames, callback) {
var names = eventNames.split(" "), name;
for (var i = 0; i < names.length; i++) {
name = names[i];
object.events = object.events || {};
object.events[name] = object.events[name] || [];
object.events[name].push(callback);
}
return callback;
};
Events.off = function(object, eventNames, callback) {
if (!eventNames) {
object.events = {};
return;
}
if (typeof eventNames === "function") {
callback = eventNames;
eventNames = Common.keys(object.events).join(" ");
}
var names = eventNames.split(" ");
for (var i = 0; i < names.length; i++) {
var callbacks = object.events[names[i]], newCallbacks = [];
if (callback && callbacks) {
for (var j = 0; j < callbacks.length; j++) {
if (callbacks[j] !== callback)
newCallbacks.push(callbacks[j]);
}
}
object.events[names[i]] = newCallbacks;
}
};
Events.trigger = function(object, eventNames, event) {
var names, name, callbacks, eventClone;
var events = object.events;
if (events && Common.keys(events).length > 0) {
if (!event)
event = {};
names = eventNames.split(" ");
for (var i = 0; i < names.length; i++) {
name = names[i];
callbacks = events[name];
if (callbacks) {
eventClone = Common.clone(event, false);
eventClone.name = name;
eventClone.source = object;
for (var j = 0; j < callbacks.length; j++) {
callbacks[j].apply(object, [eventClone]);
}
}
}
}
};
})();
}
),
/***/
6790: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Matter = {};
module2.exports = Matter;
var Plugin = __webpack_require__2(73832);
var Common = __webpack_require__2(53402);
(function() {
Matter.name = "matter-js";
Matter.version = "0.20.0";
Matter.uses = [];
Matter.used = [];
Matter.use = function() {
Plugin.use(Matter, Array.prototype.slice.call(arguments));
};
Matter.before = function(path, func) {
path = path.replace(/^Matter./, "");
return Common.chainPathBefore(Matter, path, func);
};
Matter.after = function(path, func) {
path = path.replace(/^Matter./, "");
return Common.chainPathAfter(Matter, path, func);
};
})();
}
),
/***/
73832: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Plugin = {};
module2.exports = Plugin;
var Common = __webpack_require__2(53402);
(function() {
Plugin._registry = {};
Plugin.register = function(plugin) {
if (!Plugin.isPlugin(plugin)) {
Common.warn("Plugin.register:", Plugin.toString(plugin), "does not implement all required fields.");
}
if (plugin.name in Plugin._registry) {
var registered = Plugin._registry[plugin.name], pluginVersion = Plugin.versionParse(plugin.version).number, registeredVersion = Plugin.versionParse(registered.version).number;
if (pluginVersion > registeredVersion) {
Common.warn("Plugin.register:", Plugin.toString(registered), "was upgraded to", Plugin.toString(plugin));
Plugin._registry[plugin.name] = plugin;
} else if (pluginVersion < registeredVersion) {
Common.warn("Plugin.register:", Plugin.toString(registered), "can not be downgraded to", Plugin.toString(plugin));
} else if (plugin !== registered) {
Common.warn("Plugin.register:", Plugin.toString(plugin), "is already registered to different plugin object");
}
} else {
Plugin._registry[plugin.name] = plugin;
}
return plugin;
};
Plugin.resolve = function(dependency) {
return Plugin._registry[Plugin.dependencyParse(dependency).name];
};
Plugin.toString = function(plugin) {
return typeof plugin === "string" ? plugin : (plugin.name || "anonymous") + "@" + (plugin.version || plugin.range || "0.0.0");
};
Plugin.isPlugin = function(obj) {
return obj && obj.name && obj.version && obj.install;
};
Plugin.isUsed = function(module3, name) {
return module3.used.indexOf(name) > -1;
};
Plugin.isFor = function(plugin, module3) {
var parsed = plugin.for && Plugin.dependencyParse(plugin.for);
return !plugin.for || module3.name === parsed.name && Plugin.versionSatisfies(module3.version, parsed.range);
};
Plugin.use = function(module3, plugins) {
module3.uses = (module3.uses || []).concat(plugins || []);
if (module3.uses.length === 0) {
Common.warn("Plugin.use:", Plugin.toString(module3), "does not specify any dependencies to install.");
return;
}
var dependencies = Plugin.dependencies(module3), sortedDependencies = Common.topologicalSort(dependencies), status = [];
for (var i = 0; i < sortedDependencies.length; i += 1) {
if (sortedDependencies[i] === module3.name) {
continue;
}
var plugin = Plugin.resolve(sortedDependencies[i]);
if (!plugin) {
status.push("❌ " + sortedDependencies[i]);
continue;
}
if (Plugin.isUsed(module3, plugin.name)) {
continue;
}
if (!Plugin.isFor(plugin, module3)) {
Common.warn("Plugin.use:", Plugin.toString(plugin), "is for", plugin.for, "but installed on", Plugin.toString(module3) + ".");
plugin._warned = true;
}
if (plugin.install) {
plugin.install(module3);
} else {
Common.warn("Plugin.use:", Plugin.toString(plugin), "does not specify an install function.");
plugin._warned = true;
}
if (plugin._warned) {
status.push("🔶 " + Plugin.toString(plugin));
delete plugin._warned;
} else {
status.push("✅ " + Plugin.toString(plugin));
}
module3.used.push(plugin.name);
}
if (status.length > 0 && !plugin.silent) {
Common.info(status.join(" "));
}
};
Plugin.dependencies = function(module3, tracked) {
var parsedBase = Plugin.dependencyParse(module3), name = parsedBase.name;
tracked = tracked || {};
if (name in tracked) {
return;
}
module3 = Plugin.resolve(module3) || module3;
tracked[name] = Common.map(module3.uses || [], function(dependency) {
if (Plugin.isPlugin(dependency)) {
Plugin.register(dependency);
}
var parsed = Plugin.dependencyParse(dependency), resolved = Plugin.resolve(dependency);
if (resolved && !Plugin.versionSatisfies(resolved.version, parsed.range)) {
Common.warn(
"Plugin.dependencies:",
Plugin.toString(resolved),
"does not satisfy",
Plugin.toString(parsed),
"used by",
Plugin.toString(parsedBase) + "."
);
resolved._warned = true;
module3._warned = true;
} else if (!resolved) {
Common.warn(
"Plugin.dependencies:",
Plugin.toString(dependency),
"used by",
Plugin.toString(parsedBase),
"could not be resolved."
);
module3._warned = true;
}
return parsed.name;
});
for (var i = 0; i < tracked[name].length; i += 1) {
Plugin.dependencies(tracked[name][i], tracked);
}
return tracked;
};
Plugin.dependencyParse = function(dependency) {
if (Common.isString(dependency)) {
var pattern = /^[\w-]+(@(\*|[\^~]?\d+\.\d+\.\d+(-[0-9A-Za-z-+]+)?))?$/;
if (!pattern.test(dependency)) {
Common.warn("Plugin.dependencyParse:", dependency, "is not a valid dependency string.");
}
return {
name: dependency.split("@")[0],
range: dependency.split("@")[1] || "*"
};
}
return {
name: dependency.name,
range: dependency.range || dependency.version
};
};
Plugin.versionParse = function(range) {
var pattern = /^(\*)|(\^|~|>=|>)?\s*((\d+)\.(\d+)\.(\d+))(-[0-9A-Za-z-+]+)?$/;
if (!pattern.test(range)) {
Common.warn("Plugin.versionParse:", range, "is not a valid version or range.");
}
var parts = pattern.exec(range);
var major = Number(parts[4]);
var minor = Number(parts[5]);
var patch = Number(parts[6]);
return {
isRange: Boolean(parts[1] || parts[2]),
version: parts[3],
range,
operator: parts[1] || parts[2] || "",
major,
minor,
patch,
parts: [major, minor, patch],
prerelease: parts[7],
number: major * 1e8 + minor * 1e4 + patch
};
};
Plugin.versionSatisfies = function(version, range) {
range = range || "*";
var r = Plugin.versionParse(range), v = Plugin.versionParse(version);
if (r.isRange) {
if (r.operator === "*" || version === "*") {
return true;
}
if (r.operator === ">") {
return v.number > r.number;
}
if (r.operator === ">=") {
return v.number >= r.number;
}
if (r.operator === "~") {
return v.major === r.major && v.minor === r.minor && v.patch >= r.patch;
}
if (r.operator === "^") {
if (r.major > 0) {
return v.major === r.major && v.number >= r.number;
}
if (r.minor > 0) {
return v.minor === r.minor && v.patch >= r.patch;
}
return v.patch === r.patch;
}
}
return version === range || version === "*";
};
})();
}
),
/***/
13037: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Runner = {};
module2.exports = Runner;
var Events = __webpack_require__2(35810);
var Engine = __webpack_require__2(48413);
var Common = __webpack_require__2(53402);
(function() {
Runner._maxFrameDelta = 1e3 / 15;
Runner._frameDeltaFallback = 1e3 / 60;
Runner._timeBufferMargin = 1.5;
Runner._elapsedNextEstimate = 1;
Runner._smoothingLowerBound = 0.1;
Runner._smoothingUpperBound = 0.9;
Runner.create = function(options) {
var defaults = {
delta: 1e3 / 60,
frameDelta: null,
frameDeltaSmoothing: true,
frameDeltaSnapping: true,
frameDeltaHistory: [],
frameDeltaHistorySize: 100,
frameRequestId: null,
timeBuffer: 0,
timeLastTick: null,
maxUpdates: null,
maxFrameTime: 1e3 / 30,
lastUpdatesDeferred: 0,
enabled: true
};
var runner = Common.extend(defaults, options);
runner.fps = 0;
return runner;
};
Runner.run = function(runner, engine) {
runner.timeBuffer = Runner._frameDeltaFallback;
(function onFrame(time) {
runner.frameRequestId = Runner._onNextFrame(runner, onFrame);
if (time && runner.enabled) {
Runner.tick(runner, engine, time);
}
})();
return runner;
};
Runner.tick = function(runner, engine, time) {
var tickStartTime = Common.now(), engineDelta = runner.delta, updateCount = 0;
var frameDelta = time - runner.timeLastTick;
if (!frameDelta || !runner.timeLastTick || frameDelta > Math.max(Runner._maxFrameDelta, runner.maxFrameTime)) {
frameDelta = runner.frameDelta || Runner._frameDeltaFallback;
}
if (runner.frameDeltaSmoothing) {
runner.frameDeltaHistory.push(frameDelta);
runner.frameDeltaHistory = runner.frameDeltaHistory.slice(-runner.frameDeltaHistorySize);
var deltaHistorySorted = runner.frameDeltaHistory.slice(0).sort();
var deltaHistoryWindow = runner.frameDeltaHistory.slice(
deltaHistorySorted.length * Runner._smoothingLowerBound,
deltaHistorySorted.length * Runner._smoothingUpperBound
);
var frameDeltaSmoothed = _mean(deltaHistoryWindow);
frameDelta = frameDeltaSmoothed || frameDelta;
}
if (runner.frameDeltaSnapping) {
frameDelta = 1e3 / Math.round(1e3 / frameDelta);
}
runner.frameDelta = frameDelta;
runner.timeLastTick = time;
runner.timeBuffer += runner.frameDelta;
runner.timeBuffer = Common.clamp(
runner.timeBuffer,
0,
runner.frameDelta + engineDelta * Runner._timeBufferMargin
);
runner.lastUpdatesDeferred = 0;
var maxUpdates = runner.maxUpdates || Math.ceil(runner.maxFrameTime / engineDelta);
var event = {
timestamp: engine.timing.timestamp
};
Events.trigger(runner, "beforeTick", event);
Events.trigger(runner, "tick", event);
var updateStartTime = Common.now();
while (engineDelta > 0 && runner.timeBuffer >= engineDelta * Runner._timeBufferMargin) {
Events.trigger(runner, "beforeUpdate", event);
Engine.update(engine, engineDelta);
Events.trigger(runner, "afterUpdate", event);
runner.timeBuffer -= engineDelta;
updateCount += 1;
var elapsedTimeTotal = Common.now() - tickStartTime, elapsedTimeUpdates = Common.now() - updateStartTime, elapsedNextEstimate = elapsedTimeTotal + Runner._elapsedNextEstimate * elapsedTimeUpdates / updateCount;
if (updateCount >= maxUpdates || elapsedNextEstimate > runner.maxFrameTime) {
runner.lastUpdatesDeferred = Math.round(Math.max(0, runner.timeBuffer / engineDelta - Runner._timeBufferMargin));
break;
}
}
engine.timing.lastUpdatesPerFrame = updateCount;
Events.trigger(runner, "afterTick", event);
if (runner.frameDeltaHistory.length >= 100) {
if (runner.lastUpdatesDeferred && Math.round(runner.frameDelta / engineDelta) > maxUpdates) {
Common.warnOnce("Matter.Runner: runner reached runner.maxUpdates, see docs.");
} else if (runner.lastUpdatesDeferred) {
Common.warnOnce("Matter.Runner: runner reached runner.maxFrameTime, see docs.");
}
if (typeof runner.isFixed !== "undefined") {
Common.warnOnce("Matter.Runner: runner.isFixed is now redundant, see docs.");
}
if (runner.deltaMin || runner.deltaMax) {
Common.warnOnce("Matter.Runner: runner.deltaMin and runner.deltaMax were removed, see docs.");
}
if (runner.fps !== 0) {
Common.warnOnce("Matter.Runner: runner.fps was replaced by runner.delta, see docs.");
}
}
};
Runner.stop = function(runner) {
Runner._cancelNextFrame(runner);
};
Runner._onNextFrame = function(runner, callback) {
if (typeof window !== "undefined" && window.requestAnimationFrame) {
runner.frameRequestId = window.requestAnimationFrame(callback);
} else {
throw new Error("Matter.Runner: missing required global window.requestAnimationFrame.");
}
return runner.frameRequestId;
};
Runner._cancelNextFrame = function(runner) {
if (typeof window !== "undefined" && window.cancelAnimationFrame) {
window.cancelAnimationFrame(runner.frameRequestId);
} else {
throw new Error("Matter.Runner: missing required global window.cancelAnimationFrame.");
}
};
var _mean = function(values) {
var result = 0, valuesLength = values.length;
for (var i = 0; i < valuesLength; i += 1) {
result += values[i];
}
return result / valuesLength || 0;
};
})();
}
),
/***/
53614: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Sleeping = {};
module2.exports = Sleeping;
var Body = __webpack_require__2(22562);
var Events = __webpack_require__2(35810);
var Common = __webpack_require__2(53402);
(function() {
Sleeping._motionWakeThreshold = 0.18;
Sleeping._motionSleepThreshold = 0.08;
Sleeping._minBias = 0.9;
Sleeping.update = function(bodies, delta) {
var timeScale = delta / Common._baseDelta, motionSleepThreshold = Sleeping._motionSleepThreshold;
for (var i = 0; i < bodies.length; i++) {
var body = bodies[i], speed = Body.getSpeed(body), angularSpeed = Body.getAngularSpeed(body), motion = speed * speed + angularSpeed * angularSpeed;
if (body.force.x !== 0 || body.force.y !== 0) {
Sleeping.set(body, false);
continue;
}
var minMotion = Math.min(body.motion, motion), maxMotion = Math.max(body.motion, motion);
body.motion = Sleeping._minBias * minMotion + (1 - Sleeping._minBias) * maxMotion;
if (body.sleepThreshold > 0 && body.motion < motionSleepThreshold) {
body.sleepCounter += 1;
if (body.sleepCounter >= body.sleepThreshold / timeScale) {
Sleeping.set(body, true);
}
} else if (body.sleepCounter > 0) {
body.sleepCounter -= 1;
}
}
};
Sleeping.afterCollisions = function(pairs) {
var motionSleepThreshold = Sleeping._motionSleepThreshold;
for (var i = 0; i < pairs.length; i++) {
var pair = pairs[i];
if (!pair.isActive)
continue;
var collision = pair.collision, bodyA = collision.bodyA.parent, bodyB = collision.bodyB.parent;
if (bodyA.isSleeping && bodyB.isSleeping || bodyA.isStatic || bodyB.isStatic)
continue;
if (bodyA.isSleeping || bodyB.isSleeping) {
var sleepingBody = bodyA.isSleeping && !bodyA.isStatic ? bodyA : bodyB, movingBody = sleepingBody === bodyA ? bodyB : bodyA;
if (!sleepingBody.isStatic && movingBody.motion > motionSleepThreshold) {
Sleeping.set(sleepingBody, false);
}
}
}
};
Sleeping.set = function(body, isSleeping) {
var wasSleeping = body.isSleeping;
if (isSleeping) {
body.isSleeping = true;
body.sleepCounter = body.sleepThreshold;
body.positionImpulse.x = 0;
body.positionImpulse.y = 0;
body.positionPrev.x = body.position.x;
body.positionPrev.y = body.position.y;
body.anglePrev = body.angle;
body.speed = 0;
body.angularSpeed = 0;
body.motion = 0;
if (!wasSleeping) {
Events.trigger(body, "sleepStart");
}
} else {
body.isSleeping = false;
body.sleepCounter = 0;
if (wasSleeping) {
Events.trigger(body, "sleepEnd");
}
}
};
})();
}
),
/***/
66280: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Bodies = {};
module2.exports = Bodies;
var Vertices = __webpack_require__2(41598);
var Common = __webpack_require__2(53402);
var Body = __webpack_require__2(22562);
var Bounds = __webpack_require__2(15647);
var Vector = __webpack_require__2(31725);
(function() {
Bodies.rectangle = function(x, y, width, height, options) {
options = options || {};
var rectangle = {
label: "Rectangle Body",
position: { x, y },
vertices: Vertices.fromPath("L 0 0 L " + width + " 0 L " + width + " " + height + " L 0 " + height)
};
if (options.chamfer) {
var chamfer = options.chamfer;
rectangle.vertices = Vertices.chamfer(
rectangle.vertices,
chamfer.radius,
chamfer.quality,
chamfer.qualityMin,
chamfer.qualityMax
);
delete options.chamfer;
}
return Body.create(Common.extend({}, rectangle, options));
};
Bodies.trapezoid = function(x, y, width, height, slope, options) {
options = options || {};
if (slope >= 1) {
Common.warn("Bodies.trapezoid: slope parameter must be < 1.");
}
slope *= 0.5;
var roof = (1 - slope * 2) * width;
var x1 = width * slope, x2 = x1 + roof, x3 = x2 + x1, verticesPath;
if (slope < 0.5) {
verticesPath = "L 0 0 L " + x1 + " " + -height + " L " + x2 + " " + -height + " L " + x3 + " 0";
} else {
verticesPath = "L 0 0 L " + x2 + " " + -height + " L " + x3 + " 0";
}
var trapezoid = {
label: "Trapezoid Body",
position: { x, y },
vertices: Vertices.fromPath(verticesPath)
};
if (options.chamfer) {
var chamfer = options.chamfer;
trapezoid.vertices = Vertices.chamfer(
trapezoid.vertices,
chamfer.radius,
chamfer.quality,
chamfer.qualityMin,
chamfer.qualityMax
);
delete options.chamfer;
}
return Body.create(Common.extend({}, trapezoid, options));
};
Bodies.circle = function(x, y, radius, options, maxSides) {
options = options || {};
var circle = {
label: "Circle Body",
circleRadius: radius
};
maxSides = maxSides || 25;
var sides = Math.ceil(Math.max(10, Math.min(maxSides, radius)));
if (sides % 2 === 1)
sides += 1;
return Bodies.polygon(x, y, sides, radius, Common.extend({}, circle, options));
};
Bodies.polygon = function(x, y, sides, radius, options) {
options = options || {};
if (sides < 3)
return Bodies.circle(x, y, radius, options);
var theta = 2 * Math.PI / sides, path = "", offset = theta * 0.5;
for (var i = 0; i < sides; i += 1) {
var angle = offset + i * theta, xx = Math.cos(angle) * radius, yy = Math.sin(angle) * radius;
path += "L " + xx.toFixed(3) + " " + yy.toFixed(3) + " ";
}
var polygon = {
label: "Polygon Body",
position: { x, y },
vertices: Vertices.fromPath(path)
};
if (options.chamfer) {
var chamfer = options.chamfer;
polygon.vertices = Vertices.chamfer(
polygon.vertices,
chamfer.radius,
chamfer.quality,
chamfer.qualityMin,
chamfer.qualityMax
);
delete options.chamfer;
}
return Body.create(Common.extend({}, polygon, options));
};
Bodies.fromVertices = function(x, y, vertexSets, options, flagInternal, removeCollinear, minimumArea, removeDuplicatePoints) {
var decomp = Common.getDecomp(), canDecomp, body, parts, isConvex, isConcave, vertices, i, j, k, v, z;
canDecomp = Boolean(decomp && decomp.quickDecomp);
options = options || {};
parts = [];
flagInternal = typeof flagInternal !== "undefined" ? flagInternal : false;
removeCollinear = typeof removeCollinear !== "undefined" ? removeCollinear : 0.01;
minimumArea = typeof minimumArea !== "undefined" ? minimumArea : 10;
removeDuplicatePoints = typeof removeDuplicatePoints !== "undefined" ? removeDuplicatePoints : 0.01;
if (!Common.isArray(vertexSets[0])) {
vertexSets = [vertexSets];
}
for (v = 0; v < vertexSets.length; v += 1) {
vertices = vertexSets[v];
isConvex = Vertices.isConvex(vertices);
isConcave = !isConvex;
if (isConcave && !canDecomp) {
Common.warnOnce(
"Bodies.fromVertices: Install the 'poly-decomp' library and use Common.setDecomp or provide 'decomp' as a global to decompose concave vertices."
);
}
if (isConvex || !canDecomp) {
if (isConvex) {
vertices = Vertices.clockwiseSort(vertices);
} else {
vertices = Vertices.hull(vertices);
}
parts.push({
position: { x, y },
vertices
});
} else {
var concave = vertices.map(function(vertex) {
return [vertex.x, vertex.y];
});
decomp.makeCCW(concave);
if (removeCollinear !== false)
decomp.removeCollinearPoints(concave, removeCollinear);
if (removeDuplicatePoints !== false && decomp.removeDuplicatePoints)
decomp.removeDuplicatePoints(concave, removeDuplicatePoints);
var decomposed = decomp.quickDecomp(concave);
for (i = 0; i < decomposed.length; i++) {
var chunk = decomposed[i];
var chunkVertices = chunk.map(function(vertices2) {
return {
x: vertices2[0],
y: vertices2[1]
};
});
if (minimumArea > 0 && Vertices.area(chunkVertices) < minimumArea)
continue;
parts.push({
position: Vertices.centre(chunkVertices),
vertices: chunkVertices
});
}
}
}
for (i = 0; i < parts.length; i++) {
parts[i] = Body.create(Common.extend(parts[i], options));
}
if (flagInternal) {
var coincident_max_dist = 5;
for (i = 0; i < parts.length; i++) {
var partA = parts[i];
for (j = i + 1; j < parts.length; j++) {
var partB = parts[j];
if (Bounds.overlaps(partA.bounds, partB.bounds)) {
var pav = partA.vertices, pbv = partB.vertices;
for (k = 0; k < partA.vertices.length; k++) {
for (z = 0; z < partB.vertices.length; z++) {
var da = Vector.magnitudeSquared(Vector.sub(pav[(k + 1) % pav.length], pbv[z])), db = Vector.magnitudeSquared(Vector.sub(pav[k], pbv[(z + 1) % pbv.length]));
if (da < coincident_max_dist && db < coincident_max_dist) {
pav[k].isInternal = true;
pbv[z].isInternal = true;
}
}
}
}
}
}
}
if (parts.length > 1) {
body = Body.create(Common.extend({ parts: parts.slice(0) }, options));
Body.setPosition(body, { x, y });
return body;
} else {
return parts[0];
}
};
Bodies.flagCoincidentParts = function(parts, maxDistance) {
if (maxDistance === void 0) {
maxDistance = 5;
}
for (var i = 0; i < parts.length; i++) {
var partA = parts[i];
for (var j = i + 1; j < parts.length; j++) {
var partB = parts[j];
if (Bounds.overlaps(partA.bounds, partB.bounds)) {
var pav = partA.vertices;
var pbv = partB.vertices;
for (var k = 0; k < partA.vertices.length; k++) {
for (var z = 0; z < partB.vertices.length; z++) {
var da = Vector.magnitudeSquared(Vector.sub(pav[(k + 1) % pav.length], pbv[z]));
var db = Vector.magnitudeSquared(Vector.sub(pav[k], pbv[(z + 1) % pbv.length]));
if (da < maxDistance && db < maxDistance) {
pav[k].isInternal = true;
pbv[z].isInternal = true;
}
}
}
}
}
}
return parts;
};
})();
}
),
/***/
74116: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Composites = {};
module2.exports = Composites;
var Composite = __webpack_require__2(69351);
var Constraint = __webpack_require__2(48140);
var Common = __webpack_require__2(53402);
var Body = __webpack_require__2(22562);
var Bodies = __webpack_require__2(66280);
(function() {
Composites.stack = function(x, y, columns, rows, columnGap, rowGap, callback) {
var stack = Composite.create({ label: "Stack" }), currentX = x, currentY = y, lastBody, i = 0;
for (var row = 0; row < rows; row++) {
var maxHeight = 0;
for (var column = 0; column < columns; column++) {
var body = callback(currentX, currentY, column, row, lastBody, i);
if (body) {
var bodyHeight = body.bounds.max.y - body.bounds.min.y, bodyWidth = body.bounds.max.x - body.bounds.min.x;
if (bodyHeight > maxHeight)
maxHeight = bodyHeight;
Body.translate(body, { x: bodyWidth * 0.5, y: bodyHeight * 0.5 });
currentX = body.bounds.max.x + columnGap;
Composite.addBody(stack, body);
lastBody = body;
i += 1;
} else {
currentX += columnGap;
}
}
currentY += maxHeight + rowGap;
currentX = x;
}
return stack;
};
Composites.chain = function(composite, xOffsetA, yOffsetA, xOffsetB, yOffsetB, options) {
var bodies = composite.bodies;
for (var i = 1; i < bodies.length; i++) {
var bodyA = bodies[i - 1], bodyB = bodies[i], bodyAHeight = bodyA.bounds.max.y - bodyA.bounds.min.y, bodyAWidth = bodyA.bounds.max.x - bodyA.bounds.min.x, bodyBHeight = bodyB.bounds.max.y - bodyB.bounds.min.y, bodyBWidth = bodyB.bounds.max.x - bodyB.bounds.min.x;
var defaults = {
bodyA,
pointA: { x: bodyAWidth * xOffsetA, y: bodyAHeight * yOffsetA },
bodyB,
pointB: { x: bodyBWidth * xOffsetB, y: bodyBHeight * yOffsetB }
};
var constraint = Common.extend(defaults, options);
Composite.addConstraint(composite, Constraint.create(constraint));
}
composite.label += " Chain";
return composite;
};
Composites.mesh = function(composite, columns, rows, crossBrace, options) {
var bodies = composite.bodies, row, col, bodyA, bodyB, bodyC;
for (row = 0; row < rows; row++) {
for (col = 1; col < columns; col++) {
bodyA = bodies[col - 1 + row * columns];
bodyB = bodies[col + row * columns];
Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA, bodyB }, options)));
}
if (row > 0) {
for (col = 0; col < columns; col++) {
bodyA = bodies[col + (row - 1) * columns];
bodyB = bodies[col + row * columns];
Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA, bodyB }, options)));
if (crossBrace && col > 0) {
bodyC = bodies[col - 1 + (row - 1) * columns];
Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyC, bodyB }, options)));
}
if (crossBrace && col < columns - 1) {
bodyC = bodies[col + 1 + (row - 1) * columns];
Composite.addConstraint(composite, Constraint.create(Common.extend({ bodyA: bodyC, bodyB }, options)));
}
}
}
}
composite.label += " Mesh";
return composite;
};
Composites.pyramid = function(x, y, columns, rows, columnGap, rowGap, callback) {
return Composites.stack(x, y, columns, rows, columnGap, rowGap, function(stackX, stackY, column, row, lastBody, i) {
var actualRows = Math.min(rows, Math.ceil(columns / 2)), lastBodyWidth = lastBody ? lastBody.bounds.max.x - lastBody.bounds.min.x : 0;
if (row > actualRows)
return;
row = actualRows - row;
var start = row, end = columns - 1 - row;
if (column < start || column > end)
return;
if (i === 1) {
Body.translate(lastBody, { x: (column + (columns % 2 === 1 ? 1 : -1)) * lastBodyWidth, y: 0 });
}
var xOffset = lastBody ? column * lastBodyWidth : 0;
return callback(x + xOffset + column * columnGap, stackY, column, row, lastBody, i);
});
};
Composites.newtonsCradle = function(x, y, number, size, length) {
var newtonsCradle = Composite.create({ label: "Newtons Cradle" });
for (var i = 0; i < number; i++) {
var separation = 1.9, circle = Bodies.circle(
x + i * (size * separation),
y + length,
size,
{ inertia: Infinity, restitution: 1, friction: 0, frictionAir: 1e-4, slop: 1 }
), constraint = Constraint.create({ pointA: { x: x + i * (size * separation), y }, bodyB: circle });
Composite.addBody(newtonsCradle, circle);
Composite.addConstraint(newtonsCradle, constraint);
}
return newtonsCradle;
};
Composites.car = function(x, y, width, height, wheelSize) {
var group = Body.nextGroup(true), wheelBase = 20, wheelAOffset = -width * 0.5 + wheelBase, wheelBOffset = width * 0.5 - wheelBase, wheelYOffset = 0;
var car = Composite.create({ label: "Car" }), body = Bodies.rectangle(x, y, width, height, {
collisionFilter: {
group
},
chamfer: {
radius: height * 0.5
},
density: 2e-4
});
var wheelA = Bodies.circle(x + wheelAOffset, y + wheelYOffset, wheelSize, {
collisionFilter: {
group
},
friction: 0.8
});
var wheelB = Bodies.circle(x + wheelBOffset, y + wheelYOffset, wheelSize, {
collisionFilter: {
group
},
friction: 0.8
});
var axelA = Constraint.create({
bodyB: body,
pointB: { x: wheelAOffset, y: wheelYOffset },
bodyA: wheelA,
stiffness: 1,
length: 0
});
var axelB = Constraint.create({
bodyB: body,
pointB: { x: wheelBOffset, y: wheelYOffset },
bodyA: wheelB,
stiffness: 1,
length: 0
});
Composite.addBody(car, body);
Composite.addBody(car, wheelA);
Composite.addBody(car, wheelB);
Composite.addConstraint(car, axelA);
Composite.addConstraint(car, axelB);
return car;
};
Composites.softBody = function(x, y, columns, rows, columnGap, rowGap, crossBrace, particleRadius, particleOptions, constraintOptions) {
particleOptions = Common.extend({ inertia: Infinity }, particleOptions);
constraintOptions = Common.extend({ stiffness: 0.2, render: { type: "line", anchors: false } }, constraintOptions);
var softBody = Composites.stack(x, y, columns, rows, columnGap, rowGap, function(stackX, stackY) {
return Bodies.circle(stackX, stackY, particleRadius, particleOptions);
});
Composites.mesh(softBody, columns, rows, crossBrace, constraintOptions);
softBody.label = "Soft Body";
return softBody;
};
})();
}
),
/***/
66615: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Axes = {};
module2.exports = Axes;
var Vector = __webpack_require__2(31725);
var Common = __webpack_require__2(53402);
(function() {
Axes.fromVertices = function(vertices) {
var axes = {};
for (var i = 0; i < vertices.length; i++) {
var j = (i + 1) % vertices.length, normal = Vector.normalise({
x: vertices[j].y - vertices[i].y,
y: vertices[i].x - vertices[j].x
}), gradient = normal.y === 0 ? Infinity : normal.x / normal.y;
gradient = gradient.toFixed(3).toString();
axes[gradient] = normal;
}
return Common.values(axes);
};
Axes.rotate = function(axes, angle) {
if (angle === 0)
return;
var cos = Math.cos(angle), sin = Math.sin(angle);
for (var i = 0; i < axes.length; i++) {
var axis = axes[i], xx;
xx = axis.x * cos - axis.y * sin;
axis.y = axis.x * sin + axis.y * cos;
axis.x = xx;
}
};
})();
}
),
/***/
15647: (
/***/
(module2) => {
var Bounds = {};
module2.exports = Bounds;
(function() {
Bounds.create = function(vertices) {
var bounds = {
min: { x: 0, y: 0 },
max: { x: 0, y: 0 }
};
if (vertices)
Bounds.update(bounds, vertices);
return bounds;
};
Bounds.update = function(bounds, vertices, velocity) {
bounds.min.x = Infinity;
bounds.max.x = -Infinity;
bounds.min.y = Infinity;
bounds.max.y = -Infinity;
for (var i = 0; i < vertices.length; i++) {
var vertex = vertices[i];
if (vertex.x > bounds.max.x) bounds.max.x = vertex.x;
if (vertex.x < bounds.min.x) bounds.min.x = vertex.x;
if (vertex.y > bounds.max.y) bounds.max.y = vertex.y;
if (vertex.y < bounds.min.y) bounds.min.y = vertex.y;
}
if (velocity) {
if (velocity.x > 0) {
bounds.max.x += velocity.x;
} else {
bounds.min.x += velocity.x;
}
if (velocity.y > 0) {
bounds.max.y += velocity.y;
} else {
bounds.min.y += velocity.y;
}
}
};
Bounds.contains = function(bounds, point) {
return point.x >= bounds.min.x && point.x <= bounds.max.x && point.y >= bounds.min.y && point.y <= bounds.max.y;
};
Bounds.overlaps = function(boundsA, boundsB) {
return boundsA.min.x <= boundsB.max.x && boundsA.max.x >= boundsB.min.x && boundsA.max.y >= boundsB.min.y && boundsA.min.y <= boundsB.max.y;
};
Bounds.translate = function(bounds, vector) {
bounds.min.x += vector.x;
bounds.max.x += vector.x;
bounds.min.y += vector.y;
bounds.max.y += vector.y;
};
Bounds.shift = function(bounds, position) {
var deltaX = bounds.max.x - bounds.min.x, deltaY = bounds.max.y - bounds.min.y;
bounds.min.x = position.x;
bounds.max.x = position.x + deltaX;
bounds.min.y = position.y;
bounds.max.y = position.y + deltaY;
};
Bounds.wrap = function(objectBounds, bounds, padding) {
var x = null, y = null;
if (typeof bounds.min.x !== "undefined" && typeof bounds.max.x !== "undefined") {
if (objectBounds.min.x > bounds.max.x) {
x = bounds.min.x - objectBounds.max.x;
} else if (objectBounds.max.x < bounds.min.x) {
x = bounds.max.x - objectBounds.min.x;
}
}
if (typeof bounds.min.y !== "undefined" && typeof bounds.max.y !== "undefined") {
if (objectBounds.min.y > bounds.max.y) {
y = bounds.min.y - objectBounds.max.y;
} else if (objectBounds.max.y < bounds.min.y) {
y = bounds.max.y - objectBounds.min.y;
}
}
if (x !== null || y !== null) {
return {
x: x || 0,
y: y || 0
};
}
};
})();
}
),
/***/
74058: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Svg = {};
module2.exports = Svg;
var Bounds = __webpack_require__2(15647);
var Common = __webpack_require__2(53402);
(function() {
Svg.pathToVertices = function(path, sampleLength) {
if (typeof window !== "undefined" && !("SVGPathSeg" in window)) {
Common.warn("Svg.pathToVertices: SVGPathSeg not defined, a polyfill is required.");
}
var i, il, total, point, segment, segments, segmentsQueue, lastSegment, lastPoint, segmentIndex, points = [], lx, ly, length = 0, x = 0, y = 0;
sampleLength = sampleLength || 15;
var addPoint = function(px, py, pathSegType) {
var isRelative = pathSegType % 2 === 1 && pathSegType > 1;
if (!lastPoint || px != lastPoint.x || py != lastPoint.y) {
if (lastPoint && isRelative) {
lx = lastPoint.x;
ly = lastPoint.y;
} else {
lx = 0;
ly = 0;
}
var point2 = {
x: lx + px,
y: ly + py
};
if (isRelative || !lastPoint) {
lastPoint = point2;
}
points.push(point2);
x = lx + px;
y = ly + py;
}
};
var addSegmentPoint = function(segment2) {
var segType = segment2.pathSegTypeAsLetter.toUpperCase();
if (segType === "Z")
return;
switch (segType) {
case "M":
case "L":
case "T":
case "C":
case "S":
case "Q":
x = segment2.x;
y = segment2.y;
break;
case "H":
x = segment2.x;
break;
case "V":
y = segment2.y;
break;
}
addPoint(x, y, segment2.pathSegType);
};
Svg._svgPathToAbsolute(path);
total = path.getTotalLength();
segments = [];
for (i = 0; i < path.pathSegList.numberOfItems; i += 1)
segments.push(path.pathSegList.getItem(i));
segmentsQueue = segments.concat();
while (length < total) {
segmentIndex = path.getPathSegAtLength(length);
segment = segments[segmentIndex];
if (segment != lastSegment) {
while (segmentsQueue.length && segmentsQueue[0] != segment)
addSegmentPoint(segmentsQueue.shift());
lastSegment = segment;
}
switch (segment.pathSegTypeAsLetter.toUpperCase()) {
case "C":
case "T":
case "S":
case "Q":
case "A":
point = path.getPointAtLength(length);
addPoint(point.x, point.y, 0);
break;
}
length += sampleLength;
}
for (i = 0, il = segmentsQueue.length; i < il; ++i)
addSegmentPoint(segmentsQueue[i]);
return points;
};
Svg._svgPathToAbsolute = function(path) {
var x0, y0, x1, y1, x2, y2, segs = path.pathSegList, x = 0, y = 0, len = segs.numberOfItems;
for (var i = 0; i < len; ++i) {
var seg = segs.getItem(i), segType = seg.pathSegTypeAsLetter;
if (/[MLHVCSQTA]/.test(segType)) {
if ("x" in seg) x = seg.x;
if ("y" in seg) y = seg.y;
} else {
if ("x1" in seg) x1 = x + seg.x1;
if ("x2" in seg) x2 = x + seg.x2;
if ("y1" in seg) y1 = y + seg.y1;
if ("y2" in seg) y2 = y + seg.y2;
if ("x" in seg) x += seg.x;
if ("y" in seg) y += seg.y;
switch (segType) {
case "m":
segs.replaceItem(path.createSVGPathSegMovetoAbs(x, y), i);
break;
case "l":
segs.replaceItem(path.createSVGPathSegLinetoAbs(x, y), i);
break;
case "h":
segs.replaceItem(path.createSVGPathSegLinetoHorizontalAbs(x), i);
break;
case "v":
segs.replaceItem(path.createSVGPathSegLinetoVerticalAbs(y), i);
break;
case "c":
segs.replaceItem(path.createSVGPathSegCurvetoCubicAbs(x, y, x1, y1, x2, y2), i);
break;
case "s":
segs.replaceItem(path.createSVGPathSegCurvetoCubicSmoothAbs(x, y, x2, y2), i);
break;
case "q":
segs.replaceItem(path.createSVGPathSegCurvetoQuadraticAbs(x, y, x1, y1), i);
break;
case "t":
segs.replaceItem(path.createSVGPathSegCurvetoQuadraticSmoothAbs(x, y), i);
break;
case "a":
segs.replaceItem(path.createSVGPathSegArcAbs(x, y, seg.r1, seg.r2, seg.angle, seg.largeArcFlag, seg.sweepFlag), i);
break;
case "z":
case "Z":
x = x0;
y = y0;
break;
}
}
if (segType == "M" || segType == "m") {
x0 = x;
y0 = y;
}
}
};
})();
}
),
/***/
31725: (
/***/
(module2) => {
var Vector = {};
module2.exports = Vector;
(function() {
Vector.create = function(x, y) {
return { x: x || 0, y: y || 0 };
};
Vector.clone = function(vector) {
return { x: vector.x, y: vector.y };
};
Vector.magnitude = function(vector) {
return Math.sqrt(vector.x * vector.x + vector.y * vector.y);
};
Vector.magnitudeSquared = function(vector) {
return vector.x * vector.x + vector.y * vector.y;
};
Vector.rotate = function(vector, angle, output) {
var cos = Math.cos(angle), sin = Math.sin(angle);
if (!output) output = {};
var x = vector.x * cos - vector.y * sin;
output.y = vector.x * sin + vector.y * cos;
output.x = x;
return output;
};
Vector.rotateAbout = function(vector, angle, point, output) {
var cos = Math.cos(angle), sin = Math.sin(angle);
if (!output) output = {};
var x = point.x + ((vector.x - point.x) * cos - (vector.y - point.y) * sin);
output.y = point.y + ((vector.x - point.x) * sin + (vector.y - point.y) * cos);
output.x = x;
return output;
};
Vector.normalise = function(vector) {
var magnitude = Vector.magnitude(vector);
if (magnitude === 0)
return { x: 0, y: 0 };
return { x: vector.x / magnitude, y: vector.y / magnitude };
};
Vector.dot = function(vectorA, vectorB) {
return vectorA.x * vectorB.x + vectorA.y * vectorB.y;
};
Vector.cross = function(vectorA, vectorB) {
return vectorA.x * vectorB.y - vectorA.y * vectorB.x;
};
Vector.cross3 = function(vectorA, vectorB, vectorC) {
return (vectorB.x - vectorA.x) * (vectorC.y - vectorA.y) - (vectorB.y - vectorA.y) * (vectorC.x - vectorA.x);
};
Vector.add = function(vectorA, vectorB, output) {
if (!output) output = {};
output.x = vectorA.x + vectorB.x;
output.y = vectorA.y + vectorB.y;
return output;
};
Vector.sub = function(vectorA, vectorB, output) {
if (!output) output = {};
output.x = vectorA.x - vectorB.x;
output.y = vectorA.y - vectorB.y;
return output;
};
Vector.mult = function(vector, scalar) {
return { x: vector.x * scalar, y: vector.y * scalar };
};
Vector.div = function(vector, scalar) {
return { x: vector.x / scalar, y: vector.y / scalar };
};
Vector.perp = function(vector, negate) {
negate = negate === true ? -1 : 1;
return { x: negate * -vector.y, y: negate * vector.x };
};
Vector.neg = function(vector) {
return { x: -vector.x, y: -vector.y };
};
Vector.angle = function(vectorA, vectorB) {
return Math.atan2(vectorB.y - vectorA.y, vectorB.x - vectorA.x);
};
Vector._temp = [
Vector.create(),
Vector.create(),
Vector.create(),
Vector.create(),
Vector.create(),
Vector.create()
];
})();
}
),
/***/
41598: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Vertices = {};
module2.exports = Vertices;
var Vector = __webpack_require__2(31725);
var Common = __webpack_require__2(53402);
(function() {
Vertices.create = function(points, body) {
var vertices = [];
for (var i = 0; i < points.length; i++) {
var point = points[i], vertex = {
x: point.x,
y: point.y,
index: i,
body,
isInternal: false
};
vertices.push(vertex);
}
return vertices;
};
Vertices.fromPath = function(path, body) {
var pathPattern = /L?\s*([-\d.e]+)[\s,]*([-\d.e]+)*/ig, points = [];
path.replace(pathPattern, function(match, x, y) {
points.push({ x: parseFloat(x), y: parseFloat(y) });
});
return Vertices.create(points, body);
};
Vertices.centre = function(vertices) {
var area = Vertices.area(vertices, true), centre = { x: 0, y: 0 }, cross, temp, j;
for (var i = 0; i < vertices.length; i++) {
j = (i + 1) % vertices.length;
cross = Vector.cross(vertices[i], vertices[j]);
temp = Vector.mult(Vector.add(vertices[i], vertices[j]), cross);
centre = Vector.add(centre, temp);
}
return Vector.div(centre, 6 * area);
};
Vertices.mean = function(vertices) {
var average = { x: 0, y: 0 };
for (var i = 0; i < vertices.length; i++) {
average.x += vertices[i].x;
average.y += vertices[i].y;
}
return Vector.div(average, vertices.length);
};
Vertices.area = function(vertices, signed) {
var area = 0, j = vertices.length - 1;
for (var i = 0; i < vertices.length; i++) {
area += (vertices[j].x - vertices[i].x) * (vertices[j].y + vertices[i].y);
j = i;
}
if (signed)
return area / 2;
return Math.abs(area) / 2;
};
Vertices.inertia = function(vertices, mass) {
var numerator = 0, denominator = 0, v = vertices, cross, j;
for (var n = 0; n < v.length; n++) {
j = (n + 1) % v.length;
cross = Math.abs(Vector.cross(v[j], v[n]));
numerator += cross * (Vector.dot(v[j], v[j]) + Vector.dot(v[j], v[n]) + Vector.dot(v[n], v[n]));
denominator += cross;
}
return mass / 6 * (numerator / denominator);
};
Vertices.translate = function(vertices, vector, scalar) {
scalar = typeof scalar !== "undefined" ? scalar : 1;
var verticesLength = vertices.length, translateX = vector.x * scalar, translateY = vector.y * scalar, i;
for (i = 0; i < verticesLength; i++) {
vertices[i].x += translateX;
vertices[i].y += translateY;
}
return vertices;
};
Vertices.rotate = function(vertices, angle, point) {
if (angle === 0)
return;
var cos = Math.cos(angle), sin = Math.sin(angle), pointX = point.x, pointY = point.y, verticesLength = vertices.length, vertex, dx, dy, i;
for (i = 0; i < verticesLength; i++) {
vertex = vertices[i];
dx = vertex.x - pointX;
dy = vertex.y - pointY;
vertex.x = pointX + (dx * cos - dy * sin);
vertex.y = pointY + (dx * sin + dy * cos);
}
return vertices;
};
Vertices.contains = function(vertices, point) {
var pointX = point.x, pointY = point.y, verticesLength = vertices.length, vertex = vertices[verticesLength - 1], nextVertex;
for (var i = 0; i < verticesLength; i++) {
nextVertex = vertices[i];
if ((pointX - vertex.x) * (nextVertex.y - vertex.y) + (pointY - vertex.y) * (vertex.x - nextVertex.x) > 0) {
return false;
}
vertex = nextVertex;
}
return true;
};
Vertices.scale = function(vertices, scaleX, scaleY, point) {
if (scaleX === 1 && scaleY === 1)
return vertices;
point = point || Vertices.centre(vertices);
var vertex, delta;
for (var i = 0; i < vertices.length; i++) {
vertex = vertices[i];
delta = Vector.sub(vertex, point);
vertices[i].x = point.x + delta.x * scaleX;
vertices[i].y = point.y + delta.y * scaleY;
}
return vertices;
};
Vertices.chamfer = function(vertices, radius, quality, qualityMin, qualityMax) {
if (typeof radius === "number") {
radius = [radius];
} else {
radius = radius || [8];
}
quality = typeof quality !== "undefined" ? quality : -1;
qualityMin = qualityMin || 2;
qualityMax = qualityMax || 14;
var newVertices = [];
for (var i = 0; i < vertices.length; i++) {
var prevVertex = vertices[i - 1 >= 0 ? i - 1 : vertices.length - 1], vertex = vertices[i], nextVertex = vertices[(i + 1) % vertices.length], currentRadius = radius[i < radius.length ? i : radius.length - 1];
if (currentRadius === 0) {
newVertices.push(vertex);
continue;
}
var prevNormal = Vector.normalise({
x: vertex.y - prevVertex.y,
y: prevVertex.x - vertex.x
});
var nextNormal = Vector.normalise({
x: nextVertex.y - vertex.y,
y: vertex.x - nextVertex.x
});
var diagonalRadius = Math.sqrt(2 * Math.pow(currentRadius, 2)), radiusVector = Vector.mult(Common.clone(prevNormal), currentRadius), midNormal = Vector.normalise(Vector.mult(Vector.add(prevNormal, nextNormal), 0.5)), scaledVertex = Vector.sub(vertex, Vector.mult(midNormal, diagonalRadius));
var precision = quality;
if (quality === -1) {
precision = Math.pow(currentRadius, 0.32) * 1.75;
}
precision = Common.clamp(precision, qualityMin, qualityMax);
if (precision % 2 === 1)
precision += 1;
var alpha = Math.acos(Vector.dot(prevNormal, nextNormal)), theta = alpha / precision;
for (var j = 0; j < precision; j++) {
newVertices.push(Vector.add(Vector.rotate(radiusVector, theta * j), scaledVertex));
}
}
return newVertices;
};
Vertices.clockwiseSort = function(vertices) {
var centre = Vertices.mean(vertices);
vertices.sort(function(vertexA, vertexB) {
return Vector.angle(centre, vertexA) - Vector.angle(centre, vertexB);
});
return vertices;
};
Vertices.isConvex = function(vertices) {
var flag = 0, n = vertices.length, i, j, k, z;
if (n < 3)
return null;
for (i = 0; i < n; i++) {
j = (i + 1) % n;
k = (i + 2) % n;
z = (vertices[j].x - vertices[i].x) * (vertices[k].y - vertices[j].y);
z -= (vertices[j].y - vertices[i].y) * (vertices[k].x - vertices[j].x);
if (z < 0) {
flag |= 1;
} else if (z > 0) {
flag |= 2;
}
if (flag === 3) {
return false;
}
}
if (flag !== 0) {
return true;
} else {
return null;
}
};
Vertices.hull = function(vertices) {
var upper = [], lower = [], vertex, i;
vertices = vertices.slice(0);
vertices.sort(function(vertexA, vertexB) {
var dx = vertexA.x - vertexB.x;
return dx !== 0 ? dx : vertexA.y - vertexB.y;
});
for (i = 0; i < vertices.length; i += 1) {
vertex = vertices[i];
while (lower.length >= 2 && Vector.cross3(lower[lower.length - 2], lower[lower.length - 1], vertex) <= 0) {
lower.pop();
}
lower.push(vertex);
}
for (i = vertices.length - 1; i >= 0; i -= 1) {
vertex = vertices[i];
while (upper.length >= 2 && Vector.cross3(upper[upper.length - 2], upper[upper.length - 1], vertex) <= 0) {
upper.pop();
}
upper.push(vertex);
}
upper.pop();
lower.pop();
return upper.concat(lower);
};
})();
}
),
/***/
55973: (
/***/
(module2) => {
module2.exports = {
decomp: polygonDecomp,
quickDecomp: polygonQuickDecomp,
isSimple: polygonIsSimple,
removeCollinearPoints: polygonRemoveCollinearPoints,
removeDuplicatePoints: polygonRemoveDuplicatePoints,
makeCCW: polygonMakeCCW
};
function lineInt(l1, l2, precision) {
precision = precision || 0;
var i = [0, 0];
var a1, b1, c1, a2, b2, c2, det;
a1 = l1[1][1] - l1[0][1];
b1 = l1[0][0] - l1[1][0];
c1 = a1 * l1[0][0] + b1 * l1[0][1];
a2 = l2[1][1] - l2[0][1];
b2 = l2[0][0] - l2[1][0];
c2 = a2 * l2[0][0] + b2 * l2[0][1];
det = a1 * b2 - a2 * b1;
if (!scalar_eq(det, 0, precision)) {
i[0] = (b2 * c1 - b1 * c2) / det;
i[1] = (a1 * c2 - a2 * c1) / det;
}
return i;
}
function lineSegmentsIntersect(p1, p2, q1, q2) {
var dx = p2[0] - p1[0];
var dy = p2[1] - p1[1];
var da = q2[0] - q1[0];
var db = q2[1] - q1[1];
if (da * dy - db * dx === 0) {
return false;
}
var s = (dx * (q1[1] - p1[1]) + dy * (p1[0] - q1[0])) / (da * dy - db * dx);
var t = (da * (p1[1] - q1[1]) + db * (q1[0] - p1[0])) / (db * dx - da * dy);
return s >= 0 && s <= 1 && t >= 0 && t <= 1;
}
function triangleArea(a, b, c) {
return (b[0] - a[0]) * (c[1] - a[1]) - (c[0] - a[0]) * (b[1] - a[1]);
}
function isLeft(a, b, c) {
return triangleArea(a, b, c) > 0;
}
function isLeftOn(a, b, c) {
return triangleArea(a, b, c) >= 0;
}
function isRight(a, b, c) {
return triangleArea(a, b, c) < 0;
}
function isRightOn(a, b, c) {
return triangleArea(a, b, c) <= 0;
}
var tmpPoint1 = [], tmpPoint2 = [];
function collinear(a, b, c, thresholdAngle) {
if (!thresholdAngle) {
return triangleArea(a, b, c) === 0;
} else {
var ab = tmpPoint1, bc = tmpPoint2;
ab[0] = b[0] - a[0];
ab[1] = b[1] - a[1];
bc[0] = c[0] - b[0];
bc[1] = c[1] - b[1];
var dot = ab[0] * bc[0] + ab[1] * bc[1], magA = Math.sqrt(ab[0] * ab[0] + ab[1] * ab[1]), magB = Math.sqrt(bc[0] * bc[0] + bc[1] * bc[1]), angle = Math.acos(dot / (magA * magB));
return angle < thresholdAngle;
}
}
function sqdist(a, b) {
var dx = b[0] - a[0];
var dy = b[1] - a[1];
return dx * dx + dy * dy;
}
function polygonAt(polygon, i) {
var s = polygon.length;
return polygon[i < 0 ? i % s + s : i % s];
}
function polygonClear(polygon) {
polygon.length = 0;
}
function polygonAppend(polygon, poly, from, to) {
for (var i = from; i < to; i++) {
polygon.push(poly[i]);
}
}
function polygonMakeCCW(polygon) {
var br = 0, v = polygon;
for (var i = 1; i < polygon.length; ++i) {
if (v[i][1] < v[br][1] || v[i][1] === v[br][1] && v[i][0] > v[br][0]) {
br = i;
}
}
if (!isLeft(polygonAt(polygon, br - 1), polygonAt(polygon, br), polygonAt(polygon, br + 1))) {
polygonReverse(polygon);
return true;
} else {
return false;
}
}
function polygonReverse(polygon) {
var tmp = [];
var N = polygon.length;
for (var i = 0; i !== N; i++) {
tmp.push(polygon.pop());
}
for (var i = 0; i !== N; i++) {
polygon[i] = tmp[i];
}
}
function polygonIsReflex(polygon, i) {
return isRight(polygonAt(polygon, i - 1), polygonAt(polygon, i), polygonAt(polygon, i + 1));
}
var tmpLine1 = [], tmpLine2 = [];
function polygonCanSee(polygon, a, b) {
var p, dist, l1 = tmpLine1, l2 = tmpLine2;
if (isLeftOn(polygonAt(polygon, a + 1), polygonAt(polygon, a), polygonAt(polygon, b)) && isRightOn(polygonAt(polygon, a - 1), polygonAt(polygon, a), polygonAt(polygon, b))) {
return false;
}
dist = sqdist(polygonAt(polygon, a), polygonAt(polygon, b));
for (var i = 0; i !== polygon.length; ++i) {
if ((i + 1) % polygon.length === a || i === a) {
continue;
}
if (isLeftOn(polygonAt(polygon, a), polygonAt(polygon, b), polygonAt(polygon, i + 1)) && isRightOn(polygonAt(polygon, a), polygonAt(polygon, b), polygonAt(polygon, i))) {
l1[0] = polygonAt(polygon, a);
l1[1] = polygonAt(polygon, b);
l2[0] = polygonAt(polygon, i);
l2[1] = polygonAt(polygon, i + 1);
p = lineInt(l1, l2);
if (sqdist(polygonAt(polygon, a), p) < dist) {
return false;
}
}
}
return true;
}
function polygonCanSee2(polygon, a, b) {
for (var i = 0; i !== polygon.length; ++i) {
if (i === a || i === b || (i + 1) % polygon.length === a || (i + 1) % polygon.length === b) {
continue;
}
if (lineSegmentsIntersect(polygonAt(polygon, a), polygonAt(polygon, b), polygonAt(polygon, i), polygonAt(polygon, i + 1))) {
return false;
}
}
return true;
}
function polygonCopy(polygon, i, j, targetPoly) {
var p = targetPoly || [];
polygonClear(p);
if (i < j) {
for (var k = i; k <= j; k++) {
p.push(polygon[k]);
}
} else {
for (var k = 0; k <= j; k++) {
p.push(polygon[k]);
}
for (var k = i; k < polygon.length; k++) {
p.push(polygon[k]);
}
}
return p;
}
function polygonGetCutEdges(polygon) {
var min = [], tmp1 = [], tmp2 = [], tmpPoly = [];
var nDiags = Number.MAX_VALUE;
for (var i = 0; i < polygon.length; ++i) {
if (polygonIsReflex(polygon, i)) {
for (var j = 0; j < polygon.length; ++j) {
if (polygonCanSee(polygon, i, j)) {
tmp1 = polygonGetCutEdges(polygonCopy(polygon, i, j, tmpPoly));
tmp2 = polygonGetCutEdges(polygonCopy(polygon, j, i, tmpPoly));
for (var k = 0; k < tmp2.length; k++) {
tmp1.push(tmp2[k]);
}
if (tmp1.length < nDiags) {
min = tmp1;
nDiags = tmp1.length;
min.push([polygonAt(polygon, i), polygonAt(polygon, j)]);
}
}
}
}
}
return min;
}
function polygonDecomp(polygon) {
var edges = polygonGetCutEdges(polygon);
if (edges.length > 0) {
return polygonSlice(polygon, edges);
} else {
return [polygon];
}
}
function polygonSlice(polygon, cutEdges) {
if (cutEdges.length === 0) {
return [polygon];
}
if (cutEdges instanceof Array && cutEdges.length && cutEdges[0] instanceof Array && cutEdges[0].length === 2 && cutEdges[0][0] instanceof Array) {
var polys = [polygon];
for (var i = 0; i < cutEdges.length; i++) {
var cutEdge = cutEdges[i];
for (var j = 0; j < polys.length; j++) {
var poly = polys[j];
var result = polygonSlice(poly, cutEdge);
if (result) {
polys.splice(j, 1);
polys.push(result[0], result[1]);
break;
}
}
}
return polys;
} else {
var cutEdge = cutEdges;
var i = polygon.indexOf(cutEdge[0]);
var j = polygon.indexOf(cutEdge[1]);
if (i !== -1 && j !== -1) {
return [
polygonCopy(polygon, i, j),
polygonCopy(polygon, j, i)
];
} else {
return false;
}
}
}
function polygonIsSimple(polygon) {
var path = polygon, i;
for (i = 0; i < path.length - 1; i++) {
for (var j = 0; j < i - 1; j++) {
if (lineSegmentsIntersect(path[i], path[i + 1], path[j], path[j + 1])) {
return false;
}
}
}
for (i = 1; i < path.length - 2; i++) {
if (lineSegmentsIntersect(path[0], path[path.length - 1], path[i], path[i + 1])) {
return false;
}
}
return true;
}
function getIntersectionPoint(p1, p2, q1, q2, delta) {
delta = delta || 0;
var a1 = p2[1] - p1[1];
var b1 = p1[0] - p2[0];
var c1 = a1 * p1[0] + b1 * p1[1];
var a2 = q2[1] - q1[1];
var b2 = q1[0] - q2[0];
var c2 = a2 * q1[0] + b2 * q1[1];
var det = a1 * b2 - a2 * b1;
if (!scalar_eq(det, 0, delta)) {
return [(b2 * c1 - b1 * c2) / det, (a1 * c2 - a2 * c1) / det];
} else {
return [0, 0];
}
}
function polygonQuickDecomp(polygon, result, reflexVertices, steinerPoints, delta, maxlevel, level) {
maxlevel = maxlevel || 100;
level = level || 0;
delta = delta || 25;
result = typeof result !== "undefined" ? result : [];
reflexVertices = reflexVertices || [];
steinerPoints = steinerPoints || [];
var upperInt = [0, 0], lowerInt = [0, 0], p = [0, 0];
var upperDist = 0, lowerDist = 0, d = 0, closestDist = 0;
var upperIndex = 0, lowerIndex = 0, closestIndex = 0;
var lowerPoly = [], upperPoly = [];
var poly = polygon, v = polygon;
if (v.length < 3) {
return result;
}
level++;
if (level > maxlevel) {
console.warn("quickDecomp: max level (" + maxlevel + ") reached.");
return result;
}
for (var i = 0; i < polygon.length; ++i) {
if (polygonIsReflex(poly, i)) {
reflexVertices.push(poly[i]);
upperDist = lowerDist = Number.MAX_VALUE;
for (var j = 0; j < polygon.length; ++j) {
if (isLeft(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j)) && isRightOn(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j - 1))) {
p = getIntersectionPoint(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j), polygonAt(poly, j - 1));
if (isRight(polygonAt(poly, i + 1), polygonAt(poly, i), p)) {
d = sqdist(poly[i], p);
if (d < lowerDist) {
lowerDist = d;
lowerInt = p;
lowerIndex = j;
}
}
}
if (isLeft(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j + 1)) && isRightOn(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j))) {
p = getIntersectionPoint(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j), polygonAt(poly, j + 1));
if (isLeft(polygonAt(poly, i - 1), polygonAt(poly, i), p)) {
d = sqdist(poly[i], p);
if (d < upperDist) {
upperDist = d;
upperInt = p;
upperIndex = j;
}
}
}
}
if (lowerIndex === (upperIndex + 1) % polygon.length) {
p[0] = (lowerInt[0] + upperInt[0]) / 2;
p[1] = (lowerInt[1] + upperInt[1]) / 2;
steinerPoints.push(p);
if (i < upperIndex) {
polygonAppend(lowerPoly, poly, i, upperIndex + 1);
lowerPoly.push(p);
upperPoly.push(p);
if (lowerIndex !== 0) {
polygonAppend(upperPoly, poly, lowerIndex, poly.length);
}
polygonAppend(upperPoly, poly, 0, i + 1);
} else {
if (i !== 0) {
polygonAppend(lowerPoly, poly, i, poly.length);
}
polygonAppend(lowerPoly, poly, 0, upperIndex + 1);
lowerPoly.push(p);
upperPoly.push(p);
polygonAppend(upperPoly, poly, lowerIndex, i + 1);
}
} else {
if (lowerIndex > upperIndex) {
upperIndex += polygon.length;
}
closestDist = Number.MAX_VALUE;
if (upperIndex < lowerIndex) {
return result;
}
for (var j = lowerIndex; j <= upperIndex; ++j) {
if (isLeftOn(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j)) && isRightOn(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j))) {
d = sqdist(polygonAt(poly, i), polygonAt(poly, j));
if (d < closestDist && polygonCanSee2(poly, i, j)) {
closestDist = d;
closestIndex = j % polygon.length;
}
}
}
if (i < closestIndex) {
polygonAppend(lowerPoly, poly, i, closestIndex + 1);
if (closestIndex !== 0) {
polygonAppend(upperPoly, poly, closestIndex, v.length);
}
polygonAppend(upperPoly, poly, 0, i + 1);
} else {
if (i !== 0) {
polygonAppend(lowerPoly, poly, i, v.length);
}
polygonAppend(lowerPoly, poly, 0, closestIndex + 1);
polygonAppend(upperPoly, poly, closestIndex, i + 1);
}
}
if (lowerPoly.length < upperPoly.length) {
polygonQuickDecomp(lowerPoly, result, reflexVertices, steinerPoints, delta, maxlevel, level);
polygonQuickDecomp(upperPoly, result, reflexVertices, steinerPoints, delta, maxlevel, level);
} else {
polygonQuickDecomp(upperPoly, result, reflexVertices, steinerPoints, delta, maxlevel, level);
polygonQuickDecomp(lowerPoly, result, reflexVertices, steinerPoints, delta, maxlevel, level);
}
return result;
}
}
result.push(polygon);
return result;
}
function polygonRemoveCollinearPoints(polygon, precision) {
var num = 0;
for (var i = polygon.length - 1; polygon.length > 3 && i >= 0; --i) {
if (collinear(polygonAt(polygon, i - 1), polygonAt(polygon, i), polygonAt(polygon, i + 1), precision)) {
polygon.splice(i % polygon.length, 1);
num++;
}
}
return num;
}
function polygonRemoveDuplicatePoints(polygon, precision) {
for (var i = polygon.length - 1; i >= 1; --i) {
var pi = polygon[i];
for (var j = i - 1; j >= 0; --j) {
if (points_eq(pi, polygon[j], precision)) {
polygon.splice(i, 1);
continue;
}
}
}
}
function scalar_eq(a, b, precision) {
precision = precision || 0;
return Math.abs(a - b) <= precision;
}
function points_eq(a, b, precision) {
return scalar_eq(a[0], b[0], precision) && scalar_eq(a[1], b[1], precision);
}
}
),
/***/
52018: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var BasePlugin = new Class({
initialize: function BasePlugin2(pluginManager) {
this.pluginManager = pluginManager;
this.game = pluginManager.game;
},
/**
* The PluginManager calls this method on a Global Plugin when the plugin is first instantiated.
* It will never be called again on this instance.
* In here you can set-up whatever you need for this plugin to run.
* If a plugin is set to automatically start then `BasePlugin.start` will be called immediately after this.
* On a Scene Plugin, this method is never called. Use {@link Phaser.Plugins.ScenePlugin#boot} instead.
*
* @method Phaser.Plugins.BasePlugin#init
* @since 3.8.0
*
* @param {?any} [data] - A value specified by the user, if any, from the `data` property of the plugin's configuration object (if started at game boot) or passed in the PluginManager's `install` method (if started manually).
*/
init: function() {
},
/**
* The PluginManager calls this method on a Global Plugin when the plugin is started.
* If a plugin is stopped, and then started again, this will get called again.
* Typically called immediately after `BasePlugin.init`.
* On a Scene Plugin, this method is never called.
*
* @method Phaser.Plugins.BasePlugin#start
* @since 3.8.0
*/
start: function() {
},
/**
* The PluginManager calls this method on a Global Plugin when the plugin is stopped.
* The game code has requested that your plugin stop doing whatever it does.
* It is now considered as 'inactive' by the PluginManager.
* Handle that process here (i.e. stop listening for events, etc)
* If the plugin is started again then `BasePlugin.start` will be called again.
* On a Scene Plugin, this method is never called.
*
* @method Phaser.Plugins.BasePlugin#stop
* @since 3.8.0
*/
stop: function() {
},
/**
* Game instance has been destroyed.
* You must release everything in here, all references, all objects, free it all up.
*
* @method Phaser.Plugins.BasePlugin#destroy
* @since 3.8.0
*/
destroy: function() {
this.pluginManager = null;
this.game = null;
this.scene = null;
this.systems = null;
}
});
module2.exports = BasePlugin;
}
),
/***/
42363: (
/***/
(module2) => {
var DefaultPlugins = {
/**
* These are the Global Managers that are created by the Phaser.Game instance.
* They are referenced from Scene.Systems so that plugins can use them.
*
* @name Phaser.Plugins.DefaultPlugins.Global
* @type {array}
* @since 3.0.0
*/
Global: [
"game",
"anims",
"cache",
"plugins",
"registry",
"scale",
"sound",
"textures",
"renderer"
],
/**
* These are the core plugins that are installed into every Scene.Systems instance, no matter what.
* They are optionally exposed in the Scene as well (see the InjectionMap for details)
*
* They are created in the order in which they appear in this array and EventEmitter is always first.
*
* @name Phaser.Plugins.DefaultPlugins.CoreScene
* @type {array}
* @since 3.0.0
*/
CoreScene: [
"EventEmitter",
"CameraManager",
"GameObjectCreator",
"GameObjectFactory",
"ScenePlugin",
"DisplayList",
"UpdateList"
],
/**
* These plugins are created in Scene.Systems in addition to the CoreScenePlugins.
*
* You can elect not to have these plugins by either creating a DefaultPlugins object as part
* of the Game Config, by creating a Plugins object as part of a Scene Config, or by modifying this array
* and building your own bundle.
*
* They are optionally exposed in the Scene as well (see the InjectionMap for details)
*
* They are always created in the order in which they appear in the array.
*
* @name Phaser.Plugins.DefaultPlugins.DefaultScene
* @type {array}
* @since 3.0.0
*/
DefaultScene: [
"Clock",
"DataManagerPlugin",
"InputPlugin",
"Loader",
"TweenManager",
"LightsPlugin"
]
};
if (false) {
}
if (false) {
}
module2.exports = DefaultPlugins;
}
),
/***/
37277: (
/***/
(module2) => {
var corePlugins = {};
var customPlugins = {};
var PluginCache = {};
PluginCache.register = function(key, plugin, mapping, custom) {
if (custom === void 0) {
custom = false;
}
corePlugins[key] = { plugin, mapping, custom };
};
PluginCache.registerCustom = function(key, plugin, mapping, data) {
customPlugins[key] = { plugin, mapping, data };
};
PluginCache.hasCore = function(key) {
return corePlugins.hasOwnProperty(key);
};
PluginCache.hasCustom = function(key) {
return customPlugins.hasOwnProperty(key);
};
PluginCache.getCore = function(key) {
return corePlugins[key];
};
PluginCache.getCustom = function(key) {
return customPlugins[key];
};
PluginCache.getCustomClass = function(key) {
return customPlugins.hasOwnProperty(key) ? customPlugins[key].plugin : null;
};
PluginCache.remove = function(key) {
if (corePlugins.hasOwnProperty(key)) {
delete corePlugins[key];
}
};
PluginCache.removeCustom = function(key) {
if (customPlugins.hasOwnProperty(key)) {
delete customPlugins[key];
}
};
PluginCache.destroyCorePlugins = function() {
for (var key in corePlugins) {
if (corePlugins.hasOwnProperty(key)) {
delete corePlugins[key];
}
}
};
PluginCache.destroyCustomPlugins = function() {
for (var key in customPlugins) {
if (customPlugins.hasOwnProperty(key)) {
delete customPlugins[key];
}
}
};
module2.exports = PluginCache;
}
),
/***/
77332: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var GameEvents = __webpack_require__2(8443);
var EventEmitter = __webpack_require__2(50792);
var FileTypesManager = __webpack_require__2(74099);
var GameObjectCreator = __webpack_require__2(44603);
var GameObjectFactory = __webpack_require__2(39429);
var GetFastValue = __webpack_require__2(95540);
var PluginCache = __webpack_require__2(37277);
var Remove = __webpack_require__2(72905);
var PluginManager = new Class({
Extends: EventEmitter,
initialize: function PluginManager2(game) {
EventEmitter.call(this);
this.game = game;
this.plugins = [];
this.scenePlugins = [];
this._pendingGlobal = [];
this._pendingScene = [];
if (game.isBooted) {
this.boot();
} else {
game.events.once(GameEvents.BOOT, this.boot, this);
}
},
/**
* Run once the game has booted and installs all of the plugins configured in the Game Config.
*
* @method Phaser.Plugins.PluginManager#boot
* @protected
* @since 3.0.0
*/
boot: function() {
var i;
var entry;
var key;
var plugin;
var start;
var mapping;
var data;
var config = this.game.config;
var list = config.installGlobalPlugins;
list = list.concat(this._pendingGlobal);
for (i = 0; i < list.length; i++) {
entry = list[i];
key = GetFastValue(entry, "key", null);
plugin = GetFastValue(entry, "plugin", null);
start = GetFastValue(entry, "start", false);
mapping = GetFastValue(entry, "mapping", null);
data = GetFastValue(entry, "data", null);
if (key) {
if (plugin) {
this.install(key, plugin, start, mapping, data);
} else {
console.warn("Missing `plugin` for key: " + key);
}
}
}
list = config.installScenePlugins;
list = list.concat(this._pendingScene);
for (i = 0; i < list.length; i++) {
entry = list[i];
key = GetFastValue(entry, "key", null);
plugin = GetFastValue(entry, "plugin", null);
mapping = GetFastValue(entry, "mapping", null);
if (key) {
if (plugin) {
this.installScenePlugin(key, plugin, mapping);
} else {
console.warn("Missing `plugin` for key: " + key);
}
}
}
this._pendingGlobal = [];
this._pendingScene = [];
this.game.events.once(GameEvents.DESTROY, this.destroy, this);
},
/**
* Called by the Scene Systems class. Tells the plugin manager to install all Scene plugins into it.
*
* First it will install global references, i.e. references from the Game systems into the Scene Systems (and Scene if mapped.)
* Then it will install Core Scene Plugins followed by Scene Plugins registered with the PluginManager.
* Finally it will install any references to Global Plugins that have a Scene mapping property into the Scene itself.
*
* @method Phaser.Plugins.PluginManager#addToScene
* @protected
* @since 3.8.0
*
* @param {Phaser.Scenes.Systems} sys - The Scene Systems class to install all the plugins in to.
* @param {array} globalPlugins - An array of global plugins to install.
* @param {array} scenePlugins - An array of scene plugins to install.
*/
addToScene: function(sys, globalPlugins, scenePlugins) {
var i;
var pluginKey;
var pluginList;
var game = this.game;
var scene = sys.scene;
var map = sys.settings.map;
var isBooted = sys.settings.isBooted;
for (i = 0; i < globalPlugins.length; i++) {
pluginKey = globalPlugins[i];
if (game[pluginKey]) {
sys[pluginKey] = game[pluginKey];
if (map.hasOwnProperty(pluginKey)) {
scene[map[pluginKey]] = sys[pluginKey];
}
} else if (pluginKey === "game" && map.hasOwnProperty(pluginKey)) {
scene[map[pluginKey]] = game;
}
}
for (var s = 0; s < scenePlugins.length; s++) {
pluginList = scenePlugins[s];
for (i = 0; i < pluginList.length; i++) {
pluginKey = pluginList[i];
if (!PluginCache.hasCore(pluginKey)) {
continue;
}
var source = PluginCache.getCore(pluginKey);
var mapKey = source.mapping;
var plugin = new source.plugin(scene, this, mapKey);
sys[mapKey] = plugin;
if (source.custom) {
scene[mapKey] = plugin;
} else if (map.hasOwnProperty(mapKey)) {
scene[map[mapKey]] = plugin;
}
if (isBooted) {
plugin.boot();
}
}
}
pluginList = this.plugins;
for (i = 0; i < pluginList.length; i++) {
var entry = pluginList[i];
if (entry.mapping) {
scene[entry.mapping] = entry.plugin;
}
}
},
/**
* Called by the Scene Systems class. Returns a list of plugins to be installed.
*
* @method Phaser.Plugins.PluginManager#getDefaultScenePlugins
* @protected
* @since 3.8.0
*
* @return {string[]} A list keys of all the Scene Plugins to install.
*/
getDefaultScenePlugins: function() {
var list = this.game.config.defaultPlugins;
list = list.concat(this.scenePlugins);
return list;
},
/**
* Installs a new Scene Plugin into the Plugin Manager and optionally adds it
* to the given Scene as well. A Scene Plugin added to the manager in this way
* will be automatically installed into all new Scenes using the key and mapping given.
*
* The `key` property is what the plugin is injected into Scene.Systems as.
* The `mapping` property is optional, and if specified is what the plugin is installed into
* the Scene as. For example:
*
* ```javascript
* this.plugins.installScenePlugin('powerupsPlugin', pluginCode, 'powerups');
*
* // and from within the scene:
* this.sys.powerupsPlugin; // key value
* this.powerups; // mapping value
* ```
*
* This method is called automatically by Phaser if you install your plugins using either the
* Game Configuration object, or by preloading them via the Loader.
*
* @method Phaser.Plugins.PluginManager#installScenePlugin
* @since 3.8.0
*
* @param {string} key - The property key that will be used to add this plugin to Scene.Systems.
* @param {function} plugin - The plugin code. This should be the non-instantiated version.
* @param {string} [mapping] - If this plugin is injected into the Phaser.Scene class, this is the property key to use.
* @param {Phaser.Scene} [addToScene] - Optionally automatically add this plugin to the given Scene.
* @param {boolean} [fromLoader=false] - Is this being called by the Loader?
*/
installScenePlugin: function(key, plugin, mapping, addToScene, fromLoader) {
if (fromLoader === void 0) {
fromLoader = false;
}
if (typeof plugin !== "function") {
console.warn("Invalid Scene Plugin: " + key);
return;
}
if (!PluginCache.hasCore(key)) {
PluginCache.register(key, plugin, mapping, true);
}
if (this.scenePlugins.indexOf(key) === -1) {
this.scenePlugins.push(key);
} else if (!fromLoader && PluginCache.hasCore(key)) {
console.warn("Scene Plugin key in use: " + key);
return;
}
if (addToScene) {
var instance = new plugin(addToScene, this, key);
addToScene.sys[key] = instance;
if (mapping && mapping !== "") {
addToScene[mapping] = instance;
}
instance.boot();
}
},
/**
* Installs a new Global Plugin into the Plugin Manager and optionally starts it running.
* A global plugin belongs to the Plugin Manager, rather than a specific Scene, and can be accessed
* and used by all Scenes in your game.
*
* The `key` property is what you use to access this plugin from the Plugin Manager.
*
* ```javascript
* this.plugins.install('powerupsPlugin', pluginCode);
*
* // and from within the scene:
* this.plugins.get('powerupsPlugin');
* ```
*
* This method is called automatically by Phaser if you install your plugins using either the
* Game Configuration object, or by preloading them via the Loader.
*
* The same plugin can be installed multiple times into the Plugin Manager by simply giving each
* instance its own unique key.
*
* @method Phaser.Plugins.PluginManager#install
* @since 3.8.0
*
* @param {string} key - The unique handle given to this plugin within the Plugin Manager.
* @param {function} plugin - The plugin code. This should be the non-instantiated version.
* @param {boolean} [start=false] - Automatically start the plugin running? This is always `true` if you provide a mapping value.
* @param {string} [mapping] - If this plugin is injected into the Phaser.Scene class, this is the property key to use.
* @param {any} [data] - A value passed to the plugin's `init` method.
*
* @return {?Phaser.Plugins.BasePlugin} The plugin that was started, or `null` if `start` was false, or game isn't yet booted.
*/
install: function(key, plugin, start, mapping, data) {
if (start === void 0) {
start = false;
}
if (mapping === void 0) {
mapping = null;
}
if (data === void 0) {
data = null;
}
if (typeof plugin !== "function") {
console.warn("Invalid Plugin: " + key);
return null;
}
if (PluginCache.hasCustom(key)) {
console.warn("Plugin key in use: " + key);
return null;
}
if (mapping !== null) {
start = true;
}
if (!this.game.isBooted) {
this._pendingGlobal.push({ key, plugin, start, mapping, data });
} else {
PluginCache.registerCustom(key, plugin, mapping, data);
if (start) {
return this.start(key);
}
}
return null;
},
/**
* Gets an index of a global plugin based on the given key.
*
* @method Phaser.Plugins.PluginManager#getIndex
* @protected
* @since 3.8.0
*
* @param {string} key - The unique plugin key.
*
* @return {number} The index of the plugin within the plugins array.
*/
getIndex: function(key) {
var list = this.plugins;
for (var i = 0; i < list.length; i++) {
var entry = list[i];
if (entry.key === key) {
return i;
}
}
return -1;
},
/**
* Gets a global plugin based on the given key.
*
* @method Phaser.Plugins.PluginManager#getEntry
* @protected
* @since 3.8.0
*
* @param {string} key - The unique plugin key.
*
* @return {Phaser.Types.Plugins.GlobalPlugin} The plugin entry.
*/
getEntry: function(key) {
var idx = this.getIndex(key);
if (idx !== -1) {
return this.plugins[idx];
}
},
/**
* Checks if the given global plugin, based on its key, is active or not.
*
* @method Phaser.Plugins.PluginManager#isActive
* @since 3.8.0
*
* @param {string} key - The unique plugin key.
*
* @return {boolean} `true` if the plugin is active, otherwise `false`.
*/
isActive: function(key) {
var entry = this.getEntry(key);
return entry && entry.active;
},
/**
* Starts a global plugin running.
*
* If the plugin was previously active then calling `start` will reset it to an active state and then
* call its `start` method.
*
* If the plugin has never been run before a new instance of it will be created within the Plugin Manager,
* its active state set and then both of its `init` and `start` methods called, in that order.
*
* If the plugin is already running under the given key then nothing happens.
*
* @method Phaser.Plugins.PluginManager#start
* @since 3.8.0
*
* @param {string} key - The key of the plugin to start.
* @param {string} [runAs] - Run the plugin under a new key. This allows you to run one plugin multiple times.
*
* @return {?Phaser.Plugins.BasePlugin} The plugin that was started, or `null` if invalid key given or plugin is already stopped.
*/
start: function(key, runAs) {
if (runAs === void 0) {
runAs = key;
}
var entry = this.getEntry(runAs);
if (entry && !entry.active) {
entry.active = true;
entry.plugin.start();
} else if (!entry) {
entry = this.createEntry(key, runAs);
}
return entry ? entry.plugin : null;
},
/**
* Creates a new instance of a global plugin, adds an entry into the plugins array and returns it.
*
* @method Phaser.Plugins.PluginManager#createEntry
* @private
* @since 3.9.0
*
* @param {string} key - The key of the plugin to create an instance of.
* @param {string} [runAs] - Run the plugin under a new key. This allows you to run one plugin multiple times.
*
* @return {?Phaser.Plugins.BasePlugin} The plugin that was started, or `null` if invalid key given.
*/
createEntry: function(key, runAs) {
var entry = PluginCache.getCustom(key);
if (entry) {
var instance = new entry.plugin(this);
entry = {
key: runAs,
plugin: instance,
active: true,
mapping: entry.mapping,
data: entry.data
};
this.plugins.push(entry);
instance.init(entry.data);
instance.start();
}
return entry;
},
/**
* Stops a global plugin from running.
*
* If the plugin is active then its active state will be set to false and the plugins `stop` method
* will be called.
*
* If the plugin is not already running, nothing will happen.
*
* @method Phaser.Plugins.PluginManager#stop
* @since 3.8.0
*
* @param {string} key - The key of the plugin to stop.
*
* @return {this} The Plugin Manager.
*/
stop: function(key) {
var entry = this.getEntry(key);
if (entry && entry.active) {
entry.active = false;
entry.plugin.stop();
}
return this;
},
/**
* Gets a global plugin from the Plugin Manager based on the given key and returns it.
*
* If it cannot find an active plugin based on the key, but there is one in the Plugin Cache with the same key,
* then it will create a new instance of the cached plugin and return that.
*
* @method Phaser.Plugins.PluginManager#get
* @since 3.8.0
*
* @param {string} key - The key of the plugin to get.
* @param {boolean} [autoStart=true] - Automatically start a new instance of the plugin if found in the cache, but not actively running.
*
* @return {?(Phaser.Plugins.BasePlugin|function)} The plugin, or `null` if no plugin was found matching the key.
*/
get: function(key, autoStart) {
if (autoStart === void 0) {
autoStart = true;
}
var entry = this.getEntry(key);
if (entry) {
return entry.plugin;
} else {
var plugin = this.getClass(key);
if (plugin && autoStart) {
entry = this.createEntry(key, key);
return entry ? entry.plugin : null;
} else if (plugin) {
return plugin;
}
}
return null;
},
/**
* Returns the plugin class from the cache.
* Used internally by the Plugin Manager.
*
* @method Phaser.Plugins.PluginManager#getClass
* @since 3.8.0
*
* @param {string} key - The key of the plugin to get.
*
* @return {Phaser.Plugins.BasePlugin} A Plugin object
*/
getClass: function(key) {
return PluginCache.getCustomClass(key);
},
/**
* Removes a global plugin from the Plugin Manager and Plugin Cache.
*
* It is up to you to remove all references to this plugin that you may hold within your game code.
*
* @method Phaser.Plugins.PluginManager#removeGlobalPlugin
* @since 3.8.0
*
* @param {string} key - The key of the plugin to remove.
*/
removeGlobalPlugin: function(key) {
var entry = this.getEntry(key);
if (entry) {
Remove(this.plugins, entry);
}
PluginCache.removeCustom(key);
},
/**
* Removes a scene plugin from the Plugin Manager and Plugin Cache.
*
* This will not remove the plugin from any active Scenes that are already using it.
*
* It is up to you to remove all references to this plugin that you may hold within your game code.
*
* @method Phaser.Plugins.PluginManager#removeScenePlugin
* @since 3.8.0
*
* @param {string} key - The key of the plugin to remove.
*/
removeScenePlugin: function(key) {
Remove(this.scenePlugins, key);
PluginCache.remove(key);
},
/**
* Registers a new type of Game Object with the global Game Object Factory and / or Creator.
* This is usually called from within your Plugin code and is a helpful short-cut for creating
* new Game Objects.
*
* The key is the property that will be injected into the factories and used to create the
* Game Object. For example:
*
* ```javascript
* this.plugins.registerGameObject('clown', clownFactoryCallback, clownCreatorCallback);
* // later in your game code:
* this.add.clown();
* this.make.clown();
* ```
*
* The callbacks are what are called when the factories try to create a Game Object
* matching the given key. It's important to understand that the callbacks are invoked within
* the context of the GameObjectFactory. In this context there are several properties available
* to use:
*
* this.scene - A reference to the Scene that owns the GameObjectFactory.
* this.displayList - A reference to the Display List the Scene owns.
* this.updateList - A reference to the Update List the Scene owns.
*
* See the GameObjectFactory and GameObjectCreator classes for more details.
* Any public property or method listed is available from your callbacks under `this`.
*
* @method Phaser.Plugins.PluginManager#registerGameObject
* @since 3.8.0
*
* @param {string} key - The key of the Game Object that the given callbacks will create, i.e. `image`, `sprite`.
* @param {function} [factoryCallback] - The callback to invoke when the Game Object Factory is called.
* @param {function} [creatorCallback] - The callback to invoke when the Game Object Creator is called.
*/
registerGameObject: function(key, factoryCallback, creatorCallback) {
if (factoryCallback) {
GameObjectFactory.register(key, factoryCallback);
}
if (creatorCallback) {
GameObjectCreator.register(key, creatorCallback);
}
return this;
},
/**
* Removes a previously registered Game Object from the global Game Object Factory and / or Creator.
* This is usually called from within your Plugin destruction code to help clean-up after your plugin has been removed.
*
* @method Phaser.Plugins.PluginManager#removeGameObject
* @since 3.19.0
*
* @param {string} key - The key of the Game Object to be removed from the factories.
* @param {boolean} [removeFromFactory=true] - Should the Game Object be removed from the Game Object Factory?
* @param {boolean} [removeFromCreator=true] - Should the Game Object be removed from the Game Object Creator?
*/
removeGameObject: function(key, removeFromFactory, removeFromCreator) {
if (removeFromFactory === void 0) {
removeFromFactory = true;
}
if (removeFromCreator === void 0) {
removeFromCreator = true;
}
if (removeFromFactory) {
GameObjectFactory.remove(key);
}
if (removeFromCreator) {
GameObjectCreator.remove(key);
}
return this;
},
/**
* Registers a new file type with the global File Types Manager, making it available to all Loader
* Plugins created after this.
*
* This is usually called from within your Plugin code and is a helpful short-cut for creating
* new loader file types.
*
* The key is the property that will be injected into the Loader Plugin and used to load the
* files. For example:
*
* ```javascript
* this.plugins.registerFileType('wad', doomWadLoaderCallback);
* // later in your preload code:
* this.load.wad();
* ```
*
* The callback is what is called when the loader tries to load a file matching the given key.
* It's important to understand that the callback is invoked within
* the context of the LoaderPlugin. In this context there are several properties / methods available
* to use:
*
* this.addFile - A method to add the new file to the load queue.
* this.scene - The Scene that owns the Loader Plugin instance.
*
* See the LoaderPlugin class for more details. Any public property or method listed is available from
* your callback under `this`.
*
* @method Phaser.Plugins.PluginManager#registerFileType
* @since 3.8.0
*
* @param {string} key - The key of the Game Object that the given callbacks will create, i.e. `image`, `sprite`.
* @param {function} callback - The callback to invoke when the Game Object Factory is called.
* @param {Phaser.Scene} [addToScene] - Optionally add this file type into the Loader Plugin owned by the given Scene.
*/
registerFileType: function(key, callback, addToScene) {
FileTypesManager.register(key, callback);
if (addToScene && addToScene.sys.load) {
addToScene.sys.load[key] = callback;
}
},
/**
* Destroys this Plugin Manager and all associated plugins.
* It will iterate all plugins found and call their `destroy` methods.
*
* The PluginCache will remove all custom plugins.
*
* @method Phaser.Plugins.PluginManager#destroy
* @since 3.8.0
*/
destroy: function() {
for (var i = 0; i < this.plugins.length; i++) {
this.plugins[i].plugin.destroy();
}
PluginCache.destroyCustomPlugins();
if (this.game.noReturn) {
PluginCache.destroyCorePlugins();
}
this.game = null;
this.plugins = [];
this.scenePlugins = [];
}
});
module2.exports = PluginManager;
}
),
/***/
45145: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BasePlugin = __webpack_require__2(52018);
var Class = __webpack_require__2(83419);
var SceneEvents = __webpack_require__2(44594);
var ScenePlugin = new Class({
Extends: BasePlugin,
initialize: function ScenePlugin2(scene, pluginManager, pluginKey) {
BasePlugin.call(this, pluginManager);
this.scene = scene;
this.systems = scene.sys;
this.pluginKey = pluginKey;
scene.sys.events.once(SceneEvents.BOOT, this.boot, this);
},
/**
* This method is called when the Scene boots. It is only ever called once.
*
* By this point the plugin properties `scene` and `systems` will have already been set.
*
* In here you can listen for {@link Phaser.Scenes.Events Scene events} and set-up whatever you need for this plugin to run.
* Here are the Scene events you can listen to:
*
* - start
* - ready
* - preupdate
* - update
* - postupdate
* - resize
* - pause
* - resume
* - sleep
* - wake
* - transitioninit
* - transitionstart
* - transitioncomplete
* - transitionout
* - shutdown
* - destroy
*
* At the very least you should offer a destroy handler for when the Scene closes down, i.e:
*
* ```javascript
* var eventEmitter = this.systems.events;
* eventEmitter.once('destroy', this.sceneDestroy, this);
* ```
*
* @method Phaser.Plugins.ScenePlugin#boot
* @since 3.8.0
*/
boot: function() {
},
/**
* Game instance has been destroyed.
*
* You must release everything in here, all references, all objects, free it all up.
*
* @method Phaser.Plugins.ScenePlugin#destroy
* @since 3.8.0
*/
destroy: function() {
this.pluginManager = null;
this.game = null;
this.scene = null;
this.systems = null;
}
});
module2.exports = ScenePlugin;
}
),
/***/
18922: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
BasePlugin: __webpack_require__2(52018),
DefaultPlugins: __webpack_require__2(42363),
PluginCache: __webpack_require__2(37277),
PluginManager: __webpack_require__2(77332),
ScenePlugin: __webpack_require__2(45145)
};
}
),
/***/
63595: (
/***/
() => {
if (typeof HTMLVideoElement !== "undefined" && !("requestVideoFrameCallback" in HTMLVideoElement.prototype) && "getVideoPlaybackQuality" in HTMLVideoElement.prototype) {
HTMLVideoElement.prototype._rvfcpolyfillmap = {};
HTMLVideoElement.prototype.requestVideoFrameCallback = function(callback) {
const handle = performance.now();
const quality = this.getVideoPlaybackQuality();
const baseline = this.mozPresentedFrames || this.mozPaintedFrames || quality.totalVideoFrames - quality.droppedVideoFrames;
const check = (old, now) => {
const newquality = this.getVideoPlaybackQuality();
const presentedFrames = this.mozPresentedFrames || this.mozPaintedFrames || newquality.totalVideoFrames - newquality.droppedVideoFrames;
if (presentedFrames > baseline) {
const processingDuration = this.mozFrameDelay || newquality.totalFrameDelay - quality.totalFrameDelay || 0;
const timediff = now - old;
callback(now, {
presentationTime: now + processingDuration * 1e3,
expectedDisplayTime: now + timediff,
width: this.videoWidth,
height: this.videoHeight,
mediaTime: Math.max(0, this.currentTime || 0) + timediff / 1e3,
presentedFrames,
processingDuration
});
delete this._rvfcpolyfillmap[handle];
} else {
this._rvfcpolyfillmap[handle] = requestAnimationFrame((newer) => check(now, newer));
}
};
this._rvfcpolyfillmap[handle] = requestAnimationFrame((newer) => check(handle, newer));
return handle;
};
HTMLVideoElement.prototype.cancelVideoFrameCallback = function(handle) {
cancelAnimationFrame(this._rvfcpolyfillmap[handle]);
delete this._rvfcpolyfillmap[handle];
};
}
}
),
/***/
10312: (
/***/
(module2) => {
module2.exports = {
/**
* Skips the Blend Mode check in the renderer.
*
* @name Phaser.BlendModes.SKIP_CHECK
* @type {number}
* @const
* @since 3.0.0
*/
SKIP_CHECK: -1,
/**
* Normal blend mode. For Canvas and WebGL.
* This is the default setting and draws new shapes on top of the existing canvas content.
*
* @name Phaser.BlendModes.NORMAL
* @type {number}
* @const
* @since 3.0.0
*/
NORMAL: 0,
/**
* Add blend mode. For Canvas and WebGL.
* Where both shapes overlap the color is determined by adding color values.
*
* @name Phaser.BlendModes.ADD
* @type {number}
* @const
* @since 3.0.0
*/
ADD: 1,
/**
* Multiply blend mode. For Canvas and WebGL.
* The pixels are of the top layer are multiplied with the corresponding pixel of the bottom layer. A darker picture is the result.
*
* @name Phaser.BlendModes.MULTIPLY
* @type {number}
* @const
* @since 3.0.0
*/
MULTIPLY: 2,
/**
* Screen blend mode. For Canvas and WebGL.
* The pixels are inverted, multiplied, and inverted again. A lighter picture is the result (opposite of multiply)
*
* @name Phaser.BlendModes.SCREEN
* @type {number}
* @const
* @since 3.0.0
*/
SCREEN: 3,
/**
* Overlay blend mode. For Canvas only.
* A combination of multiply and screen. Dark parts on the base layer become darker, and light parts become lighter.
*
* @name Phaser.BlendModes.OVERLAY
* @type {number}
* @const
* @since 3.0.0
*/
OVERLAY: 4,
/**
* Darken blend mode. For Canvas only.
* Retains the darkest pixels of both layers.
*
* @name Phaser.BlendModes.DARKEN
* @type {number}
* @const
* @since 3.0.0
*/
DARKEN: 5,
/**
* Lighten blend mode. For Canvas only.
* Retains the lightest pixels of both layers.
*
* @name Phaser.BlendModes.LIGHTEN
* @type {number}
* @const
* @since 3.0.0
*/
LIGHTEN: 6,
/**
* Color Dodge blend mode. For Canvas only.
* Divides the bottom layer by the inverted top layer.
*
* @name Phaser.BlendModes.COLOR_DODGE
* @type {number}
* @const
* @since 3.0.0
*/
COLOR_DODGE: 7,
/**
* Color Burn blend mode. For Canvas only.
* Divides the inverted bottom layer by the top layer, and then inverts the result.
*
* @name Phaser.BlendModes.COLOR_BURN
* @type {number}
* @const
* @since 3.0.0
*/
COLOR_BURN: 8,
/**
* Hard Light blend mode. For Canvas only.
* A combination of multiply and screen like overlay, but with top and bottom layer swapped.
*
* @name Phaser.BlendModes.HARD_LIGHT
* @type {number}
* @const
* @since 3.0.0
*/
HARD_LIGHT: 9,
/**
* Soft Light blend mode. For Canvas only.
* A softer version of hard-light. Pure black or white does not result in pure black or white.
*
* @name Phaser.BlendModes.SOFT_LIGHT
* @type {number}
* @const
* @since 3.0.0
*/
SOFT_LIGHT: 10,
/**
* Difference blend mode. For Canvas only.
* Subtracts the bottom layer from the top layer or the other way round to always get a positive value.
*
* @name Phaser.BlendModes.DIFFERENCE
* @type {number}
* @const
* @since 3.0.0
*/
DIFFERENCE: 11,
/**
* Exclusion blend mode. For Canvas only.
* Like difference, but with lower contrast.
*
* @name Phaser.BlendModes.EXCLUSION
* @type {number}
* @const
* @since 3.0.0
*/
EXCLUSION: 12,
/**
* Hue blend mode. For Canvas only.
* Preserves the luma and chroma of the bottom layer, while adopting the hue of the top layer.
*
* @name Phaser.BlendModes.HUE
* @type {number}
* @const
* @since 3.0.0
*/
HUE: 13,
/**
* Saturation blend mode. For Canvas only.
* Preserves the luma and hue of the bottom layer, while adopting the chroma of the top layer.
*
* @name Phaser.BlendModes.SATURATION
* @type {number}
* @const
* @since 3.0.0
*/
SATURATION: 14,
/**
* Color blend mode. For Canvas only.
* Preserves the luma of the bottom layer, while adopting the hue and chroma of the top layer.
*
* @name Phaser.BlendModes.COLOR
* @type {number}
* @const
* @since 3.0.0
*/
COLOR: 15,
/**
* Luminosity blend mode. For Canvas only.
* Preserves the hue and chroma of the bottom layer, while adopting the luma of the top layer.
*
* @name Phaser.BlendModes.LUMINOSITY
* @type {number}
* @const
* @since 3.0.0
*/
LUMINOSITY: 16,
/**
* Alpha erase blend mode. For Canvas and WebGL.
*
* @name Phaser.BlendModes.ERASE
* @type {number}
* @const
* @since 3.0.0
*/
ERASE: 17,
/**
* Source-in blend mode. For Canvas only.
* The new shape is drawn only where both the new shape and the destination canvas overlap. Everything else is made transparent.
*
* @name Phaser.BlendModes.SOURCE_IN
* @type {number}
* @const
* @since 3.0.0
*/
SOURCE_IN: 18,
/**
* Source-out blend mode. For Canvas only.
* The new shape is drawn where it doesn't overlap the existing canvas content.
*
* @name Phaser.BlendModes.SOURCE_OUT
* @type {number}
* @const
* @since 3.0.0
*/
SOURCE_OUT: 19,
/**
* Source-out blend mode. For Canvas only.
* The new shape is only drawn where it overlaps the existing canvas content.
*
* @name Phaser.BlendModes.SOURCE_ATOP
* @type {number}
* @const
* @since 3.0.0
*/
SOURCE_ATOP: 20,
/**
* Destination-over blend mode. For Canvas only.
* New shapes are drawn behind the existing canvas content.
*
* @name Phaser.BlendModes.DESTINATION_OVER
* @type {number}
* @const
* @since 3.0.0
*/
DESTINATION_OVER: 21,
/**
* Destination-in blend mode. For Canvas only.
* The existing canvas content is kept where both the new shape and existing canvas content overlap. Everything else is made transparent.
*
* @name Phaser.BlendModes.DESTINATION_IN
* @type {number}
* @const
* @since 3.0.0
*/
DESTINATION_IN: 22,
/**
* Destination-out blend mode. For Canvas only.
* The existing content is kept where it doesn't overlap the new shape.
*
* @name Phaser.BlendModes.DESTINATION_OUT
* @type {number}
* @const
* @since 3.0.0
*/
DESTINATION_OUT: 23,
/**
* Destination-out blend mode. For Canvas only.
* The existing canvas is only kept where it overlaps the new shape. The new shape is drawn behind the canvas content.
*
* @name Phaser.BlendModes.DESTINATION_ATOP
* @type {number}
* @const
* @since 3.0.0
*/
DESTINATION_ATOP: 24,
/**
* Lighten blend mode. For Canvas only.
* Where both shapes overlap the color is determined by adding color values.
*
* @name Phaser.BlendModes.LIGHTER
* @type {number}
* @const
* @since 3.0.0
*/
LIGHTER: 25,
/**
* Copy blend mode. For Canvas only.
* Only the new shape is shown.
*
* @name Phaser.BlendModes.COPY
* @type {number}
* @const
* @since 3.0.0
*/
COPY: 26,
/**
* Xor blend mode. For Canvas only.
* Shapes are made transparent where both overlap and drawn normal everywhere else.
*
* @name Phaser.BlendModes.XOR
* @type {number}
* @const
* @since 3.0.0
*/
XOR: 27
};
}
),
/***/
29795: (
/***/
(module2) => {
var ScaleModes = {
/**
* Default Scale Mode (Linear).
*
* @name Phaser.ScaleModes.DEFAULT
* @type {number}
* @readonly
* @since 3.0.0
*/
DEFAULT: 0,
/**
* Linear Scale Mode.
*
* @name Phaser.ScaleModes.LINEAR
* @type {number}
* @readonly
* @since 3.0.0
*/
LINEAR: 0,
/**
* Nearest Scale Mode.
*
* @name Phaser.ScaleModes.NEAREST
* @type {number}
* @readonly
* @since 3.0.0
*/
NEAREST: 1
};
module2.exports = ScaleModes;
}
),
/***/
68627: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CameraEvents = __webpack_require__2(19715);
var CanvasSnapshot = __webpack_require__2(32880);
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(8054);
var EventEmitter = __webpack_require__2(50792);
var Events = __webpack_require__2(92503);
var GetBlendModes = __webpack_require__2(56373);
var ScaleEvents = __webpack_require__2(97480);
var TextureEvents = __webpack_require__2(69442);
var TransformMatrix = __webpack_require__2(61340);
var CanvasRenderer = new Class({
Extends: EventEmitter,
initialize: function CanvasRenderer2(game) {
EventEmitter.call(this);
var gameConfig = game.config;
this.config = {
clearBeforeRender: gameConfig.clearBeforeRender,
backgroundColor: gameConfig.backgroundColor,
antialias: gameConfig.antialias,
roundPixels: gameConfig.roundPixels
};
this.game = game;
this.type = CONST.CANVAS;
this.drawCount = 0;
this.width = 0;
this.height = 0;
this.gameCanvas = game.canvas;
var contextOptions = {
alpha: game.config.transparent,
desynchronized: game.config.desynchronized,
willReadFrequently: false
};
this.gameContext = gameConfig.context ? gameConfig.context : this.gameCanvas.getContext("2d", contextOptions);
this.currentContext = this.gameContext;
this.antialias = game.config.antialias;
this.blendModes = GetBlendModes();
this.snapshotState = {
x: 0,
y: 0,
width: 1,
height: 1,
getPixel: false,
callback: null,
type: "image/png",
encoder: 0.92
};
this._tempMatrix1 = new TransformMatrix();
this._tempMatrix2 = new TransformMatrix();
this._tempMatrix3 = new TransformMatrix();
this.isBooted = false;
this.init();
},
/**
* Prepares the game canvas for rendering.
*
* @method Phaser.Renderer.Canvas.CanvasRenderer#init
* @since 3.0.0
*/
init: function() {
this.game.textures.once(TextureEvents.READY, this.boot, this);
},
/**
* Internal boot handler.
*
* @method Phaser.Renderer.Canvas.CanvasRenderer#boot
* @private
* @since 3.50.0
*/
boot: function() {
var game = this.game;
var baseSize = game.scale.baseSize;
this.width = baseSize.width;
this.height = baseSize.height;
this.isBooted = true;
game.scale.on(ScaleEvents.RESIZE, this.onResize, this);
this.resize(baseSize.width, baseSize.height);
},
/**
* The event handler that manages the `resize` event dispatched by the Scale Manager.
*
* @method Phaser.Renderer.Canvas.CanvasRenderer#onResize
* @since 3.16.0
*
* @param {Phaser.Structs.Size} gameSize - The default Game Size object. This is the un-modified game dimensions.
* @param {Phaser.Structs.Size} baseSize - The base Size object. The game dimensions multiplied by the resolution. The canvas width / height values match this.
*/
onResize: function(gameSize, baseSize) {
if (baseSize.width !== this.width || baseSize.height !== this.height) {
this.resize(baseSize.width, baseSize.height);
}
},
/**
* Resize the main game canvas.
*
* @method Phaser.Renderer.Canvas.CanvasRenderer#resize
* @fires Phaser.Renderer.Events#RESIZE
* @since 3.0.0
*
* @param {number} [width] - The new width of the renderer.
* @param {number} [height] - The new height of the renderer.
*/
resize: function(width, height) {
this.width = width;
this.height = height;
this.emit(Events.RESIZE, width, height);
},
/**
* Resets the transformation matrix of the current context to the identity matrix, thus resetting any transformation.
*
* @method Phaser.Renderer.Canvas.CanvasRenderer#resetTransform
* @since 3.0.0
*/
resetTransform: function() {
this.currentContext.setTransform(1, 0, 0, 1, 0, 0);
},
/**
* Sets the blend mode (compositing operation) of the current context.
*
* @method Phaser.Renderer.Canvas.CanvasRenderer#setBlendMode
* @since 3.0.0
*
* @param {string} blendMode - The new blend mode which should be used.
*
* @return {this} This CanvasRenderer object.
*/
setBlendMode: function(blendMode) {
this.currentContext.globalCompositeOperation = blendMode;
return this;
},
/**
* Changes the Canvas Rendering Context that all draw operations are performed against.
*
* @method Phaser.Renderer.Canvas.CanvasRenderer#setContext
* @since 3.12.0
*
* @param {?CanvasRenderingContext2D} [ctx] - The new Canvas Rendering Context to draw everything to. Leave empty to reset to the Game Canvas.
*
* @return {this} The Canvas Renderer instance.
*/
setContext: function(ctx) {
this.currentContext = ctx ? ctx : this.gameContext;
return this;
},
/**
* Sets the global alpha of the current context.
*
* @method Phaser.Renderer.Canvas.CanvasRenderer#setAlpha
* @since 3.0.0
*
* @param {number} alpha - The new alpha to use, where 0 is fully transparent and 1 is fully opaque.
*
* @return {this} This CanvasRenderer object.
*/
setAlpha: function(alpha) {
this.currentContext.globalAlpha = alpha;
return this;
},
/**
* Called at the start of the render loop.
*
* @method Phaser.Renderer.Canvas.CanvasRenderer#preRender
* @fires Phaser.Renderer.Events#PRE_RENDER_CLEAR
* @fires Phaser.Renderer.Events#PRE_RENDER
* @since 3.0.0
*/
preRender: function() {
var ctx = this.gameContext;
var config = this.config;
var width = this.width;
var height = this.height;
ctx.globalAlpha = 1;
ctx.globalCompositeOperation = "source-over";
ctx.setTransform(1, 0, 0, 1, 0, 0);
this.emit(Events.PRE_RENDER_CLEAR);
if (config.clearBeforeRender) {
ctx.clearRect(0, 0, width, height);
if (!config.transparent) {
ctx.fillStyle = config.backgroundColor.rgba;
ctx.fillRect(0, 0, width, height);
}
}
ctx.save();
this.drawCount = 0;
this.emit(Events.PRE_RENDER);
},
/**
* The core render step for a Scene Camera.
*
* Iterates through the given array of Game Objects and renders them with the given Camera.
*
* This is called by the `CameraManager.render` method. The Camera Manager instance belongs to a Scene, and is invoked
* by the Scene Systems.render method.
*
* This method is not called if `Camera.visible` is `false`, or `Camera.alpha` is zero.
*
* @method Phaser.Renderer.Canvas.CanvasRenderer#render
* @fires Phaser.Renderer.Events#RENDER
* @since 3.0.0
*
* @param {Phaser.Scene} scene - The Scene to render.
* @param {Phaser.GameObjects.GameObject[]} children - An array of filtered Game Objects that can be rendered by the given Camera.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Scene Camera to render with.
*/
render: function(scene, children, camera) {
var childCount = children.length;
this.emit(Events.RENDER, scene, camera);
var cx = camera.x;
var cy = camera.y;
var cw = camera.width;
var ch = camera.height;
var ctx = camera.renderToTexture ? camera.context : scene.sys.context;
ctx.save();
if (this.game.scene.customViewports) {
ctx.beginPath();
ctx.rect(cx, cy, cw, ch);
ctx.clip();
}
camera.emit(CameraEvents.PRE_RENDER, camera);
this.currentContext = ctx;
var mask = camera.mask;
if (mask) {
mask.preRenderCanvas(this, null, camera._maskCamera);
}
if (!camera.transparent) {
ctx.fillStyle = camera.backgroundColor.rgba;
ctx.fillRect(cx, cy, cw, ch);
}
ctx.globalAlpha = camera.alpha;
ctx.globalCompositeOperation = "source-over";
this.drawCount += childCount;
if (camera.renderToTexture) {
camera.emit(CameraEvents.PRE_RENDER, camera);
}
camera.matrix.copyToContext(ctx);
for (var i = 0; i < childCount; i++) {
var child = children[i];
if (child.mask) {
child.mask.preRenderCanvas(this, child, camera);
}
child.renderCanvas(this, child, camera);
if (child.mask) {
child.mask.postRenderCanvas(this, child, camera);
}
}
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.globalCompositeOperation = "source-over";
ctx.globalAlpha = 1;
camera.flashEffect.postRenderCanvas(ctx);
camera.fadeEffect.postRenderCanvas(ctx);
camera.dirty = false;
if (mask) {
mask.postRenderCanvas(this);
}
ctx.restore();
if (camera.renderToTexture) {
camera.emit(CameraEvents.POST_RENDER, camera);
if (camera.renderToGame) {
scene.sys.context.drawImage(camera.canvas, cx, cy);
}
}
camera.emit(CameraEvents.POST_RENDER, camera);
},
/**
* Restores the game context's global settings and takes a snapshot if one is scheduled.
*
* The post-render step happens after all Cameras in all Scenes have been rendered.
*
* @method Phaser.Renderer.Canvas.CanvasRenderer#postRender
* @fires Phaser.Renderer.Events#POST_RENDER
* @since 3.0.0
*/
postRender: function() {
var ctx = this.gameContext;
ctx.restore();
this.emit(Events.POST_RENDER);
var state = this.snapshotState;
if (state.callback) {
CanvasSnapshot(this.gameCanvas, state);
state.callback = null;
}
},
/**
* Takes a snapshot of the given area of the given canvas.
*
* Unlike the other snapshot methods, this one is processed immediately and doesn't wait for the next render.
*
* Snapshots work by creating an Image object from the canvas data, this is a blocking process, which gets
* more expensive the larger the canvas size gets, so please be careful how you employ this in your game.
*
* @method Phaser.Renderer.Canvas.CanvasRenderer#snapshotCanvas
* @since 3.19.0
*
* @param {HTMLCanvasElement} canvas - The canvas to grab from.
* @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created.
* @param {boolean} [getPixel=false] - Grab a single pixel as a Color object, or an area as an Image object?
* @param {number} [x=0] - The x coordinate to grab from.
* @param {number} [y=0] - The y coordinate to grab from.
* @param {number} [width=canvas.width] - The width of the area to grab.
* @param {number} [height=canvas.height] - The height of the area to grab.
* @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`.
* @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`.
*
* @return {this} This Canvas Renderer.
*/
snapshotCanvas: function(canvas, callback, getPixel, x, y, width, height, type, encoderOptions) {
if (getPixel === void 0) {
getPixel = false;
}
this.snapshotArea(x, y, width, height, callback, type, encoderOptions);
var state = this.snapshotState;
state.getPixel = getPixel;
CanvasSnapshot(canvas, state);
state.callback = null;
return this;
},
/**
* Schedules a snapshot of the entire game viewport to be taken after the current frame is rendered.
*
* To capture a specific area see the `snapshotArea` method. To capture a specific pixel, see `snapshotPixel`.
*
* Only one snapshot can be active _per frame_. If you have already called `snapshotPixel`, for example, then
* calling this method will override it.
*
* Snapshots work by creating an Image object from the canvas data, this is a blocking process, which gets
* more expensive the larger the canvas size gets, so please be careful how you employ this in your game.
*
* @method Phaser.Renderer.Canvas.CanvasRenderer#snapshot
* @since 3.0.0
*
* @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created.
* @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`.
* @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`.
*
* @return {this} This WebGL Renderer.
*/
snapshot: function(callback, type, encoderOptions) {
return this.snapshotArea(0, 0, this.gameCanvas.width, this.gameCanvas.height, callback, type, encoderOptions);
},
/**
* Schedules a snapshot of the given area of the game viewport to be taken after the current frame is rendered.
*
* To capture the whole game viewport see the `snapshot` method. To capture a specific pixel, see `snapshotPixel`.
*
* Only one snapshot can be active _per frame_. If you have already called `snapshotPixel`, for example, then
* calling this method will override it.
*
* Snapshots work by creating an Image object from the canvas data, this is a blocking process, which gets
* more expensive the larger the canvas size gets, so please be careful how you employ this in your game.
*
* @method Phaser.Renderer.Canvas.CanvasRenderer#snapshotArea
* @since 3.16.0
*
* @param {number} x - The x coordinate to grab from.
* @param {number} y - The y coordinate to grab from.
* @param {number} width - The width of the area to grab.
* @param {number} height - The height of the area to grab.
* @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created.
* @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`.
* @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`.
*
* @return {this} This WebGL Renderer.
*/
snapshotArea: function(x, y, width, height, callback, type, encoderOptions) {
var state = this.snapshotState;
state.callback = callback;
state.type = type;
state.encoder = encoderOptions;
state.getPixel = false;
state.x = x;
state.y = y;
state.width = Math.min(width, this.gameCanvas.width);
state.height = Math.min(height, this.gameCanvas.height);
return this;
},
/**
* Schedules a snapshot of the given pixel from the game viewport to be taken after the current frame is rendered.
*
* To capture the whole game viewport see the `snapshot` method. To capture a specific area, see `snapshotArea`.
*
* Only one snapshot can be active _per frame_. If you have already called `snapshotArea`, for example, then
* calling this method will override it.
*
* Unlike the other two snapshot methods, this one will return a `Color` object containing the color data for
* the requested pixel. It doesn't need to create an internal Canvas or Image object, so is a lot faster to execute,
* using less memory.
*
* @method Phaser.Renderer.Canvas.CanvasRenderer#snapshotPixel
* @since 3.16.0
*
* @param {number} x - The x coordinate of the pixel to get.
* @param {number} y - The y coordinate of the pixel to get.
* @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot pixel data is extracted.
*
* @return {this} This WebGL Renderer.
*/
snapshotPixel: function(x, y, callback) {
this.snapshotArea(x, y, 1, 1, callback);
this.snapshotState.getPixel = true;
return this;
},
/**
* Takes a Sprite Game Object, or any object that extends it, and draws it to the current context.
*
* @method Phaser.Renderer.Canvas.CanvasRenderer#batchSprite
* @since 3.12.0
*
* @param {Phaser.GameObjects.GameObject} sprite - The texture based Game Object to draw.
* @param {Phaser.Textures.Frame} frame - The frame to draw, doesn't have to be that owned by the Game Object.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use for the rendering transform.
* @param {Phaser.GameObjects.Components.TransformMatrix} [parentTransformMatrix] - The transform matrix of the parent container, if set.
*/
batchSprite: function(sprite, frame, camera, parentTransformMatrix) {
var alpha = camera.alpha * sprite.alpha;
if (alpha === 0) {
return;
}
var ctx = this.currentContext;
var camMatrix = this._tempMatrix1;
var spriteMatrix = this._tempMatrix2;
var cd = frame.canvasData;
var frameX = cd.x;
var frameY = cd.y;
var frameWidth = frame.cutWidth;
var frameHeight = frame.cutHeight;
var customPivot = frame.customPivot;
var res = frame.source.resolution;
var displayOriginX = sprite.displayOriginX;
var displayOriginY = sprite.displayOriginY;
var x = -displayOriginX + frame.x;
var y = -displayOriginY + frame.y;
if (sprite.isCropped) {
var crop = sprite._crop;
if (crop.flipX !== sprite.flipX || crop.flipY !== sprite.flipY) {
frame.updateCropUVs(crop, sprite.flipX, sprite.flipY);
}
frameWidth = crop.cw;
frameHeight = crop.ch;
frameX = crop.cx;
frameY = crop.cy;
x = -displayOriginX + crop.x;
y = -displayOriginY + crop.y;
if (sprite.flipX) {
if (x >= 0) {
x = -(x + frameWidth);
} else if (x < 0) {
x = Math.abs(x) - frameWidth;
}
}
if (sprite.flipY) {
if (y >= 0) {
y = -(y + frameHeight);
} else if (y < 0) {
y = Math.abs(y) - frameHeight;
}
}
}
var flipX = 1;
var flipY = 1;
if (sprite.flipX) {
if (!customPivot) {
x += -frame.realWidth + displayOriginX * 2;
}
flipX = -1;
}
if (sprite.flipY) {
if (!customPivot) {
y += -frame.realHeight + displayOriginY * 2;
}
flipY = -1;
}
var gx = sprite.x;
var gy = sprite.y;
if (camera.roundPixels) {
gx = Math.floor(gx);
gy = Math.floor(gy);
}
spriteMatrix.applyITRS(gx, gy, sprite.rotation, sprite.scaleX * flipX, sprite.scaleY * flipY);
camMatrix.copyFrom(camera.matrix);
if (parentTransformMatrix) {
camMatrix.multiplyWithOffset(parentTransformMatrix, -camera.scrollX * sprite.scrollFactorX, -camera.scrollY * sprite.scrollFactorY);
spriteMatrix.e = gx;
spriteMatrix.f = gy;
} else {
spriteMatrix.e -= camera.scrollX * sprite.scrollFactorX;
spriteMatrix.f -= camera.scrollY * sprite.scrollFactorY;
}
camMatrix.multiply(spriteMatrix);
if (camera.renderRoundPixels) {
camMatrix.e = Math.floor(camMatrix.e + 0.5);
camMatrix.f = Math.floor(camMatrix.f + 0.5);
}
ctx.save();
camMatrix.setToContext(ctx);
ctx.globalCompositeOperation = this.blendModes[sprite.blendMode];
ctx.globalAlpha = alpha;
ctx.imageSmoothingEnabled = !frame.source.scaleMode;
if (sprite.mask) {
sprite.mask.preRenderCanvas(this, sprite, camera);
}
if (frameWidth > 0 && frameHeight > 0) {
var fw = frameWidth / res;
var fh = frameHeight / res;
if (camera.roundPixels) {
x = Math.floor(x + 0.5);
y = Math.floor(y + 0.5);
fw += 0.5;
fh += 0.5;
}
ctx.drawImage(
frame.source.image,
frameX,
frameY,
frameWidth,
frameHeight,
x,
y,
fw,
fh
);
}
if (sprite.mask) {
sprite.mask.postRenderCanvas(this, sprite, camera);
}
ctx.restore();
},
/**
* Destroys all object references in the Canvas Renderer.
*
* @method Phaser.Renderer.Canvas.CanvasRenderer#destroy
* @since 3.0.0
*/
destroy: function() {
this.removeAllListeners();
this.game = null;
this.gameCanvas = null;
this.gameContext = null;
}
});
module2.exports = CanvasRenderer;
}
),
/***/
55830: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
CanvasRenderer: __webpack_require__2(68627),
GetBlendModes: __webpack_require__2(56373),
SetTransform: __webpack_require__2(20926)
};
}
),
/***/
56373: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var modes = __webpack_require__2(10312);
var CanvasFeatures = __webpack_require__2(89289);
var GetBlendModes = function() {
var output = [];
var useNew = CanvasFeatures.supportNewBlendModes;
var so = "source-over";
output[modes.NORMAL] = so;
output[modes.ADD] = "lighter";
output[modes.MULTIPLY] = useNew ? "multiply" : so;
output[modes.SCREEN] = useNew ? "screen" : so;
output[modes.OVERLAY] = useNew ? "overlay" : so;
output[modes.DARKEN] = useNew ? "darken" : so;
output[modes.LIGHTEN] = useNew ? "lighten" : so;
output[modes.COLOR_DODGE] = useNew ? "color-dodge" : so;
output[modes.COLOR_BURN] = useNew ? "color-burn" : so;
output[modes.HARD_LIGHT] = useNew ? "hard-light" : so;
output[modes.SOFT_LIGHT] = useNew ? "soft-light" : so;
output[modes.DIFFERENCE] = useNew ? "difference" : so;
output[modes.EXCLUSION] = useNew ? "exclusion" : so;
output[modes.HUE] = useNew ? "hue" : so;
output[modes.SATURATION] = useNew ? "saturation" : so;
output[modes.COLOR] = useNew ? "color" : so;
output[modes.LUMINOSITY] = useNew ? "luminosity" : so;
output[modes.ERASE] = "destination-out";
output[modes.SOURCE_IN] = "source-in";
output[modes.SOURCE_OUT] = "source-out";
output[modes.SOURCE_ATOP] = "source-atop";
output[modes.DESTINATION_OVER] = "destination-over";
output[modes.DESTINATION_IN] = "destination-in";
output[modes.DESTINATION_OUT] = "destination-out";
output[modes.DESTINATION_ATOP] = "destination-atop";
output[modes.LIGHTER] = "lighter";
output[modes.COPY] = "copy";
output[modes.XOR] = "xor";
return output;
};
module2.exports = GetBlendModes;
}
),
/***/
20926: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetCalcMatrix = __webpack_require__2(91296);
var SetTransform = function(renderer, ctx, src, camera, parentMatrix) {
var alpha = camera.alpha * src.alpha;
if (alpha <= 0) {
return false;
}
var calcMatrix = GetCalcMatrix(src, camera, parentMatrix).calc;
ctx.globalCompositeOperation = renderer.blendModes[src.blendMode];
ctx.globalAlpha = alpha;
ctx.save();
calcMatrix.setToContext(ctx);
ctx.imageSmoothingEnabled = src.frame ? !src.frame.source.scaleMode : renderer.antialias;
return true;
};
module2.exports = SetTransform;
}
),
/***/
63899: (
/***/
(module2) => {
module2.exports = "losewebgl";
}
),
/***/
6119: (
/***/
(module2) => {
module2.exports = "postrender";
}
),
/***/
48070: (
/***/
(module2) => {
module2.exports = "prerender";
}
),
/***/
15640: (
/***/
(module2) => {
module2.exports = "render";
}
),
/***/
8912: (
/***/
(module2) => {
module2.exports = "resize";
}
),
/***/
87124: (
/***/
(module2) => {
module2.exports = "restorewebgl";
}
),
/***/
92503: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
LOSE_WEBGL: __webpack_require__2(63899),
POST_RENDER: __webpack_require__2(6119),
PRE_RENDER: __webpack_require__2(48070),
RENDER: __webpack_require__2(15640),
RESIZE: __webpack_require__2(8912),
RESTORE_WEBGL: __webpack_require__2(87124)
};
}
),
/***/
36909: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Events: __webpack_require__2(92503),
Snapshot: __webpack_require__2(89966)
};
if (true) {
module2.exports.Canvas = __webpack_require__2(55830);
}
if (true) {
module2.exports.WebGL = __webpack_require__2(4159);
}
}
),
/***/
32880: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CanvasPool = __webpack_require__2(27919);
var Color = __webpack_require__2(40987);
var GetFastValue = __webpack_require__2(95540);
var CanvasSnapshot = function(canvas, config) {
var callback = GetFastValue(config, "callback");
var type = GetFastValue(config, "type", "image/png");
var encoderOptions = GetFastValue(config, "encoder", 0.92);
var x = Math.abs(Math.round(GetFastValue(config, "x", 0)));
var y = Math.abs(Math.round(GetFastValue(config, "y", 0)));
var width = Math.floor(GetFastValue(config, "width", canvas.width));
var height = Math.floor(GetFastValue(config, "height", canvas.height));
var getPixel = GetFastValue(config, "getPixel", false);
if (getPixel) {
var context = canvas.getContext("2d", { willReadFrequently: false });
var imageData = context.getImageData(x, y, 1, 1);
var data = imageData.data;
callback.call(null, new Color(data[0], data[1], data[2], data[3]));
} else if (x !== 0 || y !== 0 || width !== canvas.width || height !== canvas.height) {
var copyCanvas = CanvasPool.createWebGL(this, width, height);
var ctx = copyCanvas.getContext("2d", { willReadFrequently: true });
if (width > 0 && height > 0) {
ctx.drawImage(canvas, x, y, width, height, 0, 0, width, height);
}
var image1 = new Image();
image1.onerror = function() {
callback.call(null);
CanvasPool.remove(copyCanvas);
};
image1.onload = function() {
callback.call(null, image1);
CanvasPool.remove(copyCanvas);
};
image1.src = copyCanvas.toDataURL(type, encoderOptions);
} else {
var image2 = new Image();
image2.onerror = function() {
callback.call(null);
};
image2.onload = function() {
callback.call(null, image2);
};
image2.src = canvas.toDataURL(type, encoderOptions);
}
};
module2.exports = CanvasSnapshot;
}
),
/***/
88815: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CanvasPool = __webpack_require__2(27919);
var Color = __webpack_require__2(40987);
var GetFastValue = __webpack_require__2(95540);
var WebGLSnapshot = function(sourceContext, config) {
var gl = sourceContext;
var callback = GetFastValue(config, "callback");
var type = GetFastValue(config, "type", "image/png");
var encoderOptions = GetFastValue(config, "encoder", 0.92);
var x = Math.abs(Math.round(GetFastValue(config, "x", 0)));
var y = Math.abs(Math.round(GetFastValue(config, "y", 0)));
var getPixel = GetFastValue(config, "getPixel", false);
var isFramebuffer = GetFastValue(config, "isFramebuffer", false);
var bufferWidth = isFramebuffer ? GetFastValue(config, "bufferWidth", 1) : gl.drawingBufferWidth;
var bufferHeight = isFramebuffer ? GetFastValue(config, "bufferHeight", 1) : gl.drawingBufferHeight;
if (getPixel) {
var pixel = new Uint8Array(4);
var destY = isFramebuffer ? y : bufferHeight - y;
gl.readPixels(x, destY, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel);
callback.call(null, new Color(pixel[0], pixel[1], pixel[2], pixel[3]));
} else {
var width = Math.floor(GetFastValue(config, "width", bufferWidth));
var height = Math.floor(GetFastValue(config, "height", bufferHeight));
var total = width * height * 4;
var pixels = new Uint8Array(total);
gl.readPixels(x, bufferHeight - y - height, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
var canvas = CanvasPool.createWebGL(this, width, height);
var ctx = canvas.getContext("2d", { willReadFrequently: true });
var imageData = ctx.getImageData(0, 0, width, height);
var data = imageData.data;
for (var py = 0; py < height; py++) {
for (var px = 0; px < width; px++) {
var sourceIndex = ((height - py - 1) * width + px) * 4;
var destIndex = isFramebuffer ? total - (py * width + (width - px)) * 4 : (py * width + px) * 4;
data[destIndex + 0] = pixels[sourceIndex + 0];
data[destIndex + 1] = pixels[sourceIndex + 1];
data[destIndex + 2] = pixels[sourceIndex + 2];
data[destIndex + 3] = pixels[sourceIndex + 3];
}
}
ctx.putImageData(imageData, 0, 0);
var image = new Image();
image.onerror = function() {
callback.call(null);
CanvasPool.remove(canvas);
};
image.onload = function() {
callback.call(null, image);
CanvasPool.remove(canvas);
};
image.src = canvas.toDataURL(type, encoderOptions);
}
};
module2.exports = WebGLSnapshot;
}
),
/***/
89966: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Canvas: __webpack_require__2(32880),
WebGL: __webpack_require__2(88815)
};
}
),
/***/
7530: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(36060);
var CustomMap = __webpack_require__2(90330);
var Device = __webpack_require__2(82264);
var GetFastValue = __webpack_require__2(95540);
var RenderTarget = __webpack_require__2(32302);
var SnapCeil = __webpack_require__2(63448);
var BitmapMaskPipeline = __webpack_require__2(31302);
var FX = __webpack_require__2(58918);
var FX_CONST = __webpack_require__2(14811);
var FXPipeline = __webpack_require__2(92651);
var LightPipeline = __webpack_require__2(96569);
var MobilePipeline = __webpack_require__2(56527);
var MultiPipeline = __webpack_require__2(57516);
var PointLightPipeline = __webpack_require__2(43439);
var RopePipeline = __webpack_require__2(81041);
var SinglePipeline = __webpack_require__2(12385);
var UtilityPipeline = __webpack_require__2(7589);
var ArrayEach = __webpack_require__2(95428);
var ArrayRemove = __webpack_require__2(72905);
var PipelineManager = new Class({
initialize: function PipelineManager2(renderer) {
this.game = renderer.game;
this.renderer = renderer;
this.classes = new CustomMap([
[CONST.UTILITY_PIPELINE, UtilityPipeline],
[CONST.MULTI_PIPELINE, MultiPipeline],
[CONST.BITMAPMASK_PIPELINE, BitmapMaskPipeline],
[CONST.SINGLE_PIPELINE, SinglePipeline],
[CONST.ROPE_PIPELINE, RopePipeline],
[CONST.LIGHT_PIPELINE, LightPipeline],
[CONST.POINTLIGHT_PIPELINE, PointLightPipeline],
[CONST.MOBILE_PIPELINE, MobilePipeline]
]);
this.postPipelineClasses = new CustomMap();
this.pipelines = new CustomMap();
this.postPipelineInstances = [];
this.default = null;
this.current = null;
this.previous = null;
this.MULTI_PIPELINE = null;
this.BITMAPMASK_PIPELINE = null;
this.UTILITY_PIPELINE = null;
this.MOBILE_PIPELINE = null;
this.FX_PIPELINE = null;
this.fullFrame1;
this.fullFrame2;
this.halfFrame1;
this.halfFrame2;
this.renderTargets = [];
this.maxDimension = 0;
this.frameInc = 32;
this.targetIndex = 0;
},
/**
* Internal boot handler, called by the WebGLRenderer durings its boot process.
*
* Adds all of the default pipelines, based on the game config, and then calls
* the `boot` method on each one of them.
*
* Finally, the default pipeline is set.
*
* @method Phaser.Renderer.WebGL.PipelineManager#boot
* @since 3.50.0
*
* @param {Phaser.Types.Core.PipelineConfig} pipelineConfig - The pipeline configuration object as set in the Game Config.
* @param {string} defaultPipeline - The name of the default Game Object pipeline, as set in the Game Config
* @param {boolean} autoMobilePipeline - Automatically set the default pipeline to mobile if non-desktop detected?
*/
boot: function(pipelineConfig, defaultPipeline, autoMobilePipeline) {
var renderer = this.renderer;
var targets = this.renderTargets;
this.frameInc = Math.floor(GetFastValue(pipelineConfig, "frameInc", 32));
var renderWidth = renderer.width;
var renderHeight = renderer.height;
var disablePreFX = this.game.config.disablePreFX;
var disablePostFX = this.game.config.disablePostFX;
if (!disablePostFX) {
this.postPipelineClasses.setAll([
[String(FX_CONST.BARREL), FX.Barrel],
[String(FX_CONST.BLOOM), FX.Bloom],
[String(FX_CONST.BLUR), FX.Blur],
[String(FX_CONST.BOKEH), FX.Bokeh],
[String(FX_CONST.CIRCLE), FX.Circle],
[String(FX_CONST.COLOR_MATRIX), FX.ColorMatrix],
[String(FX_CONST.DISPLACEMENT), FX.Displacement],
[String(FX_CONST.GLOW), FX.Glow],
[String(FX_CONST.GRADIENT), FX.Gradient],
[String(FX_CONST.PIXELATE), FX.Pixelate],
[String(FX_CONST.SHADOW), FX.Shadow],
[String(FX_CONST.SHINE), FX.Shine],
[String(FX_CONST.VIGNETTE), FX.Vignette],
[String(FX_CONST.WIPE), FX.Wipe]
]);
}
if (!disablePreFX) {
this.classes.set(CONST.FX_PIPELINE, FXPipeline);
var minDimension = Math.min(renderWidth, renderHeight);
var qty = Math.ceil(minDimension / this.frameInc);
for (var i = 1; i < qty; i++) {
var targetWidth = i * this.frameInc;
targets.push(new RenderTarget(renderer, targetWidth, targetWidth));
targets.push(new RenderTarget(renderer, targetWidth, targetWidth));
targets.push(new RenderTarget(renderer, targetWidth, targetWidth));
this.maxDimension = targetWidth;
}
targets.push(new RenderTarget(renderer, renderWidth, renderHeight, 1, 0, true, true));
targets.push(new RenderTarget(renderer, renderWidth, renderHeight, 1, 0, true, true));
targets.push(new RenderTarget(renderer, renderWidth, renderHeight, 1, 0, true, true));
}
var instance;
var pipelineName;
var _this = this;
var game = this.game;
this.classes.each(function(pipelineName2, pipeline) {
instance = _this.add(pipelineName2, new pipeline({ game }));
if (pipelineName2 === CONST.UTILITY_PIPELINE) {
_this.UTILITY_PIPELINE = instance;
_this.fullFrame1 = instance.fullFrame1;
_this.fullFrame2 = instance.fullFrame2;
_this.halfFrame1 = instance.halfFrame1;
_this.halfFrame2 = instance.halfFrame2;
}
});
this.MULTI_PIPELINE = this.get(CONST.MULTI_PIPELINE);
this.BITMAPMASK_PIPELINE = this.get(CONST.BITMAPMASK_PIPELINE);
this.MOBILE_PIPELINE = this.get(CONST.MOBILE_PIPELINE);
if (!disablePreFX) {
this.FX_PIPELINE = this.get(CONST.FX_PIPELINE);
}
if (pipelineConfig) {
for (pipelineName in pipelineConfig) {
var pipelineClass = pipelineConfig[pipelineName];
instance = new pipelineClass(game);
instance.name = pipelineName;
if (instance.isPostFX) {
this.postPipelineClasses.set(pipelineName, pipelineClass);
} else if (!this.has(pipelineName)) {
this.classes.set(pipelineName, pipelineClass);
this.add(pipelineName, instance);
}
}
}
this.default = this.get(defaultPipeline);
if (autoMobilePipeline && !Device.os.desktop) {
this.default = this.MOBILE_PIPELINE;
}
},
/**
* Sets the default pipeline being used by Game Objects.
*
* If no instance, or matching name, exists in this manager, it returns `undefined`.
*
* You can use this to override the default pipeline, for example by forcing
* the Mobile or Multi Tint Pipelines, which is especially useful for development
* testing.
*
* Make sure you call this method _before_ creating any Game Objects, as it will
* only impact Game Objects created after you call it.
*
* @method Phaser.Renderer.WebGL.PipelineManager#setDefaultPipeline
* @since 3.60.0
*
* @param {(string|Phaser.Renderer.WebGL.WebGLPipeline)} pipeline - Either the string-based name of the pipeline to get, or a pipeline instance to look-up.
*
* @return {Phaser.Renderer.WebGL.WebGLPipeline} The pipeline instance that was set as default, or `undefined` if not found.
*/
setDefaultPipeline: function(pipeline) {
var instance = this.get(pipeline);
if (instance) {
this.default = instance;
}
return instance;
},
/**
* Adds a pipeline instance to this Pipeline Manager.
*
* The name of the instance must be unique within this manager.
*
* Make sure to pass an instance to this method, not a base class.
*
* For example, you should pass it like this:
*
* ```javascript
* this.add('yourName', new CustomPipeline(game));`
* ```
*
* and **not** like this:
*
* ```javascript
* this.add('yourName', CustomPipeline);`
* ```
*
* To add a **Post Pipeline**, see `addPostPipeline` instead.
*
* @method Phaser.Renderer.WebGL.PipelineManager#add
* @since 3.50.0
*
* @param {string} name - A unique string-based key for the pipeline within the manager.
* @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - A pipeline _instance_ which must extend `WebGLPipeline`.
*
* @return {Phaser.Renderer.WebGL.WebGLPipeline} The pipeline instance that was passed.
*/
add: function(name, pipeline) {
if (pipeline.isPostFX) {
console.warn(name + " is a Post Pipeline. Use `addPostPipeline` instead");
return;
}
var pipelines = this.pipelines;
var renderer = this.renderer;
if (!pipelines.has(name)) {
pipeline.name = name;
pipeline.manager = this;
pipelines.set(name, pipeline);
} else {
console.warn("Pipeline exists: " + name);
}
if (!pipeline.hasBooted) {
pipeline.boot();
}
if (renderer.width !== 0 && renderer.height !== 0 && !pipeline.isPreFX) {
pipeline.resize(renderer.width, renderer.height);
}
return pipeline;
},
/**
* Adds a Post Pipeline to this Pipeline Manager.
*
* Make sure to pass a base class to this method, not an instance.
*
* For example, you should pass it like this:
*
* ```javascript
* this.addPostPipeline('yourName', CustomPipeline);`
* ```
*
* and **not** like this:
*
* ```javascript
* this.addPostPipeline('yourName', new CustomPipeline());`
* ```
*
* To add a regular pipeline, see the `add` method instead.
*
* @method Phaser.Renderer.WebGL.PipelineManager#addPostPipeline
* @since 3.50.0
*
* @param {string} name - A unique string-based key for the pipeline within the manager.
* @param {function} pipeline - A pipeline class which must extend `PostFXPipeline`.
*
* @return {this} This Pipeline Manager.
*/
addPostPipeline: function(name, pipeline) {
if (!this.postPipelineClasses.has(name)) {
this.postPipelineClasses.set(name, pipeline);
}
},
/**
* Flushes the current pipeline, if one is bound.
*
* @method Phaser.Renderer.WebGL.PipelineManager#flush
* @since 3.50.0
*/
flush: function() {
if (this.current) {
this.current.flush();
}
},
/**
* Checks if a pipeline is present in this Pipeline Manager.
*
* @method Phaser.Renderer.WebGL.PipelineManager#has
* @since 3.50.0
*
* @param {(string|Phaser.Renderer.WebGL.WebGLPipeline)} pipeline - Either the string-based name of the pipeline to get, or a pipeline instance to look-up.
*
* @return {boolean} `true` if the given pipeline is loaded, otherwise `false`.
*/
has: function(pipeline) {
var pipelines = this.pipelines;
if (typeof pipeline === "string") {
return pipelines.has(pipeline);
} else if (pipelines.contains(pipeline)) {
return true;
}
return false;
},
/**
* Returns the pipeline instance based on the given name, or instance.
*
* If no instance, or matching name, exists in this manager, it returns `undefined`.
*
* @method Phaser.Renderer.WebGL.PipelineManager#get
* @since 3.50.0
*
* @param {(string|Phaser.Renderer.WebGL.WebGLPipeline)} pipeline - Either the string-based name of the pipeline to get, or a pipeline instance to look-up.
*
* @return {Phaser.Renderer.WebGL.WebGLPipeline} The pipeline instance, or `undefined` if not found.
*/
get: function(pipeline) {
var pipelines = this.pipelines;
if (typeof pipeline === "string") {
return pipelines.get(pipeline);
} else if (pipelines.contains(pipeline)) {
return pipeline;
}
},
/**
* Returns a _new instance_ of the post pipeline based on the given name, or class.
*
* If no instance, or matching name, exists in this manager, it returns `undefined`.
*
* @method Phaser.Renderer.WebGL.PipelineManager#getPostPipeline
* @since 3.50.0
*
* @param {(string|function|Phaser.Renderer.WebGL.Pipelines.PostFXPipeline)} pipeline - Either the string-based name of the pipeline to get, or a pipeline instance, or class to look-up.
* @param {Phaser.GameObjects.GameObject} [gameObject] - If this post pipeline is being installed into a Game Object or Camera, this is a reference to it.
* @param {object} [config] - Optional pipeline data object that is set in to the `postPipelineData` property of this Game Object.
*
* @return {Phaser.Renderer.WebGL.Pipelines.PostFXPipeline} The pipeline instance, or `undefined` if not found.
*/
getPostPipeline: function(pipeline, gameObject, config) {
var pipelineClasses = this.postPipelineClasses;
var instance;
var pipelineName = "";
var pipetype = typeof pipeline;
if (pipetype === "string" || pipetype === "number") {
instance = pipelineClasses.get(pipeline);
pipelineName = pipeline;
} else if (pipetype === "function") {
if (pipelineClasses.contains(pipeline)) {
instance = pipeline;
}
pipelineName = pipeline.name;
} else if (pipetype === "object") {
instance = pipelineClasses.get(pipeline.name);
pipelineName = pipeline.name;
}
if (instance) {
var newPipeline = new instance(this.game, config);
newPipeline.name = pipelineName;
if (gameObject) {
newPipeline.gameObject = gameObject;
}
this.postPipelineInstances.push(newPipeline);
return newPipeline;
}
},
/**
* Removes a PostFXPipeline instance from this Pipeline Manager.
*
* Note that the pipeline will not be flushed or destroyed, it's simply removed from
* this manager.
*
* @method Phaser.Renderer.WebGL.PipelineManager#removePostPipeline
* @since 3.80.0
*
* @param {Phaser.Renderer.WebGL.Pipelines.PostFXPipeline} pipeline - The pipeline instance to be removed.
*/
removePostPipeline: function(pipeline) {
ArrayRemove(this.postPipelineInstances, pipeline);
},
/**
* Removes a pipeline instance based on the given name.
*
* If no pipeline matches the name, this method does nothing.
*
* Note that the pipeline will not be flushed or destroyed, it's simply removed from
* this manager.
*
* @method Phaser.Renderer.WebGL.PipelineManager#remove
* @since 3.50.0
*
* @param {string} name - The name of the pipeline to be removed.
* @param {boolean} [removeClass=true] - Remove the pipeline class as well as the instance?
* @param {boolean} [removePostPipelineClass=true] - Remove the post pipeline class as well as the instance?
*/
remove: function(name, removeClass, removePostPipelineClass) {
if (removeClass === void 0) {
removeClass = true;
}
if (removePostPipelineClass === void 0) {
removePostPipelineClass = true;
}
this.pipelines.delete(name);
if (removeClass) {
this.classes.delete(name);
}
if (removePostPipelineClass) {
this.postPipelineClasses.delete(name);
}
},
/**
* Sets the current pipeline to be used by the `WebGLRenderer`.
*
* This method accepts a pipeline instance as its parameter, not the name.
*
* If the pipeline isn't already the current one it will call `WebGLPipeline.bind` and then `onBind`.
*
* You cannot set Post FX Pipelines using this method. To use a Post FX Pipeline, you should
* apply it to either a Camera, Container or other supporting Game Object.
*
* @method Phaser.Renderer.WebGL.PipelineManager#set
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The pipeline instance to be set as current.
* @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object that invoked this pipeline, if any.
* @param {Phaser.Renderer.WebGL.WebGLShader} [currentShader] - The shader to set as being current.
*
* @return {Phaser.Renderer.WebGL.WebGLPipeline} The pipeline that was set, or undefined if it couldn't be set.
*/
set: function(pipeline, gameObject, currentShader) {
if (pipeline.isPostFX) {
return;
}
if (!this.isCurrent(pipeline, currentShader)) {
this.flush();
if (this.current) {
this.current.unbind();
}
this.current = pipeline;
pipeline.bind(currentShader);
}
pipeline.updateProjectionMatrix();
pipeline.onBind(gameObject);
return pipeline;
},
/**
* This method is called by the `WebGLPipeline.batchQuad` method, right before a quad
* belonging to a Game Object is about to be added to the batch.
*
* It is also called directly bu custom Game Objects, such as Nine Slice or Mesh,
* from their render methods.
*
* It causes a batch flush, then calls the `preBatch` method on the Post FX Pipelines
* belonging to the Game Object.
*
* It should be followed by a call to `postBatch` to complete the process.
*
* @method Phaser.Renderer.WebGL.PipelineManager#preBatch
* @since 3.50.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object about to be batched.
*/
preBatch: function(gameObject) {
if (gameObject.hasPostPipeline) {
this.flush();
var pipelines = gameObject.postPipelines;
for (var i = pipelines.length - 1; i >= 0; i--) {
var pipeline = pipelines[i];
if (pipeline.active) {
pipeline.preBatch(gameObject);
}
}
}
},
/**
* This method is called by the `WebGLPipeline.batchQuad` method, right after a quad
* belonging to a Game Object has been added to the batch.
*
* It is also called directly bu custom Game Objects, such as Nine Slice or Mesh,
* from their render methods.
*
* It causes a batch flush, then calls the `postBatch` method on the Post FX Pipelines
* belonging to the Game Object.
*
* It should be preceeded by a call to `preBatch` to start the process.
*
* @method Phaser.Renderer.WebGL.PipelineManager#postBatch
* @since 3.50.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object that was just added to the batch.
*/
postBatch: function(gameObject) {
if (gameObject.hasPostPipeline) {
this.flush();
var pipelines = gameObject.postPipelines;
for (var i = 0; i < pipelines.length; i++) {
var pipeline = pipelines[i];
if (pipeline.active) {
pipeline.postBatch(gameObject);
}
}
}
},
/**
* Called at the start of the `WebGLRenderer.preRenderCamera` method.
*
* If the Camera has post pipelines set, it will flush the batch and then call the
* `preBatch` method on the post-fx pipelines belonging to the Camera.
*
* @method Phaser.Renderer.WebGL.PipelineManager#preBatchCamera
* @since 3.50.0
*
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera about to be rendered.
*/
preBatchCamera: function(camera) {
if (camera.hasPostPipeline) {
this.flush();
var pipelines = camera.postPipelines;
for (var i = pipelines.length - 1; i >= 0; i--) {
var pipeline = pipelines[i];
if (pipeline.active) {
pipeline.preBatch(camera);
}
}
}
},
/**
* Called at the end of the `WebGLRenderer.postRenderCamera` method.
*
* If the Camera has post pipelines set, it will flush the batch and then call the
* `postBatch` method on the post-fx pipelines belonging to the Camera.
*
* @method Phaser.Renderer.WebGL.PipelineManager#postBatchCamera
* @since 3.50.0
*
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that was just rendered.
*/
postBatchCamera: function(camera) {
if (camera.hasPostPipeline) {
this.flush();
var pipelines = camera.postPipelines;
for (var i = 0; i < pipelines.length; i++) {
var pipeline = pipelines[i];
if (pipeline.active) {
pipeline.postBatch(camera);
}
}
}
},
/**
* Checks to see if the given pipeline is already the active pipeline, both within this
* Pipeline Manager and also has the same shader set in the Renderer.
*
* @method Phaser.Renderer.WebGL.PipelineManager#isCurrent
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.WebGLPipeline} pipeline - The pipeline instance to be checked.
* @param {Phaser.Renderer.WebGL.WebGLShader} [currentShader] - The shader to set as being current.
*
* @return {boolean} `true` if the given pipeline is already the current pipeline, otherwise `false`.
*/
isCurrent: function(pipeline, currentShader) {
var renderer = this.renderer;
var current = this.current;
if (current && !currentShader) {
currentShader = current.currentShader;
}
return !(current !== pipeline || currentShader.program !== renderer.currentProgram);
},
/**
* Copy the `source` Render Target to the `target` Render Target.
*
* You can optionally set the brightness factor of the copy.
*
* The difference between this method and `drawFrame` is that this method
* uses a faster copy shader, where only the brightness can be modified.
* If you need color level manipulation, see `drawFrame` instead.
*
* The copy itself is handled by the Utility Pipeline.
*
* @method Phaser.Renderer.WebGL.PipelineManager#copyFrame
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target.
* @param {number} [brightness=1] - The brightness value applied to the frame copy.
* @param {boolean} [clear=true] - Clear the target before copying?
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
*
* @return {this} This Pipeline Manager instance.
*/
copyFrame: function(source, target, brightness, clear, clearAlpha) {
this.setUtility(this.UTILITY_PIPELINE.copyShader).copyFrame(source, target, brightness, clear, clearAlpha);
return this;
},
/**
* Pops the framebuffer from the renderers FBO stack and sets that as the active target,
* then draws the `source` Render Target to it. It then resets the renderer textures.
*
* This should be done when you need to draw the _final_ results of a pipeline to the game
* canvas, or the next framebuffer in line on the FBO stack. You should only call this once
* in the `onDraw` handler and it should be the final thing called. Be careful not to call
* this if you need to actually use the pipeline shader, instead of the copy shader. In
* those cases, use the `bindAndDraw` method.
*
* @method Phaser.Renderer.WebGL.PipelineManager#copyToGame
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The Render Target to draw from.
*/
copyToGame: function(source) {
this.setUtility(this.UTILITY_PIPELINE.copyShader).copyToGame(source);
return this;
},
/**
* Copy the `source` Render Target to the `target` Render Target, using the
* given Color Matrix.
*
* The difference between this method and `copyFrame` is that this method
* uses a color matrix shader, where you have full control over the luminance
* values used during the copy. If you don't need this, you can use the faster
* `copyFrame` method instead.
*
* The copy itself is handled by the Utility Pipeline.
*
* @method Phaser.Renderer.WebGL.PipelineManager#drawFrame
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target.
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
* @param {Phaser.Display.ColorMatrix} [colorMatrix] - The Color Matrix to use when performing the draw.
*
* @return {this} This Pipeline Manager instance.
*/
drawFrame: function(source, target, clearAlpha, colorMatrix) {
this.setUtility(this.UTILITY_PIPELINE.colorMatrixShader).drawFrame(source, target, clearAlpha, colorMatrix);
return this;
},
/**
* Draws the `source1` and `source2` Render Targets to the `target` Render Target
* using a linear blend effect, which is controlled by the `strength` parameter.
*
* The draw itself is handled by the Utility Pipeline.
*
* @method Phaser.Renderer.WebGL.PipelineManager#blendFrames
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source1 - The first source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} source2 - The second source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target.
* @param {number} [strength=1] - The strength of the blend.
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
*
* @return {this} This Pipeline Manager instance.
*/
blendFrames: function(source1, source2, target, strength, clearAlpha) {
this.setUtility(this.UTILITY_PIPELINE.linearShader).blendFrames(source1, source2, target, strength, clearAlpha);
return this;
},
/**
* Draws the `source1` and `source2` Render Targets to the `target` Render Target
* using an additive blend effect, which is controlled by the `strength` parameter.
*
* The draw itself is handled by the Utility Pipeline.
*
* @method Phaser.Renderer.WebGL.PipelineManager#blendFramesAdditive
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source1 - The first source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} source2 - The second source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target.
* @param {number} [strength=1] - The strength of the blend.
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
*
* @return {this} This Pipeline Manager instance.
*/
blendFramesAdditive: function(source1, source2, target, strength, clearAlpha) {
this.setUtility(this.UTILITY_PIPELINE.addShader).blendFramesAdditive(source1, source2, target, strength, clearAlpha);
return this;
},
/**
* Clears the given Render Target.
*
* @method Phaser.Renderer.WebGL.PipelineManager#clearFrame
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} target - The Render Target to clear.
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
*
* @return {this} This Pipeline Manager instance.
*/
clearFrame: function(target, clearAlpha) {
this.UTILITY_PIPELINE.clearFrame(target, clearAlpha);
return this;
},
/**
* Copy the `source` Render Target to the `target` Render Target.
*
* The difference with this copy is that no resizing takes place. If the `source`
* Render Target is larger than the `target` then only a portion the same size as
* the `target` dimensions is copied across.
*
* You can optionally set the brightness factor of the copy.
*
* @method Phaser.Renderer.WebGL.PipelineManager#blitFrame
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} target - The target Render Target.
* @param {number} [brightness=1] - The brightness value applied to the frame copy.
* @param {boolean} [clear=true] - Clear the target before copying?
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
* @param {boolean} [eraseMode=false] - Erase source from target using ERASE Blend Mode?
*
* @return {this} This Pipeline Manager instance.
*/
blitFrame: function(source, target, brightness, clear, clearAlpha, eraseMode) {
this.setUtility(this.UTILITY_PIPELINE.copyShader).blitFrame(source, target, brightness, clear, clearAlpha, eraseMode);
return this;
},
/**
* Binds the `source` Render Target and then copies a section of it to the `target` Render Target.
*
* This method is extremely fast because it uses `gl.copyTexSubImage2D` and doesn't
* require the use of any shaders. Remember the coordinates are given in standard WebGL format,
* where x and y specify the lower-left corner of the section, not the top-left. Also, the
* copy entirely replaces the contents of the target texture, no 'merging' or 'blending' takes
* place.
*
* @method Phaser.Renderer.WebGL.PipelineManager#copyFrameRect
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} target - The target Render Target.
* @param {number} x - The x coordinate of the lower left corner where to start copying.
* @param {number} y - The y coordinate of the lower left corner where to start copying.
* @param {number} width - The width of the texture.
* @param {number} height - The height of the texture.
* @param {boolean} [clear=true] - Clear the target before copying?
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
*
* @return {this} This Pipeline Manager instance.
*/
copyFrameRect: function(source, target, x, y, width, height, clear, clearAlpha) {
this.UTILITY_PIPELINE.copyFrameRect(source, target, x, y, width, height, clear, clearAlpha);
return this;
},
/**
* Returns `true` if the current pipeline is forced to use texture unit zero.
*
* @method Phaser.Renderer.WebGL.PipelineManager#forceZero
* @since 3.50.0
*
* @return {boolean} `true` if the current pipeline is forced to use texture unit zero.
*/
forceZero: function() {
return this.current && this.current.forceZero;
},
/**
* Sets the Multi Pipeline to be the currently bound pipeline.
*
* This is the default Phaser 3 rendering pipeline.
*
* @method Phaser.Renderer.WebGL.PipelineManager#setMulti
* @since 3.50.0
*
* @return {Phaser.Renderer.WebGL.Pipelines.MultiPipeline} The Multi Pipeline instance.
*/
setMulti: function() {
return this.set(this.MULTI_PIPELINE);
},
/**
* Sets the Utility Pipeline to be the currently bound pipeline.
*
* @method Phaser.Renderer.WebGL.PipelineManager#setUtility
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.WebGLShader} [currentShader] - The shader to set as being current.
*
* @return {Phaser.Renderer.WebGL.Pipelines.UtilityPipeline} The Utility Pipeline instance.
*/
setUtility: function(currentShader) {
return this.UTILITY_PIPELINE.bind(currentShader);
},
/**
* Sets the FX Pipeline to be the currently bound pipeline.
*
* @method Phaser.Renderer.WebGL.PipelineManager#setFX
* @since 3.60.0
*
* @return {Phaser.Renderer.WebGL.Pipelines.FXPipeline} The FX Pipeline instance.
*/
setFX: function() {
return this.set(this.FX_PIPELINE);
},
/**
* Restore WebGL resources after context was lost.
*
* Calls `rebind` on this Pipeline Manager.
* Then calls `restoreContext` on each pipeline in turn.
*
* @method Phaser.Renderer.WebGL.PipelineManager#restoreContext
* @since 3.80.0
*/
restoreContext: function() {
this.rebind();
this.pipelines.each(function(_, pipeline) {
pipeline.restoreContext();
});
ArrayEach(this.postPipelineInstances, function(pipeline) {
pipeline.restoreContext();
});
},
/**
* Use this to reset the gl context to the state that Phaser requires to continue rendering.
*
* Calling this will:
*
* * Disable `DEPTH_TEST`, `CULL_FACE` and `STENCIL_TEST`.
* * Clear the depth buffer and stencil buffers.
* * Reset the viewport size.
* * Reset the blend mode.
* * Bind a blank texture as the active texture on texture unit zero.
* * Rebinds the given pipeline instance.
*
* You should call this if you have previously called `clear`, and then wish to return
* rendering control to Phaser again.
*
* @method Phaser.Renderer.WebGL.PipelineManager#rebind
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.WebGLPipeline} [pipeline] - The pipeline instance to be rebound. If not given, the previous pipeline will be bound.
*/
rebind: function(pipeline) {
if (pipeline === void 0 && this.previous) {
pipeline = this.previous;
}
var renderer = this.renderer;
var gl = renderer.gl;
gl.disable(gl.DEPTH_TEST);
gl.disable(gl.CULL_FACE);
if (renderer.hasActiveStencilMask()) {
gl.clear(gl.DEPTH_BUFFER_BIT);
} else {
gl.disable(gl.STENCIL_TEST);
gl.clear(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
}
gl.viewport(0, 0, renderer.width, renderer.height);
renderer.currentProgram = null;
renderer.setBlendMode(0, true);
var vao = renderer.vaoExtension;
if (vao) {
vao.bindVertexArrayOES(null);
}
var entries = this.pipelines.entries;
for (var key in entries) {
entries[key].glReset = true;
}
if (pipeline) {
this.current = pipeline;
pipeline.rebind();
}
},
/**
* Flushes the current pipeline being used and then clears it, along with the
* the current shader program and vertex buffer from the `WebGLRenderer`.
*
* Then resets the blend mode to NORMAL.
*
* Call this before jumping to your own gl context handler, and then call `rebind` when
* you wish to return control to Phaser again.
*
* @method Phaser.Renderer.WebGL.PipelineManager#clear
* @since 3.50.0
*/
clear: function() {
var renderer = this.renderer;
this.flush();
if (this.current) {
this.current.unbind();
this.previous = this.current;
this.current = null;
} else {
this.previous = null;
}
renderer.currentProgram = null;
renderer.setBlendMode(0, true);
var vao = renderer.vaoExtension;
if (vao) {
vao.bindVertexArrayOES(null);
}
},
/**
* Gets a Render Target the right size to render the Sprite on.
*
* If the Sprite exceeds the size of the renderer, the Render Target will only ever be the maximum
* size of the renderer.
*
* @method Phaser.Renderer.WebGL.PipelineManager#getRenderTarget
* @since 3.60.0
*
* @param {number} size - The maximum dimension required.
*
* @return {Phaser.Renderer.WebGL.RenderTarget} A Render Target large enough to fit the sprite.
*/
getRenderTarget: function(size) {
var targets = this.renderTargets;
var offset = 3;
if (size > this.maxDimension) {
this.targetIndex = targets.length - offset;
return targets[this.targetIndex];
} else {
var index = (SnapCeil(size, this.frameInc, 0, true) - 1) * offset;
this.targetIndex = index;
return targets[index];
}
},
/**
* Gets a matching Render Target, the same size as the one the Sprite was drawn to,
* useful for double-buffer style effects such as blurs.
*
* @method Phaser.Renderer.WebGL.PipelineManager#getSwapRenderTarget
* @since 3.60.0
*
* @return {Phaser.Renderer.WebGL.RenderTarget} The Render Target swap frame.
*/
getSwapRenderTarget: function() {
return this.renderTargets[this.targetIndex + 1];
},
/**
* Gets a matching Render Target, the same size as the one the Sprite was drawn to,
* useful for double-buffer style effects such as blurs.
*
* @method Phaser.Renderer.WebGL.PipelineManager#getAltSwapRenderTarget
* @since 3.60.0
*
* @return {Phaser.Renderer.WebGL.RenderTarget} The Render Target swap frame.
*/
getAltSwapRenderTarget: function() {
return this.renderTargets[this.targetIndex + 2];
},
/**
* Destroy the Pipeline Manager, cleaning up all related resources and references.
*
* @method Phaser.Renderer.WebGL.PipelineManager#destroy
* @since 3.50.0
*/
destroy: function() {
this.flush();
this.classes.clear();
this.postPipelineClasses.clear();
this.pipelines.clear();
this.renderer = null;
this.game = null;
this.classes = null;
this.postPipelineClasses = null;
this.pipelines = null;
this.default = null;
this.current = null;
this.previous = null;
}
});
module2.exports = PipelineManager;
}
),
/***/
32302: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Events = __webpack_require__2(92503);
var RenderTarget = new Class({
initialize: function RenderTarget2(renderer, width, height, scale, minFilter, autoClear, autoResize, addDepthBuffer, forceClamp) {
if (scale === void 0) {
scale = 1;
}
if (minFilter === void 0) {
minFilter = 0;
}
if (autoClear === void 0) {
autoClear = true;
}
if (autoResize === void 0) {
autoResize = false;
}
if (addDepthBuffer === void 0) {
addDepthBuffer = true;
}
if (forceClamp === void 0) {
forceClamp = true;
}
this.renderer = renderer;
this.framebuffer = null;
this.texture = null;
this.width = 0;
this.height = 0;
this.scale = scale;
this.minFilter = minFilter;
this.autoClear = autoClear;
this.autoResize = true;
this.hasDepthBuffer = addDepthBuffer;
this.forceClamp = forceClamp;
this.init(width, height);
if (autoResize) {
this.renderer.on(Events.RESIZE, this.resize, this);
} else {
this.autoResize = false;
}
},
/**
* Sets up this Render Target to the given width and height, creating a new
* frame buffer and texture. This method is called automatically by the constructor
* and at no other time.
*
* @method Phaser.Renderer.WebGL.RenderTarget#init
* @since 3.86.0
*
* @param {number} width - The new width of this Render Target.
* @param {number} height - The new height of this Render Target.
*/
init: function(width, height) {
var renderer = this.renderer;
this.texture = renderer.createTextureFromSource(null, width, height, this.minFilter, this.forceClamp);
this.framebuffer = renderer.createFramebuffer(width, height, this.texture, this.hasDepthBuffer);
this.width = width;
this.height = height;
},
/**
* Sets if this Render Target should automatically resize when the WebGL Renderer
* emits a resize event.
*
* @method Phaser.Renderer.WebGL.RenderTarget#setAutoResize
* @since 3.50.0
*
* @param {boolean} autoResize - Automatically resize this Render Target when the WebGL Renderer resizes?
*
* @return {this} This RenderTarget instance.
*/
setAutoResize: function(autoResize) {
if (autoResize && !this.autoResize) {
this.renderer.on(Events.RESIZE, this.resize, this);
this.autoResize = true;
} else if (!autoResize && this.autoResize) {
this.renderer.off(Events.RESIZE, this.resize, this);
this.autoResize = false;
}
return this;
},
/**
* Resizes this Render Target as long as the given width and height are different
* to the current width and height.
*
* Deletes both the frame buffer and texture, if they exist and then re-creates
* them using the new sizes.
*
* This method is called automatically by the pipeline during its resize handler.
*
* @method Phaser.Renderer.WebGL.RenderTarget#resize
* @since 3.50.0
*
* @param {number} width - The new width of this Render Target.
* @param {number} height - The new height of this Render Target.
*
* @return {this} This RenderTarget instance.
*/
resize: function(width, height) {
if (this.autoResize && this.willResize(width, height)) {
var renderer = this.renderer;
renderer.deleteFramebuffer(this.framebuffer);
renderer.deleteTexture(this.texture);
this.texture = renderer.createTextureFromSource(null, width, height, this.minFilter, this.forceClamp);
this.framebuffer = renderer.createFramebuffer(width, height, this.texture, this.hasDepthBuffer);
this.width = width;
this.height = height;
}
return this;
},
/**
* Checks if this Render Target will resize, or not, if given the new
* width and height values.
*
* @method Phaser.Renderer.WebGL.RenderTarget#willResize
* @since 3.70.0
*
* @param {number} width - The new width of this Render Target.
* @param {number} height - The new height of this Render Target.
*
* @return {boolean} `true` if the Render Target will resize, otherwise `false`.
*/
willResize: function(width, height) {
if (typeof width !== "number" || typeof height !== "number") {
return false;
}
width = Math.round(width * this.scale);
height = Math.round(height * this.scale);
width = Math.max(width, 1);
height = Math.max(height, 1);
return width !== this.width || height !== this.height;
},
/**
* Pushes this Render Target as the current frame buffer of the renderer.
*
* If `autoClear` is set, then clears the texture.
*
* If `adjustViewport` is `true` then it will flush the renderer and then adjust the GL viewport.
*
* @method Phaser.Renderer.WebGL.RenderTarget#bind
* @since 3.50.0
*
* @param {boolean} [adjustViewport=false] - Adjust the GL viewport by calling `RenderTarget.adjustViewport` ?
* @param {number} [width] - Optional new width of this Render Target.
* @param {number} [height] - Optional new height of this Render Target.
*/
bind: function(adjustViewport, width, height) {
if (adjustViewport === void 0) {
adjustViewport = false;
}
var renderer = this.renderer;
if (adjustViewport) {
renderer.flush();
}
if (width && height) {
this.resize(width, height);
}
renderer.pushFramebuffer(this.framebuffer, false, false);
if (adjustViewport) {
this.adjustViewport();
}
if (this.autoClear) {
var gl = this.renderer.gl;
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
}
renderer.clearStencilMask();
},
/**
* Adjusts the GL viewport to match the width and height of this Render Target.
*
* Also disables `SCISSOR_TEST`.
*
* @method Phaser.Renderer.WebGL.RenderTarget#adjustViewport
* @since 3.50.0
*/
adjustViewport: function() {
var gl = this.renderer.gl;
gl.viewport(0, 0, this.width, this.height);
gl.disable(gl.SCISSOR_TEST);
},
/**
* Clears a portion or everything from this Render Target. To clear an area,
* specify the `x`, `y`, `width` and `height`.
*
* @param {number} [x=0] - The left coordinate of the fill rectangle.
* @param {number} [y=0] - The top coordinate of the fill rectangle.
* @param {number} [width=this.width] - The width of the fill rectangle.
* @param {number} [height=this.height] - The height of the fill rectangle.
*
* @method Phaser.Renderer.WebGL.RenderTarget#clear
* @since 3.50.0
*/
clear: function(x, y, width, height) {
var renderer = this.renderer;
var gl = renderer.gl;
renderer.pushFramebuffer(this.framebuffer);
if (x !== void 0 && y !== void 0 && width !== void 0 && height !== void 0) {
gl.enable(gl.SCISSOR_TEST);
gl.scissor(x, y, width, height);
} else {
gl.disable(gl.SCISSOR_TEST);
}
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
renderer.popFramebuffer();
renderer.resetScissor();
},
/**
* Unbinds this Render Target and optionally flushes the WebGL Renderer first.
*
* @name Phaser.Renderer.WebGL.RenderTarget#unbind
* @since 3.50.0
*
* @param {boolean} [flush=false] - Flush the WebGL Renderer before unbinding?
*
* @return {Phaser.Renderer.WebGL.Wrappers.WebGLFramebufferWrapper} The Framebuffer that was set, or `null` if there aren't any more in the stack.
*/
unbind: function(flush) {
if (flush === void 0) {
flush = false;
}
var renderer = this.renderer;
if (flush) {
renderer.flush();
}
return renderer.popFramebuffer();
},
/**
* Removes all external references from this class and deletes the
* WebGL framebuffer and texture instances.
*
* Does not remove this Render Target from the parent pipeline.
*
* @name Phaser.Renderer.WebGL.RenderTarget#destroy
* @since 3.50.0
*/
destroy: function() {
var renderer = this.renderer;
renderer.off(Events.RESIZE, this.resize, this);
renderer.deleteFramebuffer(this.framebuffer);
renderer.deleteTexture(this.texture);
this.renderer = null;
this.framebuffer = null;
this.texture = null;
}
});
module2.exports = RenderTarget;
}
),
/***/
70554: (
/***/
(module2) => {
module2.exports = {
/**
* Packs four floats on a range from 0.0 to 1.0 into a single Uint32
*
* @function Phaser.Renderer.WebGL.Utils.getTintFromFloats
* @since 3.0.0
*
* @param {number} r - Red component in a range from 0.0 to 1.0
* @param {number} g - Green component in a range from 0.0 to 1.0
* @param {number} b - Blue component in a range from 0.0 to 1.0
* @param {number} a - Alpha component in a range from 0.0 to 1.0
*
* @return {number} The packed RGBA values as a Uint32.
*/
getTintFromFloats: function(r, g, b, a) {
var ur = (r * 255 | 0) & 255;
var ug = (g * 255 | 0) & 255;
var ub = (b * 255 | 0) & 255;
var ua = (a * 255 | 0) & 255;
return (ua << 24 | ur << 16 | ug << 8 | ub) >>> 0;
},
/**
* Packs a Uint24, representing RGB components, with a Float32, representing
* the alpha component, with a range between 0.0 and 1.0 and return a Uint32
*
* @function Phaser.Renderer.WebGL.Utils.getTintAppendFloatAlpha
* @since 3.0.0
*
* @param {number} rgb - Uint24 representing RGB components
* @param {number} a - Float32 representing Alpha component
*
* @return {number} Packed RGBA as Uint32
*/
getTintAppendFloatAlpha: function(rgb, a) {
var ua = (a * 255 | 0) & 255;
return (ua << 24 | rgb) >>> 0;
},
/**
* Packs a Uint24, representing RGB components, with a Float32, representing
* the alpha component, with a range between 0.0 and 1.0 and return a
* swizzled Uint32
*
* @function Phaser.Renderer.WebGL.Utils.getTintAppendFloatAlphaAndSwap
* @since 3.0.0
*
* @param {number} rgb - Uint24 representing RGB components
* @param {number} a - Float32 representing Alpha component
*
* @return {number} Packed RGBA as Uint32
*/
getTintAppendFloatAlphaAndSwap: function(rgb, a) {
var ur = (rgb >> 16 | 0) & 255;
var ug = (rgb >> 8 | 0) & 255;
var ub = (rgb | 0) & 255;
var ua = (a * 255 | 0) & 255;
return (ua << 24 | ub << 16 | ug << 8 | ur) >>> 0;
},
/**
* Unpacks a Uint24 RGB into an array of floats of ranges of 0.0 and 1.0
*
* @function Phaser.Renderer.WebGL.Utils.getFloatsFromUintRGB
* @since 3.0.0
*
* @param {number} rgb - RGB packed as a Uint24
*
* @return {array} Array of floats representing each component as a float
*/
getFloatsFromUintRGB: function(rgb) {
var ur = (rgb >> 16 | 0) & 255;
var ug = (rgb >> 8 | 0) & 255;
var ub = (rgb | 0) & 255;
return [ur / 255, ug / 255, ub / 255];
},
/**
* Check to see how many texture units the GPU supports in a fragment shader
* and if the value specific in the game config is allowed.
*
* This value is hard-clamped to 16 for performance reasons on Android devices.
*
* @function Phaser.Renderer.WebGL.Utils.checkShaderMax
* @since 3.50.0
*
* @param {WebGLRenderingContext} gl - The WebGLContext used to create the shaders.
* @param {number} maxTextures - The Game Config maxTextures value.
*
* @return {number} The number of texture units that is supported by this browser and GPU.
*/
checkShaderMax: function(gl, maxTextures) {
var gpuMax = Math.min(16, gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS));
if (!maxTextures || maxTextures === -1) {
return gpuMax;
} else {
return Math.min(gpuMax, maxTextures);
}
},
/**
* Checks the given Fragment Shader Source for `%count%` and `%forloop%` declarations and
* replaces those with GLSL code for setting `texture = texture2D(uMainSampler[i], outTexCoord)`.
*
* @function Phaser.Renderer.WebGL.Utils.parseFragmentShaderMaxTextures
* @since 3.50.0
*
* @param {string} fragmentShaderSource - The Fragment Shader source code to operate on.
* @param {number} maxTextures - The number of maxTextures value.
*
* @return {string} The modified Fragment Shader source.
*/
parseFragmentShaderMaxTextures: function(fragmentShaderSource, maxTextures) {
if (!fragmentShaderSource) {
return "";
}
var src = "";
for (var i = 0; i < maxTextures; i++) {
if (i > 0) {
src += "\n else ";
}
if (i < maxTextures - 1) {
src += "if (outTexId < " + i + ".5)";
}
src += "\n {";
src += "\n texture = texture2D(uMainSampler[" + i + "], outTexCoord);";
src += "\n }";
}
fragmentShaderSource = fragmentShaderSource.replace(/%count%/gi, maxTextures.toString());
return fragmentShaderSource.replace(/%forloop%/gi, src);
},
/**
* Takes the Glow FX Shader source and parses out the __SIZE__ and __DIST__
* consts with the configuration values.
*
* @function Phaser.Renderer.WebGL.Utils.setGlowQuality
* @since 3.60.0
*
* @param {string} shader - The Fragment Shader source code to operate on.
* @param {Phaser.Game} game - The Phaser Game instance.
* @param {number} [quality] - The quality of the glow (defaults to 0.1)
* @param {number} [distance] - The distance of the glow (defaults to 10)
*
* @return {string} The modified Fragment Shader source.
*/
setGlowQuality: function(shader, game, quality, distance) {
if (quality === void 0) {
quality = game.config.glowFXQuality;
}
if (distance === void 0) {
distance = game.config.glowFXDistance;
}
shader = shader.replace(/__SIZE__/gi, (1 / quality / distance).toFixed(7));
shader = shader.replace(/__DIST__/gi, distance.toFixed(0) + ".0");
return shader;
}
};
}
),
/***/
29100: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var DeepCopy = __webpack_require__2(62644);
var EventEmitter = __webpack_require__2(50792);
var Events = __webpack_require__2(77085);
var GetFastValue = __webpack_require__2(95540);
var Matrix4 = __webpack_require__2(37867);
var RendererEvents = __webpack_require__2(92503);
var RenderTarget = __webpack_require__2(32302);
var Utils = __webpack_require__2(70554);
var WebGLShader = __webpack_require__2(38683);
var WebGLPipeline = new Class({
Extends: EventEmitter,
initialize: function WebGLPipeline2(config) {
EventEmitter.call(this);
var game = config.game;
var renderer = game.renderer;
var gl = renderer.gl;
this.name = GetFastValue(config, "name", "WebGLPipeline");
this.game = game;
this.renderer = renderer;
this.manager;
this.gl = gl;
this.view = game.canvas;
this.width = 0;
this.height = 0;
this.vertexCount = 0;
this.vertexCapacity = 0;
this.vertexData;
this.vertexBuffer;
this.activeBuffer;
this.topology = GetFastValue(config, "topology", gl.TRIANGLES);
this.bytes;
this.vertexViewF32;
this.vertexViewU32;
this.active = true;
this.forceZero = GetFastValue(config, "forceZero", false);
this.hasBooted = false;
this.isPostFX = false;
this.isPreFX = false;
this.renderTargets = [];
this.currentRenderTarget;
this.shaders = [];
this.currentShader;
this.projectionMatrix;
this.projectionWidth = 0;
this.projectionHeight = 0;
this.config = config;
this.glReset = false;
this.batch = [];
this.currentBatch = null;
this.currentTexture = null;
this.currentUnit = 0;
this.activeTextures = [];
this.resizeUniform = GetFastValue(config, "resizeUniform", "");
},
/**
* Called when the Game has fully booted and the Renderer has finished setting up.
*
* By this stage all Game level systems are now in place. You can perform any final tasks that the
* pipeline may need, that relies on game systems such as the Texture Manager being ready.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#boot
* @fires Phaser.Renderer.WebGL.Pipelines.Events#BOOT
* @since 3.11.0
*/
boot: function() {
var i;
var gl = this.gl;
var config = this.config;
var renderer = this.renderer;
if (!this.isPostFX) {
this.projectionMatrix = new Matrix4().identity();
}
var renderTargets = this.renderTargets;
var targets = GetFastValue(config, "renderTarget", false);
if (typeof targets === "boolean" && targets) {
targets = 1;
}
var width = renderer.width;
var height = renderer.height;
if (typeof targets === "number") {
for (i = 0; i < targets; i++) {
renderTargets.push(new RenderTarget(renderer, width, height, 1, 0, true));
}
} else if (Array.isArray(targets)) {
for (i = 0; i < targets.length; i++) {
var scale = GetFastValue(targets[i], "scale", 1);
var minFilter = GetFastValue(targets[i], "minFilter", 0);
var autoClear = GetFastValue(targets[i], "autoClear", 1);
var autoResize = GetFastValue(targets[i], "autoResize", false);
var targetWidth = GetFastValue(targets[i], "width", null);
var targetHeight = GetFastValue(targets[i], "height", targetWidth);
if (targetWidth) {
renderTargets.push(new RenderTarget(renderer, targetWidth, targetHeight, 1, minFilter, autoClear, autoResize));
} else {
renderTargets.push(new RenderTarget(renderer, width, height, scale, minFilter, autoClear, autoResize));
}
}
}
if (renderTargets.length) {
this.currentRenderTarget = renderTargets[0];
}
this.setShadersFromConfig(config);
var shaders = this.shaders;
var vertexSize = 0;
for (i = 0; i < shaders.length; i++) {
if (shaders[i].vertexSize > vertexSize) {
vertexSize = shaders[i].vertexSize;
}
}
var batchSize = GetFastValue(config, "batchSize", renderer.config.batchSize);
this.vertexCapacity = batchSize * 6;
var data = new ArrayBuffer(this.vertexCapacity * vertexSize);
this.vertexData = data;
this.bytes = new Uint8Array(data);
this.vertexViewF32 = new Float32Array(data);
this.vertexViewU32 = new Uint32Array(data);
var configVerts = GetFastValue(config, "vertices", null);
if (configVerts) {
this.vertexViewF32.set(configVerts);
this.vertexBuffer = renderer.createVertexBuffer(data, gl.STATIC_DRAW);
} else {
this.vertexBuffer = renderer.createVertexBuffer(data.byteLength, gl.DYNAMIC_DRAW);
}
this.setVertexBuffer();
for (i = shaders.length - 1; i >= 0; i--) {
shaders[i].rebind();
}
this.hasBooted = true;
renderer.on(RendererEvents.RESIZE, this.resize, this);
renderer.on(RendererEvents.PRE_RENDER, this.onPreRender, this);
renderer.on(RendererEvents.RENDER, this.onRender, this);
renderer.on(RendererEvents.POST_RENDER, this.onPostRender, this);
this.emit(Events.BOOT, this);
this.onBoot();
},
/**
* This method is called once when this pipeline has finished being set-up
* at the end of the boot process. By the time this method is called, all
* of the shaders are ready and configured.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onBoot
* @since 3.50.0
*/
onBoot: function() {
},
/**
* This method is called once when this pipeline has finished being set-up
* at the end of the boot process. By the time this method is called, all
* of the shaders are ready and configured. It's also called if the renderer
* changes size.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onResize
* @since 3.50.0
*
* @param {number} width - The new width of this WebGL Pipeline.
* @param {number} height - The new height of this WebGL Pipeline.
*/
onResize: function() {
},
/**
* Sets the currently active shader within this pipeline.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setShader
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.WebGLShader} shader - The shader to set as being current.
* @param {boolean} [setAttributes=false] - Should the vertex attribute pointers be set?
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLBufferWrapper} [vertexBuffer] - The vertex buffer to be set before the shader is bound. Defaults to the one owned by this pipeline.
*
* @return {this} This WebGLPipeline instance.
*/
setShader: function(shader, setAttributes, vertexBuffer) {
var renderer = this.renderer;
if (shader !== this.currentShader || renderer.currentProgram !== this.currentShader.program) {
this.flush();
var wasBound = this.setVertexBuffer(vertexBuffer);
if (wasBound && !setAttributes) {
setAttributes = true;
}
shader.bind(setAttributes, false);
this.currentShader = shader;
}
return this;
},
/**
* Searches all shaders in this pipeline for one matching the given name, then returns it.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#getShaderByName
* @since 3.50.0
*
* @param {string} name - The index of the shader to set.
*
* @return {Phaser.Renderer.WebGL.WebGLShader} The WebGLShader instance, if found.
*/
getShaderByName: function(name) {
var shaders = this.shaders;
for (var i = 0; i < shaders.length; i++) {
if (shaders[i].name === name) {
return shaders[i];
}
}
},
/**
* Destroys all shaders currently set in the `WebGLPipeline.shaders` array and then parses the given
* `config` object, extracting the shaders from it, creating `WebGLShader` instances and finally
* setting them into the `shaders` array of this pipeline.
*
* This is a destructive process. Be very careful when you call it, should you need to.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setShadersFromConfig
* @since 3.50.0
*
* @param {Phaser.Types.Renderer.WebGL.WebGLPipelineConfig} config - The configuration object for this WebGL Pipeline.
*
* @return {this} This WebGLPipeline instance.
*/
setShadersFromConfig: function(config) {
var i;
var shaders = this.shaders;
var renderer = this.renderer;
for (i = 0; i < shaders.length; i++) {
shaders[i].destroy();
}
var vName = "vertShader";
var fName = "fragShader";
var aName = "attributes";
var defaultVertShader = GetFastValue(config, vName, null);
var defaultFragShader = Utils.parseFragmentShaderMaxTextures(GetFastValue(config, fName, null), renderer.maxTextures);
var defaultAttribs = GetFastValue(config, aName, null);
var configShaders = GetFastValue(config, "shaders", []);
var len = configShaders.length;
if (len === 0) {
if (defaultVertShader && defaultFragShader) {
this.shaders = [new WebGLShader(this, "default", defaultVertShader, defaultFragShader, DeepCopy(defaultAttribs))];
}
} else {
var newShaders = [];
for (i = 0; i < len; i++) {
var shaderEntry = configShaders[i];
var name;
var vertShader;
var fragShader;
var attributes;
if (typeof shaderEntry === "string") {
name = "default";
vertShader = defaultVertShader;
fragShader = Utils.parseFragmentShaderMaxTextures(shaderEntry, renderer.maxTextures);
attributes = defaultAttribs;
} else {
name = GetFastValue(shaderEntry, "name", "default");
vertShader = GetFastValue(shaderEntry, vName, defaultVertShader);
fragShader = Utils.parseFragmentShaderMaxTextures(GetFastValue(shaderEntry, fName, defaultFragShader), renderer.maxTextures);
attributes = GetFastValue(shaderEntry, aName, defaultAttribs);
}
if (name === "default") {
var lines = fragShader.split("\n");
var test = lines[0].trim();
if (test.indexOf("#define SHADER_NAME") > -1) {
name = test.substring(20);
}
}
if (vertShader && fragShader) {
newShaders.push(new WebGLShader(this, name, vertShader, fragShader, DeepCopy(attributes)));
}
}
this.shaders = newShaders;
}
if (this.shaders.length === 0) {
console.warn("Pipeline: " + this.name + " - Invalid shader config");
} else {
this.currentShader = this.shaders[0];
}
return this;
},
/**
* Creates a new WebGL Pipeline Batch Entry, sets the texture unit as zero
* and pushes the entry into the batch.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#createBatch
* @since 3.60.0
*
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} texture - The texture assigned to this batch entry.
*
* @return {number} The texture unit that was bound.
*/
createBatch: function(texture) {
this.currentBatch = {
start: this.vertexCount,
count: 0,
texture: [texture],
unit: 0,
maxUnit: 0
};
this.currentUnit = 0;
this.currentTexture = texture;
this.batch.push(this.currentBatch);
return 0;
},
/**
* Adds the given texture to the current WebGL Pipeline Batch Entry and
* increases the batch entry unit and maxUnit values by 1.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#addTextureToBatch
* @since 3.60.0
*
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} texture - The texture assigned to this batch entry.
*/
addTextureToBatch: function(texture) {
var batch = this.currentBatch;
if (batch) {
batch.texture.push(texture);
batch.unit++;
batch.maxUnit++;
}
},
/**
* Takes the given WebGLTextureWrapper and determines what to do with it.
*
* If there is no current batch (i.e. after a flush) it will create a new
* batch from it.
*
* If the texture is already bound, it will return the current texture unit.
*
* If the texture already exists in the current batch, the unit gets reset
* to match it.
*
* If the texture cannot be found in the current batch, and it supports
* multiple textures, it's added into the batch and the unit indexes are
* advanced.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#pushBatch
* @since 3.60.0
*
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} texture - The texture assigned to this batch entry.
*
* @return {number} The texture unit that was bound.
*/
pushBatch: function(texture) {
if (!this.currentBatch || this.forceZero && texture !== this.currentTexture) {
return this.createBatch(texture);
}
if (texture === this.currentTexture) {
return this.currentUnit;
} else {
var current = this.currentBatch;
var idx = current.texture.indexOf(texture);
if (idx === -1) {
if (current.texture.length === this.renderer.maxTextures) {
return this.createBatch(texture);
} else {
current.unit++;
current.maxUnit++;
current.texture.push(texture);
this.currentUnit = current.unit;
this.currentTexture = texture;
return current.unit;
}
} else {
this.currentUnit = idx;
this.currentTexture = texture;
return idx;
}
}
},
/**
* Custom pipelines can use this method in order to perform any required pre-batch tasks
* for the given Game Object. It must return the texture unit the Game Object was assigned.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setGameObject
* @since 3.50.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object being rendered or added to the batch.
* @param {Phaser.Textures.Frame} [frame] - Optional frame to use. Can override that of the Game Object.
*
* @return {number} The texture unit the Game Object has been assigned.
*/
setGameObject: function(gameObject, frame) {
if (frame === void 0) {
frame = gameObject.frame;
}
return this.pushBatch(frame.source.glTexture);
},
/**
* Check if the current batch of vertices is full.
*
* You can optionally provide an `amount` parameter. If given, it will check if the batch
* needs to flush _if_ the `amount` is added to it. This allows you to test if you should
* flush before populating the batch.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#shouldFlush
* @since 3.0.0
*
* @param {number} [amount=0] - Will the batch need to flush if this many vertices are added to it?
*
* @return {boolean} `true` if the current batch should be flushed, otherwise `false`.
*/
shouldFlush: function(amount) {
if (amount === void 0) {
amount = 0;
}
return this.vertexCount + amount > this.vertexCapacity;
},
/**
* Returns the number of vertices that can be added to the current batch before
* it will trigger a flush to happen.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#vertexAvailable
* @since 3.60.0
*
* @return {number} The number of vertices that can still be added to the current batch before it will flush.
*/
vertexAvailable: function() {
return this.vertexCapacity - this.vertexCount;
},
/**
* Resizes the properties used to describe the viewport.
*
* This method is called automatically by the renderer during its resize handler.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#resize
* @fires Phaser.Renderer.WebGL.Pipelines.Events#RESIZE
* @since 3.0.0
*
* @param {number} width - The new width of this WebGL Pipeline.
* @param {number} height - The new height of this WebGL Pipeline.
*
* @return {this} This WebGLPipeline instance.
*/
resize: function(width, height) {
if (width !== this.width || height !== this.height) {
this.flush();
}
this.width = width;
this.height = height;
var targets = this.renderTargets;
for (var i = 0; i < targets.length; i++) {
targets[i].resize(width, height);
}
this.setProjectionMatrix(width, height);
if (this.resizeUniform) {
this.set2f(this.resizeUniform, width, height);
}
this.emit(Events.RESIZE, width, height, this);
this.onResize(width, height);
return this;
},
/**
* Adjusts this pipelines ortho Projection Matrix to use the given dimensions
* and resets the `uProjectionMatrix` uniform on all bound shaders.
*
* This method is called automatically by the renderer during its resize handler.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setProjectionMatrix
* @since 3.50.0
*
* @param {number} width - The new width of this WebGL Pipeline.
* @param {number} height - The new height of this WebGL Pipeline.
*
* @return {this} This WebGLPipeline instance.
*/
setProjectionMatrix: function(width, height) {
var projectionMatrix = this.projectionMatrix;
if (!projectionMatrix) {
return this;
}
this.projectionWidth = width;
this.projectionHeight = height;
projectionMatrix.ortho(0, width, height, 0, -1e3, 1e3);
var shaders = this.shaders;
var name = "uProjectionMatrix";
for (var i = 0; i < shaders.length; i++) {
var shader = shaders[i];
if (shader.hasUniform(name)) {
shader.resetUniform(name);
shader.setMatrix4fv(name, false, projectionMatrix.val, shader);
}
}
return this;
},
/**
* Adjusts this pipelines ortho Projection Matrix to flip the y
* and bottom values. Call with 'false' as the parameter to flip
* them back again.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#flipProjectionMatrix
* @since 3.60.0
*
* @param {boolean} [flipY=true] - Flip the y and bottom values?
*/
flipProjectionMatrix: function(flipY) {
if (flipY === void 0) {
flipY = true;
}
var projectionMatrix = this.projectionMatrix;
if (!projectionMatrix) {
return this;
}
var width = this.projectionWidth;
var height = this.projectionHeight;
if (flipY) {
projectionMatrix.ortho(0, width, 0, height, -1e3, 1e3);
} else {
projectionMatrix.ortho(0, width, height, 0, -1e3, 1e3);
}
this.setMatrix4fv("uProjectionMatrix", false, projectionMatrix.val);
},
/**
* Adjusts this pipelines ortho Projection Matrix to match that of the global
* WebGL Renderer Projection Matrix.
*
* This method is called automatically by the Pipeline Manager when this
* pipeline is set.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#updateProjectionMatrix
* @since 3.50.0
*/
updateProjectionMatrix: function() {
if (this.projectionMatrix) {
var globalWidth = this.renderer.projectionWidth;
var globalHeight = this.renderer.projectionHeight;
if (this.projectionWidth !== globalWidth || this.projectionHeight !== globalHeight) {
this.setProjectionMatrix(globalWidth, globalHeight);
}
}
},
/**
* This method is called every time the Pipeline Manager makes this pipeline the currently active one.
*
* It binds the resources and shader needed for this pipeline, including setting the vertex buffer
* and attribute pointers.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#bind
* @fires Phaser.Renderer.WebGL.Pipelines.Events#BIND
* @since 3.0.0
*
* @param {Phaser.Renderer.WebGL.WebGLShader} [currentShader] - The shader to set as being current.
*
* @return {this} This WebGLPipeline instance.
*/
bind: function(currentShader) {
if (currentShader === void 0) {
currentShader = this.currentShader;
}
if (this.glReset) {
return this.rebind(currentShader);
}
var wasBound = false;
var gl = this.gl;
if (gl.getParameter(gl.ARRAY_BUFFER_BINDING) !== this.vertexBuffer) {
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer.webGLBuffer);
this.activeBuffer = this.vertexBuffer;
wasBound = true;
}
currentShader.bind(wasBound);
this.currentShader = currentShader;
this.activeTextures.length = 0;
this.emit(Events.BIND, this, currentShader);
this.onActive(currentShader);
return this;
},
/**
* This method is called every time the Pipeline Manager rebinds this pipeline.
*
* It resets all shaders this pipeline uses, setting their attributes again.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#rebind
* @fires Phaser.Renderer.WebGL.Pipelines.Events#REBIND
* @since 3.0.0
*
* @param {Phaser.Renderer.WebGL.WebGLShader} [currentShader] - The shader to set as being current.
*
* @return {this} This WebGLPipeline instance.
*/
rebind: function(currentShader) {
this.activeBuffer = null;
this.setVertexBuffer();
var shaders = this.shaders;
for (var i = shaders.length - 1; i >= 0; i--) {
var shader = shaders[i].rebind();
if (!currentShader || shader === currentShader) {
this.currentShader = shader;
}
}
this.activeTextures.length = 0;
this.emit(Events.REBIND, this.currentShader);
this.onActive(this.currentShader);
this.onRebind();
this.glReset = false;
return this;
},
/**
* This method is called if the WebGL context is lost and restored.
* It ensures that uniforms are synced back to the GPU
* for all shaders in this pipeline.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#restoreContext
* @since 3.80.0
*/
restoreContext: function() {
var shaders = this.shaders;
var hasVertexBuffer = !!this.vertexBuffer;
this.activeBuffer = null;
this.activeTextures.length = 0;
this.batch.length = 0;
this.currentBatch = null;
this.currentTexture = null;
this.currentUnit = 0;
if (hasVertexBuffer) {
this.setVertexBuffer();
}
for (var i = 0; i < shaders.length; i++) {
var shader = shaders[i];
shader.syncUniforms();
if (hasVertexBuffer) {
shader.rebind();
}
}
},
/**
* Binds the vertex buffer to be the active ARRAY_BUFFER on the WebGL context.
*
* It first checks to see if it's already set as the active buffer and only
* binds itself if not.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setVertexBuffer
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLBufferWrapper} [buffer] - The Vertex Buffer to be bound. Defaults to the one owned by this pipeline.
*
* @return {boolean} `true` if the vertex buffer was bound, or `false` if it was already bound.
*/
setVertexBuffer: function(buffer) {
if (buffer === void 0) {
buffer = this.vertexBuffer;
}
if (buffer !== this.activeBuffer) {
var gl = this.gl;
this.gl.bindBuffer(gl.ARRAY_BUFFER, buffer.webGLBuffer);
this.activeBuffer = buffer;
return true;
}
return false;
},
/**
* This method is called as a result of the `WebGLPipeline.batchQuad` method, right before a quad
* belonging to a Game Object is about to be added to the batch. When this is called, the
* renderer has just performed a flush. It will bind the current render target, if any are set
* and finally call the `onPreBatch` hook.
*
* It is also called as part of the `PipelineManager.preBatch` method when processing Post FX Pipelines.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#preBatch
* @since 3.50.0
*
* @param {(Phaser.GameObjects.GameObject|Phaser.Cameras.Scene2D.Camera)} [gameObject] - The Game Object or Camera that invoked this pipeline, if any.
*
* @return {this} This WebGLPipeline instance.
*/
preBatch: function(gameObject) {
if (this.currentRenderTarget) {
this.currentRenderTarget.bind();
}
this.onPreBatch(gameObject);
return this;
},
/**
* This method is called as a result of the `WebGLPipeline.batchQuad` method, right after a quad
* belonging to a Game Object has been added to the batch. When this is called, the
* renderer has just performed a flush.
*
* It calls the `onDraw` hook followed by the `onPostBatch` hook, which can be used to perform
* additional Post FX Pipeline processing.
*
* It is also called as part of the `PipelineManager.postBatch` method when processing Post FX Pipelines.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#postBatch
* @since 3.50.0
*
* @param {(Phaser.GameObjects.GameObject|Phaser.Cameras.Scene2D.Camera)} [gameObject] - The Game Object or Camera that invoked this pipeline, if any.
*
* @return {this} This WebGLPipeline instance.
*/
postBatch: function(gameObject) {
this.onDraw(this.currentRenderTarget);
this.onPostBatch(gameObject);
return this;
},
/**
* This method is only used by Sprite FX and Post FX Pipelines and those that extend from them.
*
* This method is called every time the `postBatch` method is called and is passed a
* reference to the current render target.
*
* At the very least a Post FX Pipeline should call `this.bindAndDraw(renderTarget)`,
* however, you can do as much additional processing as you like in this method if
* you override it from within your own pipelines.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onDraw
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} renderTarget - The Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} [swapTarget] - A Swap Render Target, useful for double-buffer effects. Only set by SpriteFX Pipelines.
*/
onDraw: function() {
},
/**
* This method is called every time the Pipeline Manager deactivates this pipeline, swapping from
* it to another one. This happens after a call to `flush` and before the new pipeline is bound.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#unbind
* @since 3.50.0
*/
unbind: function() {
if (this.currentRenderTarget) {
this.currentRenderTarget.unbind();
}
},
/**
* Uploads the vertex data and emits a draw call for the current batch of vertices.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#flush
* @fires Phaser.Renderer.WebGL.Pipelines.Events#BEFORE_FLUSH
* @fires Phaser.Renderer.WebGL.Pipelines.Events#AFTER_FLUSH
* @since 3.0.0
*
* @param {boolean} [isPostFlush=false] - Was this flush invoked as part of a post-process, or not?
*
* @return {this} This WebGLPipeline instance.
*/
flush: function(isPostFlush) {
if (isPostFlush === void 0) {
isPostFlush = false;
}
if (this.vertexCount > 0) {
this.emit(Events.BEFORE_FLUSH, this, isPostFlush);
this.onBeforeFlush(isPostFlush);
var gl = this.gl;
var vertexCount = this.vertexCount;
var vertexSize = this.currentShader.vertexSize;
var topology = this.topology;
if (this.active) {
this.setVertexBuffer();
if (vertexCount === this.vertexCapacity) {
gl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.DYNAMIC_DRAW);
} else {
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.bytes.subarray(0, vertexCount * vertexSize));
}
var i;
var entry;
var texture;
var batch = this.batch;
var activeTextures = this.activeTextures;
if (this.forceZero) {
if (!activeTextures[0]) {
gl.activeTexture(gl.TEXTURE0);
}
for (i = 0; i < batch.length; i++) {
entry = batch[i];
texture = entry.texture[0];
if (activeTextures[0] !== texture) {
gl.bindTexture(gl.TEXTURE_2D, texture.webGLTexture);
activeTextures[0] = texture;
}
gl.drawArrays(topology, entry.start, entry.count);
}
} else {
for (i = 0; i < batch.length; i++) {
entry = batch[i];
for (var t = 0; t <= entry.maxUnit; t++) {
texture = entry.texture[t];
if (activeTextures[t] !== texture) {
gl.activeTexture(gl.TEXTURE0 + t);
gl.bindTexture(gl.TEXTURE_2D, texture.webGLTexture);
activeTextures[t] = texture;
}
}
gl.drawArrays(topology, entry.start, entry.count);
}
}
}
this.vertexCount = 0;
this.batch.length = 0;
this.currentBatch = null;
this.currentTexture = null;
this.currentUnit = 0;
this.emit(Events.AFTER_FLUSH, this, isPostFlush);
this.onAfterFlush(isPostFlush);
}
return this;
},
/**
* By default this is an empty method hook that you can override and use in your own custom pipelines.
*
* This method is called every time the Pipeline Manager makes this the active pipeline. It is called
* at the end of the `WebGLPipeline.bind` method, after the current shader has been set. The current
* shader is passed to this hook.
*
* For example, if a display list has 3 Sprites in it that all use the same pipeline, this hook will
* only be called for the first one, as the 2nd and 3rd Sprites do not cause the pipeline to be changed.
*
* If you need to listen for that event instead, use the `onBind` hook.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onActive
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.WebGLShader} currentShader - The shader that was set as current.
*/
onActive: function() {
},
/**
* By default this is an empty method hook that you can override and use in your own custom pipelines.
*
* This method is called every time a **Game Object** asks the Pipeline Manager to use this pipeline,
* even if the pipeline is already active.
*
* Unlike the `onActive` method, which is only called when the Pipeline Manager makes this pipeline
* active, this hook is called for every Game Object that requests use of this pipeline, allowing you to
* perform per-object set-up, such as loading shader uniform data.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onBind
* @since 3.50.0
*
* @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object that invoked this pipeline, if any.
*/
onBind: function() {
},
/**
* By default this is an empty method hook that you can override and use in your own custom pipelines.
*
* This method is called when the Pipeline Manager needs to rebind this pipeline. This happens after a
* pipeline has been cleared, usually when passing control over to a 3rd party WebGL library, like Spine,
* and then returing to Phaser again.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onRebind
* @since 3.50.0
*/
onRebind: function() {
},
/**
* By default this is an empty method hook that you can override and use in your own custom pipelines.
*
* This method is called every time the `batchQuad` or `batchTri` methods are called. If this was
* as a result of a Game Object, then the Game Object reference is passed to this hook too.
*
* This hook is called _after_ the quad (or tri) has been added to the batch, so you can safely
* call 'flush' from within this.
*
* Note that Game Objects may call `batchQuad` or `batchTri` multiple times for a single draw,
* for example the Graphics Game Object.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onBatch
* @since 3.50.0
*
* @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object that invoked this pipeline, if any.
*/
onBatch: function() {
},
/**
* By default this is an empty method hook that you can override and use in your own custom pipelines.
*
* This method is called immediately before a **Game Object** is about to add itself to the batch.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onPreBatch
* @since 3.50.0
*
* @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object that invoked this pipeline, if any.
*/
onPreBatch: function() {
},
/**
* By default this is an empty method hook that you can override and use in your own custom pipelines.
*
* This method is called immediately after a **Game Object** has been added to the batch.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onPostBatch
* @since 3.50.0
*
* @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object that invoked this pipeline, if any.
*/
onPostBatch: function() {
},
/**
* By default this is an empty method hook that you can override and use in your own custom pipelines.
*
* This method is called once per frame, right before anything has been rendered, but after the canvas
* has been cleared. If this pipeline has a render target, it will also have been cleared by this point.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onPreRender
* @since 3.50.0
*/
onPreRender: function() {
},
/**
* By default this is an empty method hook that you can override and use in your own custom pipelines.
*
* This method is called _once per frame_, by every Camera in a Scene that wants to render.
*
* It is called at the start of the rendering process, before anything has been drawn to the Camera.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onRender
* @since 3.50.0
*
* @param {Phaser.Scene} scene - The Scene being rendered.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Scene Camera being rendered with.
*/
onRender: function() {
},
/**
* By default this is an empty method hook that you can override and use in your own custom pipelines.
*
* This method is called _once per frame_, after all rendering has happened and snapshots have been taken.
*
* It is called at the very end of the rendering process, once all Cameras, for all Scenes, have
* been rendered.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onPostRender
* @since 3.50.0
*/
onPostRender: function() {
},
/**
* By default this is an empty method hook that you can override and use in your own custom pipelines.
*
* This method is called every time this pipeline is asked to flush its batch.
*
* It is called immediately before the `gl.bufferData` and `gl.drawArrays` calls are made, so you can
* perform any final pre-render modifications. To apply changes post-render, see `onAfterFlush`.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onBeforeFlush
* @since 3.50.0
*
* @param {boolean} [isPostFlush=false] - Was this flush invoked as part of a post-process, or not?
*/
onBeforeFlush: function() {
},
/**
* By default this is an empty method hook that you can override and use in your own custom pipelines.
*
* This method is called immediately after this pipeline has finished flushing its batch.
*
* It is called after the `gl.drawArrays` call.
*
* You can perform additional post-render effects, but be careful not to call `flush`
* on this pipeline from within this method, or you'll cause an infinite loop.
*
* To apply changes pre-render, see `onBeforeFlush`.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#onAfterFlush
* @since 3.50.0
*
* @param {boolean} [isPostFlush=false] - Was this flush invoked as part of a post-process, or not?
*/
onAfterFlush: function() {
},
/**
* Adds a single vertex to the current vertex buffer and increments the
* `vertexCount` property by 1.
*
* This method is called directly by `batchTri` and `batchQuad`.
*
* It does not perform any batch limit checking itself, so if you need to call
* this method directly, do so in the same way that `batchQuad` does, for example.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#batchVert
* @since 3.50.0
*
* @param {number} x - The vertex x position.
* @param {number} y - The vertex y position.
* @param {number} u - UV u value.
* @param {number} v - UV v value.
* @param {number} unit - Texture unit to which the texture needs to be bound.
* @param {(number|boolean)} tintEffect - The tint effect for the shader to use.
* @param {number} tint - The tint color value.
*/
batchVert: function(x, y, u, v, unit, tintEffect, tint) {
var vertexViewF32 = this.vertexViewF32;
var vertexViewU32 = this.vertexViewU32;
var vertexOffset = this.vertexCount * this.currentShader.vertexComponentCount - 1;
vertexViewF32[++vertexOffset] = x;
vertexViewF32[++vertexOffset] = y;
vertexViewF32[++vertexOffset] = u;
vertexViewF32[++vertexOffset] = v;
vertexViewF32[++vertexOffset] = unit;
vertexViewF32[++vertexOffset] = tintEffect;
vertexViewU32[++vertexOffset] = tint;
this.vertexCount++;
this.currentBatch.count = this.vertexCount - this.currentBatch.start;
},
/**
* Adds the vertices data into the batch and flushes if full.
*
* Assumes 6 vertices in the following arrangement:
*
* ```
* 0----3
* |\ B|
* | \ |
* | \ |
* | A \|
* | \
* 1----2
* ```
*
* Where tx0/ty0 = 0, tx1/ty1 = 1, tx2/ty2 = 2 and tx3/ty3 = 3
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#batchQuad
* @since 3.50.0
*
* @param {(Phaser.GameObjects.GameObject|null)} gameObject - The Game Object, if any, drawing this quad.
* @param {number} x0 - The top-left x position.
* @param {number} y0 - The top-left y position.
* @param {number} x1 - The bottom-left x position.
* @param {number} y1 - The bottom-left y position.
* @param {number} x2 - The bottom-right x position.
* @param {number} y2 - The bottom-right y position.
* @param {number} x3 - The top-right x position.
* @param {number} y3 - The top-right y position.
* @param {number} u0 - UV u0 value.
* @param {number} v0 - UV v0 value.
* @param {number} u1 - UV u1 value.
* @param {number} v1 - UV v1 value.
* @param {number} tintTL - The top-left tint color value.
* @param {number} tintTR - The top-right tint color value.
* @param {number} tintBL - The bottom-left tint color value.
* @param {number} tintBR - The bottom-right tint color value.
* @param {(number|boolean)} tintEffect - The tint effect for the shader to use.
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} [texture] - Texture that will be assigned to the current batch if a flush occurs.
* @param {number} [unit=0] - Texture unit to which the texture needs to be bound.
*
* @return {boolean} `true` if this method caused the batch to flush, otherwise `false`.
*/
batchQuad: function(gameObject, x0, y0, x1, y1, x2, y2, x3, y3, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, unit) {
if (unit === void 0) {
unit = this.currentUnit;
}
var hasFlushed = false;
if (this.shouldFlush(6)) {
this.flush();
hasFlushed = true;
}
if (!this.currentBatch) {
unit = this.setTexture2D(texture);
}
var vertexViewF32 = this.vertexViewF32;
var vertexViewU32 = this.vertexViewU32;
var vertexOffset = this.vertexCount * this.currentShader.vertexComponentCount - 1;
vertexViewF32[++vertexOffset] = x0;
vertexViewF32[++vertexOffset] = y0;
vertexViewF32[++vertexOffset] = u0;
vertexViewF32[++vertexOffset] = v0;
vertexViewF32[++vertexOffset] = unit;
vertexViewF32[++vertexOffset] = tintEffect;
vertexViewU32[++vertexOffset] = tintTL;
vertexViewF32[++vertexOffset] = x1;
vertexViewF32[++vertexOffset] = y1;
vertexViewF32[++vertexOffset] = u0;
vertexViewF32[++vertexOffset] = v1;
vertexViewF32[++vertexOffset] = unit;
vertexViewF32[++vertexOffset] = tintEffect;
vertexViewU32[++vertexOffset] = tintBL;
vertexViewF32[++vertexOffset] = x2;
vertexViewF32[++vertexOffset] = y2;
vertexViewF32[++vertexOffset] = u1;
vertexViewF32[++vertexOffset] = v1;
vertexViewF32[++vertexOffset] = unit;
vertexViewF32[++vertexOffset] = tintEffect;
vertexViewU32[++vertexOffset] = tintBR;
vertexViewF32[++vertexOffset] = x0;
vertexViewF32[++vertexOffset] = y0;
vertexViewF32[++vertexOffset] = u0;
vertexViewF32[++vertexOffset] = v0;
vertexViewF32[++vertexOffset] = unit;
vertexViewF32[++vertexOffset] = tintEffect;
vertexViewU32[++vertexOffset] = tintTL;
vertexViewF32[++vertexOffset] = x2;
vertexViewF32[++vertexOffset] = y2;
vertexViewF32[++vertexOffset] = u1;
vertexViewF32[++vertexOffset] = v1;
vertexViewF32[++vertexOffset] = unit;
vertexViewF32[++vertexOffset] = tintEffect;
vertexViewU32[++vertexOffset] = tintBR;
vertexViewF32[++vertexOffset] = x3;
vertexViewF32[++vertexOffset] = y3;
vertexViewF32[++vertexOffset] = u1;
vertexViewF32[++vertexOffset] = v0;
vertexViewF32[++vertexOffset] = unit;
vertexViewF32[++vertexOffset] = tintEffect;
vertexViewU32[++vertexOffset] = tintTR;
this.vertexCount += 6;
this.currentBatch.count = this.vertexCount - this.currentBatch.start;
this.onBatch(gameObject);
return hasFlushed;
},
/**
* Adds the vertices data into the batch and flushes if full.
*
* Assumes 3 vertices in the following arrangement:
*
* ```
* 0
* |\
* | \
* | \
* | \
* | \
* 1-----2
* ```
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#batchTri
* @since 3.50.0
*
* @param {(Phaser.GameObjects.GameObject|null)} gameObject - The Game Object, if any, drawing this quad.
* @param {number} x1 - The bottom-left x position.
* @param {number} y1 - The bottom-left y position.
* @param {number} x2 - The bottom-right x position.
* @param {number} y2 - The bottom-right y position.
* @param {number} x3 - The top-right x position.
* @param {number} y3 - The top-right y position.
* @param {number} u0 - UV u0 value.
* @param {number} v0 - UV v0 value.
* @param {number} u1 - UV u1 value.
* @param {number} v1 - UV v1 value.
* @param {number} tintTL - The top-left tint color value.
* @param {number} tintTR - The top-right tint color value.
* @param {number} tintBL - The bottom-left tint color value.
* @param {(number|boolean)} tintEffect - The tint effect for the shader to use.
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} [texture] - Texture that will be assigned to the current batch if a flush occurs.
* @param {number} [unit=0] - Texture unit to which the texture needs to be bound.
*
* @return {boolean} `true` if this method caused the batch to flush, otherwise `false`.
*/
batchTri: function(gameObject, x0, y0, x1, y1, x2, y2, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintEffect, texture, unit) {
if (unit === void 0) {
unit = this.currentUnit;
}
var hasFlushed = false;
if (this.shouldFlush(3)) {
this.flush();
hasFlushed = true;
}
if (!this.currentBatch) {
unit = this.setTexture2D(texture);
}
var vertexViewF32 = this.vertexViewF32;
var vertexViewU32 = this.vertexViewU32;
var vertexOffset = this.vertexCount * this.currentShader.vertexComponentCount - 1;
vertexViewF32[++vertexOffset] = x0;
vertexViewF32[++vertexOffset] = y0;
vertexViewF32[++vertexOffset] = u0;
vertexViewF32[++vertexOffset] = v0;
vertexViewF32[++vertexOffset] = unit;
vertexViewF32[++vertexOffset] = tintEffect;
vertexViewU32[++vertexOffset] = tintTL;
vertexViewF32[++vertexOffset] = x1;
vertexViewF32[++vertexOffset] = y1;
vertexViewF32[++vertexOffset] = u0;
vertexViewF32[++vertexOffset] = v1;
vertexViewF32[++vertexOffset] = unit;
vertexViewF32[++vertexOffset] = tintEffect;
vertexViewU32[++vertexOffset] = tintTR;
vertexViewF32[++vertexOffset] = x2;
vertexViewF32[++vertexOffset] = y2;
vertexViewF32[++vertexOffset] = u1;
vertexViewF32[++vertexOffset] = v1;
vertexViewF32[++vertexOffset] = unit;
vertexViewF32[++vertexOffset] = tintEffect;
vertexViewU32[++vertexOffset] = tintBL;
this.vertexCount += 3;
this.currentBatch.count = this.vertexCount - this.currentBatch.start;
this.onBatch(gameObject);
return hasFlushed;
},
/**
* Pushes a filled rectangle into the vertex batch.
*
* The dimensions are run through `Math.floor` before the quad is generated.
*
* Rectangle has no transform values and isn't transformed into the local space.
*
* Used for directly batching untransformed rectangles, such as Camera background colors.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#drawFillRect
* @since 3.50.0
*
* @param {number} x - Horizontal top left coordinate of the rectangle.
* @param {number} y - Vertical top left coordinate of the rectangle.
* @param {number} width - Width of the rectangle.
* @param {number} height - Height of the rectangle.
* @param {number} color - Color of the rectangle to draw.
* @param {number} alpha - Alpha value of the rectangle to draw.
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} [texture] - texture that will be assigned to the current batch if a flush occurs.
* @param {boolean} [flipUV=true] - Flip the vertical UV coordinates of the texture before rendering?
*/
drawFillRect: function(x, y, width, height, color, alpha, texture, flipUV) {
if (texture === void 0) {
texture = this.renderer.whiteTexture;
}
if (flipUV === void 0) {
flipUV = true;
}
x = Math.floor(x);
y = Math.floor(y);
var xw = Math.floor(x + width);
var yh = Math.floor(y + height);
var unit = this.setTexture2D(texture);
var tint = Utils.getTintAppendFloatAlphaAndSwap(color, alpha);
var u0 = 0;
var v0 = 0;
var u1 = 1;
var v1 = 1;
if (flipUV) {
v0 = 1;
v1 = 0;
}
this.batchQuad(null, x, y, x, yh, xw, yh, xw, y, u0, v0, u1, v1, tint, tint, tint, tint, 0, texture, unit);
},
/**
* Sets the texture to be bound to the next available texture unit and returns
* the unit id.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setTexture2D
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} [texture] - Texture that will be assigned to the current batch. If not given uses `whiteTexture`.
*
* @return {number} The assigned texture unit.
*/
setTexture2D: function(texture) {
if (texture === void 0) {
texture = this.renderer.whiteTexture;
}
return this.pushBatch(texture);
},
/**
* Activates the given WebGL Texture and binds it to the requested texture slot.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#bindTexture
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} [target] - Texture to activate and bind.
* @param {number} [unit=0] - The WebGL texture ID to activate. Defaults to `gl.TEXTURE0`.
*
* @return {this} This WebGL Pipeline instance.
*/
bindTexture: function(texture, unit) {
if (unit === void 0) {
unit = 0;
}
var gl = this.gl;
gl.activeTexture(gl.TEXTURE0 + unit);
gl.bindTexture(gl.TEXTURE_2D, texture.webGLTexture);
return this;
},
/**
* Activates the given Render Target texture and binds it to the
* requested WebGL texture slot.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#bindRenderTarget
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The Render Target to activate and bind.
* @param {number} [unit=0] - The WebGL texture ID to activate. Defaults to `gl.TEXTURE0`.
*
* @return {this} This WebGL Pipeline instance.
*/
bindRenderTarget: function(target, unit) {
return this.bindTexture(target.texture, unit);
},
/**
* Sets the current duration into a 1f uniform value based on the given name.
*
* This can be used for mapping time uniform values, such as `iTime`.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setTime
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used.
*
* @return {this} This WebGLPipeline instance.
*/
setTime: function(name, shader) {
this.set1f(name, this.game.loop.getDuration(), shader);
return this;
},
/**
* Sets a boolean uniform value based on the given name on the currently set shader.
*
* The current shader is bound, before the uniform is set, making it active within the
* WebGLRenderer. This means you can safely call this method from a location such as
* a Scene `create` or `update` method. However, when working within a Shader file
* directly, use the `WebGLShader` method equivalent instead, to avoid the program
* being set.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setBoolean
* @since 3.60.0
*
* @param {string} name - The name of the uniform to set.
* @param {boolean} value - The new value of the `boolean` uniform.
* @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used.
*
* @return {this} This WebGLPipeline instance.
*/
setBoolean: function(name, value, shader) {
if (shader === void 0) {
shader = this.currentShader;
}
shader.setBoolean(name, value);
return this;
},
/**
* Sets a 1f uniform value based on the given name on the currently set shader.
*
* The current shader is bound, before the uniform is set, making it active within the
* WebGLRenderer. This means you can safely call this method from a location such as
* a Scene `create` or `update` method. However, when working within a Shader file
* directly, use the `WebGLShader` method equivalent instead, to avoid the program
* being set.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#set1f
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number} x - The new value of the `float` uniform.
* @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used.
*
* @return {this} This WebGLPipeline instance.
*/
set1f: function(name, x, shader) {
if (shader === void 0) {
shader = this.currentShader;
}
shader.set1f(name, x);
return this;
},
/**
* Sets a 2f uniform value based on the given name on the currently set shader.
*
* The current shader is bound, before the uniform is set, making it active within the
* WebGLRenderer. This means you can safely call this method from a location such as
* a Scene `create` or `update` method. However, when working within a Shader file
* directly, use the `WebGLShader` method equivalent instead, to avoid the program
* being set.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#set2f
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number} x - The new X component of the `vec2` uniform.
* @param {number} y - The new Y component of the `vec2` uniform.
* @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used.
*
* @return {this} This WebGLPipeline instance.
*/
set2f: function(name, x, y, shader) {
if (shader === void 0) {
shader = this.currentShader;
}
shader.set2f(name, x, y);
return this;
},
/**
* Sets a 3f uniform value based on the given name on the currently set shader.
*
* The current shader is bound, before the uniform is set, making it active within the
* WebGLRenderer. This means you can safely call this method from a location such as
* a Scene `create` or `update` method. However, when working within a Shader file
* directly, use the `WebGLShader` method equivalent instead, to avoid the program
* being set.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#set3f
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number} x - The new X component of the `vec3` uniform.
* @param {number} y - The new Y component of the `vec3` uniform.
* @param {number} z - The new Z component of the `vec3` uniform.
* @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used.
*
* @return {this} This WebGLPipeline instance.
*/
set3f: function(name, x, y, z, shader) {
if (shader === void 0) {
shader = this.currentShader;
}
shader.set3f(name, x, y, z);
return this;
},
/**
* Sets a 4f uniform value based on the given name on the currently set shader.
*
* The current shader is bound, before the uniform is set, making it active within the
* WebGLRenderer. This means you can safely call this method from a location such as
* a Scene `create` or `update` method. However, when working within a Shader file
* directly, use the `WebGLShader` method equivalent instead, to avoid the program
* being set.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#set4f
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number} x - X component of the uniform
* @param {number} y - Y component of the uniform
* @param {number} z - Z component of the uniform
* @param {number} w - W component of the uniform
* @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used.
*
* @return {this} This WebGLPipeline instance.
*/
set4f: function(name, x, y, z, w, shader) {
if (shader === void 0) {
shader = this.currentShader;
}
shader.set4f(name, x, y, z, w);
return this;
},
/**
* Sets a 1fv uniform value based on the given name on the currently set shader.
*
* The current shader is bound, before the uniform is set, making it active within the
* WebGLRenderer. This means you can safely call this method from a location such as
* a Scene `create` or `update` method. However, when working within a Shader file
* directly, use the `WebGLShader` method equivalent instead, to avoid the program
* being set.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#set1fv
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number[]|Float32Array} arr - The new value to be used for the uniform variable.
* @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used.
*
* @return {this} This WebGLPipeline instance.
*/
set1fv: function(name, arr, shader) {
if (shader === void 0) {
shader = this.currentShader;
}
shader.set1fv(name, arr);
return this;
},
/**
* Sets a 2fv uniform value based on the given name on the currently set shader.
*
* The current shader is bound, before the uniform is set, making it active within the
* WebGLRenderer. This means you can safely call this method from a location such as
* a Scene `create` or `update` method. However, when working within a Shader file
* directly, use the `WebGLShader` method equivalent instead, to avoid the program
* being set.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#set2fv
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number[]|Float32Array} arr - The new value to be used for the uniform variable.
* @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used.
*
* @return {this} This WebGLPipeline instance.
*/
set2fv: function(name, arr, shader) {
if (shader === void 0) {
shader = this.currentShader;
}
shader.set2fv(name, arr);
return this;
},
/**
* Sets a 3fv uniform value based on the given name on the currently set shader.
*
* The current shader is bound, before the uniform is set, making it active within the
* WebGLRenderer. This means you can safely call this method from a location such as
* a Scene `create` or `update` method. However, when working within a Shader file
* directly, use the `WebGLShader` method equivalent instead, to avoid the program
* being set.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#set3fv
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number[]|Float32Array} arr - The new value to be used for the uniform variable.
* @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used.
*
* @return {this} This WebGLPipeline instance.
*/
set3fv: function(name, arr, shader) {
if (shader === void 0) {
shader = this.currentShader;
}
shader.set3fv(name, arr);
return this;
},
/**
* Sets a 4fv uniform value based on the given name on the currently set shader.
*
* The current shader is bound, before the uniform is set, making it active within the
* WebGLRenderer. This means you can safely call this method from a location such as
* a Scene `create` or `update` method. However, when working within a Shader file
* directly, use the `WebGLShader` method equivalent instead, to avoid the program
* being set.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#set4fv
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number[]|Float32Array} arr - The new value to be used for the uniform variable.
* @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used.
*
* @return {this} This WebGLPipeline instance.
*/
set4fv: function(name, arr, shader) {
if (shader === void 0) {
shader = this.currentShader;
}
shader.set4fv(name, arr);
return this;
},
/**
* Sets a 1iv uniform value based on the given name on the currently set shader.
*
* The current shader is bound, before the uniform is set, making it active within the
* WebGLRenderer. This means you can safely call this method from a location such as
* a Scene `create` or `update` method. However, when working within a Shader file
* directly, use the `WebGLShader` method equivalent instead, to avoid the program
* being set.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#set1iv
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number[]|Float32Array} arr - The new value to be used for the uniform variable.
* @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used.
*
* @return {this} This WebGLPipeline instance.
*/
set1iv: function(name, arr, shader) {
if (shader === void 0) {
shader = this.currentShader;
}
shader.set1iv(name, arr);
return this;
},
/**
* Sets a 2iv uniform value based on the given name on the currently set shader.
*
* The current shader is bound, before the uniform is set, making it active within the
* WebGLRenderer. This means you can safely call this method from a location such as
* a Scene `create` or `update` method. However, when working within a Shader file
* directly, use the `WebGLShader` method equivalent instead, to avoid the program
* being set.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#set2iv
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number[]|Float32Array} arr - The new value to be used for the uniform variable.
* @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used.
*
* @return {this} This WebGLPipeline instance.
*/
set2iv: function(name, arr, shader) {
if (shader === void 0) {
shader = this.currentShader;
}
shader.set2iv(name, arr);
return this;
},
/**
* Sets a 3iv uniform value based on the given name on the currently set shader.
*
* The current shader is bound, before the uniform is set, making it active within the
* WebGLRenderer. This means you can safely call this method from a location such as
* a Scene `create` or `update` method. However, when working within a Shader file
* directly, use the `WebGLShader` method equivalent instead, to avoid the program
* being set.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#set3iv
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number[]|Float32Array} arr - The new value to be used for the uniform variable.
* @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used.
*
* @return {this} This WebGLPipeline instance.
*/
set3iv: function(name, arr, shader) {
if (shader === void 0) {
shader = this.currentShader;
}
shader.set3iv(name, arr);
return this;
},
/**
* Sets a 4iv uniform value based on the given name on the currently set shader.
*
* The current shader is bound, before the uniform is set, making it active within the
* WebGLRenderer. This means you can safely call this method from a location such as
* a Scene `create` or `update` method. However, when working within a Shader file
* directly, use the `WebGLShader` method equivalent instead, to avoid the program
* being set.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#set4iv
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number[]|Float32Array} arr - The new value to be used for the uniform variable.
* @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used.
*
* @return {this} This WebGLPipeline instance.
*/
set4iv: function(name, arr, shader) {
if (shader === void 0) {
shader = this.currentShader;
}
shader.set4iv(name, arr);
return this;
},
/**
* Sets a 1i uniform value based on the given name on the currently set shader.
*
* The current shader is bound, before the uniform is set, making it active within the
* WebGLRenderer. This means you can safely call this method from a location such as
* a Scene `create` or `update` method. However, when working within a Shader file
* directly, use the `WebGLShader` method equivalent instead, to avoid the program
* being set.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#set1i
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number} x - The new value of the `int` uniform.
* @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used.
*
* @return {this} This WebGLPipeline instance.
*/
set1i: function(name, x, shader) {
if (shader === void 0) {
shader = this.currentShader;
}
shader.set1i(name, x);
return this;
},
/**
* Sets a 2i uniform value based on the given name on the currently set shader.
*
* The current shader is bound, before the uniform is set, making it active within the
* WebGLRenderer. This means you can safely call this method from a location such as
* a Scene `create` or `update` method. However, when working within a Shader file
* directly, use the `WebGLShader` method equivalent instead, to avoid the program
* being set.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#set2i
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number} x - The new X component of the `ivec2` uniform.
* @param {number} y - The new Y component of the `ivec2` uniform.
* @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used.
*
* @return {this} This WebGLPipeline instance.
*/
set2i: function(name, x, y, shader) {
if (shader === void 0) {
shader = this.currentShader;
}
shader.set2i(name, x, y);
return this;
},
/**
* Sets a 3i uniform value based on the given name on the currently set shader.
*
* The current shader is bound, before the uniform is set, making it active within the
* WebGLRenderer. This means you can safely call this method from a location such as
* a Scene `create` or `update` method. However, when working within a Shader file
* directly, use the `WebGLShader` method equivalent instead, to avoid the program
* being set.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#set3i
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number} x - The new X component of the `ivec3` uniform.
* @param {number} y - The new Y component of the `ivec3` uniform.
* @param {number} z - The new Z component of the `ivec3` uniform.
* @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used.
*
* @return {this} This WebGLPipeline instance.
*/
set3i: function(name, x, y, z, shader) {
if (shader === void 0) {
shader = this.currentShader;
}
shader.set3i(name, x, y, z);
return this;
},
/**
* Sets a 4i uniform value based on the given name on the currently set shader.
*
* The current shader is bound, before the uniform is set, making it active within the
* WebGLRenderer. This means you can safely call this method from a location such as
* a Scene `create` or `update` method. However, when working within a Shader file
* directly, use the `WebGLShader` method equivalent instead, to avoid the program
* being set.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#set4i
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number} x - X component of the uniform.
* @param {number} y - Y component of the uniform.
* @param {number} z - Z component of the uniform.
* @param {number} w - W component of the uniform.
* @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used.
*
* @return {this} This WebGLPipeline instance.
*/
set4i: function(name, x, y, z, w, shader) {
if (shader === void 0) {
shader = this.currentShader;
}
shader.set4i(name, x, y, z, w);
return this;
},
/**
* Sets a matrix 2fv uniform value based on the given name on the currently set shader.
*
* The current shader is bound, before the uniform is set, making it active within the
* WebGLRenderer. This means you can safely call this method from a location such as
* a Scene `create` or `update` method. However, when working within a Shader file
* directly, use the `WebGLShader` method equivalent instead, to avoid the program
* being set.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setMatrix2fv
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {boolean} transpose - Whether to transpose the matrix. Should be `false`.
* @param {number[]|Float32Array} matrix - The new values for the `mat2` uniform.
* @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used.
*
* @return {this} This WebGLPipeline instance.
*/
setMatrix2fv: function(name, transpose, matrix, shader) {
if (shader === void 0) {
shader = this.currentShader;
}
shader.setMatrix2fv(name, transpose, matrix);
return this;
},
/**
* Sets a matrix 3fv uniform value based on the given name on the currently set shader.
*
* The current shader is bound, before the uniform is set, making it active within the
* WebGLRenderer. This means you can safely call this method from a location such as
* a Scene `create` or `update` method. However, when working within a Shader file
* directly, use the `WebGLShader` method equivalent instead, to avoid the program
* being set.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setMatrix3fv
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {boolean} transpose - Whether to transpose the matrix. Should be `false`.
* @param {Float32Array} matrix - The new values for the `mat3` uniform.
* @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used.
*
* @return {this} This WebGLPipeline instance.
*/
setMatrix3fv: function(name, transpose, matrix, shader) {
if (shader === void 0) {
shader = this.currentShader;
}
shader.setMatrix3fv(name, transpose, matrix);
return this;
},
/**
* Sets a matrix 4fv uniform value based on the given name on the currently set shader.
*
* The current shader is bound, before the uniform is set, making it active within the
* WebGLRenderer. This means you can safely call this method from a location such as
* a Scene `create` or `update` method. However, when working within a Shader file
* directly, use the `WebGLShader` method equivalent instead, to avoid the program
* being set.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#setMatrix4fv
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {boolean} transpose - Whether to transpose the matrix. Should be `false`.
* @param {Float32Array} matrix - The matrix data. If using a Matrix4 this should be the `Matrix4.val` property.
* @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to set the value on. If not given, the `currentShader` is used.
*
* @return {this} This WebGLPipeline instance.
*/
setMatrix4fv: function(name, transpose, matrix, shader) {
if (shader === void 0) {
shader = this.currentShader;
}
shader.setMatrix4fv(name, transpose, matrix);
return this;
},
/**
* Destroys all shader instances, removes all object references and nulls all external references.
*
* @method Phaser.Renderer.WebGL.WebGLPipeline#destroy
* @fires Phaser.Renderer.WebGL.Pipelines.Events#DESTROY
* @since 3.0.0
*
* @return {this} This WebGLPipeline instance.
*/
destroy: function() {
this.emit(Events.DESTROY, this);
var i;
var shaders = this.shaders;
for (i = 0; i < shaders.length; i++) {
shaders[i].destroy();
}
var targets = this.renderTargets;
for (i = 0; i < targets.length; i++) {
targets[i].destroy();
}
var renderer = this.renderer;
renderer.deleteBuffer(this.vertexBuffer);
renderer.off(RendererEvents.RESIZE, this.resize, this);
renderer.off(RendererEvents.PRE_RENDER, this.onPreRender, this);
renderer.off(RendererEvents.RENDER, this.onRender, this);
renderer.off(RendererEvents.POST_RENDER, this.onPostRender, this);
this.removeAllListeners();
this.game = null;
this.renderer = null;
this.manager = null;
this.gl = null;
this.view = null;
this.shaders = null;
this.renderTargets = null;
this.bytes = null;
this.vertexViewF32 = null;
this.vertexViewU32 = null;
this.vertexData = null;
this.vertexBuffer = null;
this.currentShader = null;
this.currentRenderTarget = null;
this.activeTextures = null;
return this;
}
});
module2.exports = WebGLPipeline;
}
),
/***/
74797: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var ArrayEach = __webpack_require__2(95428);
var ArrayRemove = __webpack_require__2(72905);
var CameraEvents = __webpack_require__2(19715);
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(8054);
var EventEmitter = __webpack_require__2(50792);
var Events = __webpack_require__2(92503);
var IsSizePowerOfTwo = __webpack_require__2(50030);
var Matrix4 = __webpack_require__2(37867);
var NOOP = __webpack_require__2(29747);
var PipelineManager = __webpack_require__2(7530);
var RenderTarget = __webpack_require__2(32302);
var ScaleEvents = __webpack_require__2(97480);
var TextureEvents = __webpack_require__2(69442);
var Utils = __webpack_require__2(70554);
var WebGLSnapshot = __webpack_require__2(88815);
var WebGLBufferWrapper = __webpack_require__2(26128);
var WebGLProgramWrapper = __webpack_require__2(1482);
var WebGLTextureWrapper = __webpack_require__2(82751);
var WebGLFramebufferWrapper = __webpack_require__2(84387);
var WebGLAttribLocationWrapper = __webpack_require__2(93567);
var WebGLUniformLocationWrapper = __webpack_require__2(57183);
var DEBUG = false;
if (false) {
var SPECTOR;
}
var WebGLRenderer = new Class({
Extends: EventEmitter,
initialize: function WebGLRenderer2(game) {
EventEmitter.call(this);
var gameConfig = game.config;
var contextCreationConfig = {
alpha: gameConfig.transparent,
desynchronized: gameConfig.desynchronized,
depth: true,
antialias: gameConfig.antialiasGL,
premultipliedAlpha: gameConfig.premultipliedAlpha,
stencil: true,
failIfMajorPerformanceCaveat: gameConfig.failIfMajorPerformanceCaveat,
powerPreference: gameConfig.powerPreference,
preserveDrawingBuffer: gameConfig.preserveDrawingBuffer,
willReadFrequently: false
};
this.config = {
clearBeforeRender: gameConfig.clearBeforeRender,
antialias: gameConfig.antialias,
backgroundColor: gameConfig.backgroundColor,
contextCreation: contextCreationConfig,
roundPixels: gameConfig.roundPixels,
maxTextures: gameConfig.maxTextures,
maxTextureSize: gameConfig.maxTextureSize,
batchSize: gameConfig.batchSize,
maxLights: gameConfig.maxLights,
mipmapFilter: gameConfig.mipmapFilter
};
this.game = game;
this.type = CONST.WEBGL;
this.pipelines = null;
this.width = 0;
this.height = 0;
this.canvas = game.canvas;
this.blendModes = [];
this.contextLost = false;
this.snapshotState = {
x: 0,
y: 0,
width: 1,
height: 1,
getPixel: false,
callback: null,
type: "image/png",
encoder: 0.92,
isFramebuffer: false,
bufferWidth: 0,
bufferHeight: 0
};
this.maxTextures = 0;
this.textureIndexes;
this.glBufferWrappers = [];
this.glProgramWrappers = [];
this.glTextureWrappers = [];
this.glFramebufferWrappers = [];
this.glAttribLocationWrappers = [];
this.glUniformLocationWrappers = [];
this.currentFramebuffer = null;
this.fboStack = [];
this.currentProgram = null;
this.currentBlendMode = Infinity;
this.currentScissorEnabled = false;
this.currentScissor = null;
this.scissorStack = [];
this.contextLostHandler = NOOP;
this.contextRestoredHandler = NOOP;
this.previousContextLostHandler = NOOP;
this.previousContextRestoredHandler = NOOP;
this.gl = null;
this.supportedExtensions = null;
this.instancedArraysExtension = null;
this.vaoExtension = null;
this.extensions = {};
this.glFormats;
this.compression;
this.drawingBufferHeight = 0;
this.blankTexture = null;
this.normalTexture = null;
this.whiteTexture = null;
this.maskCount = 0;
this.maskStack = [];
this.currentMask = { mask: null, camera: null };
this.currentCameraMask = { mask: null, camera: null };
this.glFuncMap = null;
this.currentType = "";
this.newType = false;
this.nextTypeMatch = false;
this.finalType = false;
this.mipmapFilter = null;
this.defaultScissor = [0, 0, 0, 0];
this.isBooted = false;
this.renderTarget = null;
this.projectionMatrix;
this.projectionWidth = 0;
this.projectionHeight = 0;
this.maskSource = null;
this.maskTarget = null;
this.spector = null;
this._debugCapture = false;
this.init(this.config);
},
/**
* Creates a new WebGLRenderingContext and initializes all internal state.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#init
* @since 3.0.0
*
* @param {object} config - The configuration object for the renderer.
*
* @return {this} This WebGLRenderer instance.
*/
init: function(config) {
var gl;
var game = this.game;
var canvas = this.canvas;
var clearColor = config.backgroundColor;
if (DEBUG) {
this.spector = new SPECTOR.Spector();
this.spector.onCapture.add(this.onCapture.bind(this));
}
if (game.config.context) {
gl = game.config.context;
} else {
gl = canvas.getContext("webgl", config.contextCreation) || canvas.getContext("experimental-webgl", config.contextCreation);
}
if (!gl || gl.isContextLost()) {
this.contextLost = true;
throw new Error("WebGL unsupported");
}
this.gl = gl;
this.setExtensions();
this.setContextHandlers();
game.context = gl;
for (var i = 0; i <= 27; i++) {
this.blendModes.push({ func: [gl.ONE, gl.ONE_MINUS_SRC_ALPHA], equation: gl.FUNC_ADD });
}
this.blendModes[1].func = [gl.ONE, gl.DST_ALPHA];
this.blendModes[2].func = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA];
this.blendModes[3].func = [gl.ONE, gl.ONE_MINUS_SRC_COLOR];
this.blendModes[17] = { func: [gl.ZERO, gl.ONE_MINUS_SRC_ALPHA], equation: gl.FUNC_REVERSE_SUBTRACT };
this.glFormats = [gl.BYTE, gl.SHORT, gl.UNSIGNED_BYTE, gl.UNSIGNED_SHORT, gl.FLOAT];
this.glFuncMap = {
mat2: { func: gl.uniformMatrix2fv, length: 1, matrix: true },
mat3: { func: gl.uniformMatrix3fv, length: 1, matrix: true },
mat4: { func: gl.uniformMatrix4fv, length: 1, matrix: true },
"1f": { func: gl.uniform1f, length: 1 },
"1fv": { func: gl.uniform1fv, length: 1 },
"1i": { func: gl.uniform1i, length: 1 },
"1iv": { func: gl.uniform1iv, length: 1 },
"2f": { func: gl.uniform2f, length: 2 },
"2fv": { func: gl.uniform2fv, length: 1 },
"2i": { func: gl.uniform2i, length: 2 },
"2iv": { func: gl.uniform2iv, length: 1 },
"3f": { func: gl.uniform3f, length: 3 },
"3fv": { func: gl.uniform3fv, length: 1 },
"3i": { func: gl.uniform3i, length: 3 },
"3iv": { func: gl.uniform3iv, length: 1 },
"4f": { func: gl.uniform4f, length: 4 },
"4fv": { func: gl.uniform4fv, length: 1 },
"4i": { func: gl.uniform4i, length: 4 },
"4iv": { func: gl.uniform4iv, length: 1 }
};
if (!config.maxTextures || config.maxTextures === -1) {
config.maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
}
if (!config.maxTextureSize) {
config.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
}
this.compression = this.getCompressedTextures();
gl.disable(gl.DEPTH_TEST);
gl.disable(gl.CULL_FACE);
gl.enable(gl.BLEND);
gl.clearColor(clearColor.redGL, clearColor.greenGL, clearColor.blueGL, clearColor.alphaGL);
var validMipMaps = ["NEAREST", "LINEAR", "NEAREST_MIPMAP_NEAREST", "LINEAR_MIPMAP_NEAREST", "NEAREST_MIPMAP_LINEAR", "LINEAR_MIPMAP_LINEAR"];
if (validMipMaps.indexOf(config.mipmapFilter) !== -1) {
this.mipmapFilter = gl[config.mipmapFilter];
}
this.maxTextures = Utils.checkShaderMax(gl, config.maxTextures);
this.textureIndexes = [];
this.createTemporaryTextures();
this.pipelines = new PipelineManager(this);
this.setBlendMode(CONST.BlendModes.NORMAL);
this.projectionMatrix = new Matrix4().identity();
game.textures.once(TextureEvents.READY, this.boot, this);
return this;
},
/**
* Internal boot handler. Calls 'boot' on each pipeline.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#boot
* @private
* @since 3.11.0
*/
boot: function() {
var game = this.game;
var pipelineManager = this.pipelines;
var baseSize = game.scale.baseSize;
var width = baseSize.width;
var height = baseSize.height;
this.width = width;
this.height = height;
this.isBooted = true;
this.renderTarget = new RenderTarget(this, width, height, 1, 0, true, true);
this.maskTarget = new RenderTarget(this, width, height, 1, 0, true, true);
this.maskSource = new RenderTarget(this, width, height, 1, 0, true, true);
var config = game.config;
pipelineManager.boot(config.pipeline, config.defaultPipeline, config.autoMobilePipeline);
this.blankTexture = game.textures.getFrame("__DEFAULT").glTexture;
this.normalTexture = game.textures.getFrame("__NORMAL").glTexture;
this.whiteTexture = game.textures.getFrame("__WHITE").glTexture;
var gl = this.gl;
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.enable(gl.SCISSOR_TEST);
game.scale.on(ScaleEvents.RESIZE, this.onResize, this);
this.resize(width, height);
},
/**
* Queries the GL context to get the supported extensions.
*
* Then sets them into the `supportedExtensions`, `instancedArraysExtension` and `vaoExtension` properties.
*
* Called automatically during the `init` method.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setExtensions
* @since 3.85.2
*/
setExtensions: function() {
var gl = this.gl;
var exts = gl.getSupportedExtensions();
this.supportedExtensions = exts;
var angleString = "ANGLE_instanced_arrays";
this.instancedArraysExtension = exts.indexOf(angleString) > -1 ? gl.getExtension(angleString) : null;
var vaoString = "OES_vertex_array_object";
this.vaoExtension = exts.indexOf(vaoString) > -1 ? gl.getExtension(vaoString) : null;
},
/**
* Sets the handlers that are called when WebGL context is lost or restored by the browser.
*
* The default handlers are referenced via the properties `WebGLRenderer.contextLostHandler` and `WebGLRenderer.contextRestoredHandler`.
* By default, these map to the methods `WebGLRenderer.dispatchContextLost` and `WebGLRenderer.dispatchContextRestored`.
*
* You can override these handlers with your own via this method.
*
* If you do override them, make sure that your handlers invoke the methods `WebGLRenderer.dispatchContextLost` and `WebGLRenderer.dispatchContextRestored` in due course, otherwise the renderer will not be able to restore itself fully.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setContextHandlers
* @since 3.85.0
*
* @param {function} [contextLost] - Custom handler for responding to the WebGL context lost event. Set as `undefined` to use the default handler.
* @param {function} [contextRestored] - Custom handler for responding to the WebGL context restored event. Set as `undefined` to use the default handler.
*/
setContextHandlers: function(contextLost, contextRestored) {
if (this.previousContextLostHandler) {
this.canvas.removeEventListener("webglcontextlost", this.previousContextLostHandler, false);
}
if (this.previousContextRestoredHandler) {
this.canvas.removeEventListener("webglcontextlost", this.previousContextRestoredHandler, false);
}
if (typeof contextLost === "function") {
this.contextLostHandler = contextLost.bind(this);
} else {
this.contextLostHandler = this.dispatchContextLost.bind(this);
}
if (typeof contextRestored === "function") {
this.contextRestoredHandler = contextRestored.bind(this);
} else {
this.contextRestoredHandler = this.dispatchContextRestored.bind(this);
}
this.canvas.addEventListener("webglcontextlost", this.contextLostHandler, false);
this.canvas.addEventListener("webglcontextrestored", this.contextRestoredHandler, false);
this.previousContextLostHandler = this.contextLostHandler;
this.previousContextRestoredHandler = this.contextRestoredHandler;
},
/**
* This method is called when the WebGL context is lost. By default this is bound to the property `WebGLRenderer.contextLostHandler`.
* If you override the context loss handler via the `setContextHandlers` method then be sure to invoke this method in due course.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#dispatchContextLost
* @since 3.85.0
*
* @param {WebGLContextEvent } event - The WebGL context lost Event.
*/
dispatchContextLost: function(event) {
this.contextLost = true;
if (console) {
console.warn("WebGL Context lost. Renderer disabled");
}
this.emit(Events.LOSE_WEBGL, this);
event.preventDefault();
},
/**
* This method is called when the WebGL context is restored. By default this is bound to the property `WebGLRenderer.contextRestoredHandler`.
* If you override the context restored handler via the `setContextHandlers` method then be sure to invoke this method in due course.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#dispatchContextRestored
* @since 3.85.0
*
* @param {WebGLContextEvent } event - The WebGL context restored Event.
*/
dispatchContextRestored: function(event) {
var gl = this.gl;
if (gl.isContextLost()) {
if (console) {
console.log("WebGL Context restored, but context is still lost");
}
return;
}
this.currentProgram = null;
this.currentFramebuffer = null;
this.setBlendMode(CONST.BlendModes.NORMAL);
gl.disable(gl.BLEND);
gl.disable(gl.DEPTH_TEST);
gl.enable(gl.CULL_FACE);
this.compression = this.getCompressedTextures();
var wrapperCreateResource = function(wrapper) {
wrapper.createResource();
};
ArrayEach(this.glTextureWrappers, wrapperCreateResource);
ArrayEach(this.glBufferWrappers, wrapperCreateResource);
ArrayEach(this.glFramebufferWrappers, wrapperCreateResource);
ArrayEach(this.glProgramWrappers, wrapperCreateResource);
ArrayEach(this.glAttribLocationWrappers, wrapperCreateResource);
ArrayEach(this.glUniformLocationWrappers, wrapperCreateResource);
this.createTemporaryTextures();
this.pipelines.restoreContext();
this.resize(this.game.scale.baseSize.width, this.game.scale.baseSize.height);
this.setExtensions();
this.contextLost = false;
if (console) {
console.warn("WebGL Context restored. Renderer running again.");
}
this.emit(Events.RESTORE_WEBGL, this);
event.preventDefault();
},
/**
* Create temporary WebGL textures to stop WebGL errors on macOS.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#createTemporaryTextures
* @since 3.60.0
*/
createTemporaryTextures: function() {
var gl = this.gl;
for (var index = 0; index < this.maxTextures; index++) {
var tempTexture = gl.createTexture();
gl.activeTexture(gl.TEXTURE0 + index);
gl.bindTexture(gl.TEXTURE_2D, tempTexture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 255, 255]));
this.textureIndexes.push(index);
}
},
/**
* This method is only available in the Debug Build of Phaser, or a build with the
* `WEBGL_DEBUG` flag set in the Webpack Config.
*
* Phaser v3.60 Debug has a build of Spector.js embedded in it, which is a WebGL inspector
* that allows for live inspection of your WebGL calls. Although it's easy to add the Spector
* extension to a desktop browsr, by embedding it in Phaser we can make it available in mobile
* browsers too, making it a powerful tool for debugging WebGL games on mobile devices where
* extensions are not permitted.
*
* See https://github.com/BabylonJS/Spector.js for more details.
*
* This method will capture the current WebGL frame and send it to the Spector.js tool for inspection.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#captureFrame
* @since 3.60.0
*
* @param {boolean} [quickCapture=false] - If `true` thumbnails are not captured in order to speed up the capture.
* @param {boolean} [fullCapture=false] - If `true` all details are captured.
*/
captureFrame: function(quickCapture, fullCapture) {
if (quickCapture === void 0) {
quickCapture = false;
}
if (fullCapture === void 0) {
fullCapture = false;
}
if (DEBUG && this.spector && !this._debugCapture) {
this.spector.captureCanvas(this.canvas, 0, quickCapture, fullCapture);
this._debugCapture = true;
}
},
/**
* This method is only available in the Debug Build of Phaser, or a build with the
* `WEBGL_DEBUG` flag set in the Webpack Config.
*
* Phaser v3.60 Debug has a build of Spector.js embedded in it, which is a WebGL inspector
* that allows for live inspection of your WebGL calls. Although it's easy to add the Spector
* extension to a desktop browsr, by embedding it in Phaser we can make it available in mobile
* browsers too, making it a powerful tool for debugging WebGL games on mobile devices where
* extensions are not permitted.
*
* See https://github.com/BabylonJS/Spector.js for more details.
*
* This method will capture the next WebGL frame and send it to the Spector.js tool for inspection.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#captureNextFrame
* @since 3.60.0
*/
captureNextFrame: function() {
if (DEBUG && this.spector && !this._debugCapture) {
this._debugCapture = true;
this.spector.captureNextFrame(this.canvas);
}
},
/**
* This method is only available in the Debug Build of Phaser, or a build with the
* `WEBGL_DEBUG` flag set in the Webpack Config.
*
* Phaser v3.60 Debug has a build of Spector.js embedded in it, which is a WebGL inspector
* that allows for live inspection of your WebGL calls. Although it's easy to add the Spector
* extension to a desktop browsr, by embedding it in Phaser we can make it available in mobile
* browsers too, making it a powerful tool for debugging WebGL games on mobile devices where
* extensions are not permitted.
*
* See https://github.com/BabylonJS/Spector.js for more details.
*
* This method will return the current FPS of the WebGL canvas.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#getFps
* @since 3.60.0
*
* @return {number} The current FPS of the WebGL canvas.
*/
getFps: function() {
if (DEBUG && this.spector) {
return this.spector.getFps();
}
},
/**
* This method is only available in the Debug Build of Phaser, or a build with the
* `WEBGL_DEBUG` flag set in the Webpack Config.
*
* Phaser v3.60 Debug has a build of Spector.js embedded in it, which is a WebGL inspector
* that allows for live inspection of your WebGL calls. Although it's easy to add the Spector
* extension to a desktop browsr, by embedding it in Phaser we can make it available in mobile
* browsers too, making it a powerful tool for debugging WebGL games on mobile devices where
* extensions are not permitted.
*
* See https://github.com/BabylonJS/Spector.js for more details.
*
* This method adds a command with the name value in the list. This can be filtered in the search.
* All logs can be filtered searching for "LOG".
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#log
* @since 3.60.0
*
* @param {...*} arguments - The arguments to log to Spector.
*
* @return {string} The current log.
*/
log: function() {
if (DEBUG && this.spector) {
var t = Array.prototype.slice.call(arguments).join(" ");
return this.spector.log(t);
}
},
/**
* This method is only available in the Debug Build of Phaser, or a build with the
* `WEBGL_DEBUG` flag set in the Webpack Config.
*
* Phaser v3.60 Debug has a build of Spector.js embedded in it, which is a WebGL inspector
* that allows for live inspection of your WebGL calls. Although it's easy to add the Spector
* extension to a desktop browsr, by embedding it in Phaser we can make it available in mobile
* browsers too, making it a powerful tool for debugging WebGL games on mobile devices where
* extensions are not permitted.
*
* See https://github.com/BabylonJS/Spector.js for more details.
*
* This method will start a capture on the Phaser canvas. The capture will stop once it reaches
* the number of commands specified as a parameter, or after 10 seconds. If quick capture is true,
* the thumbnails are not captured in order to speed up the capture.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#startCapture
* @since 3.60.0
*
* @param {number} [commandCount=0] - The number of commands to capture. If zero it will capture for 10 seconds.
* @param {boolean} [quickCapture=false] - If `true` thumbnails are not captured in order to speed up the capture.
* @param {boolean} [fullCapture=false] - If `true` all details are captured.
*/
startCapture: function(commandCount, quickCapture, fullCapture) {
if (commandCount === void 0) {
commandCount = 0;
}
if (quickCapture === void 0) {
quickCapture = false;
}
if (fullCapture === void 0) {
fullCapture = false;
}
if (DEBUG && this.spector && !this._debugCapture) {
this.spector.startCapture(this.canvas, commandCount, quickCapture, fullCapture);
this._debugCapture = true;
}
},
/**
* This method is only available in the Debug Build of Phaser, or a build with the
* `WEBGL_DEBUG` flag set in the Webpack Config.
*
* Phaser v3.60 Debug has a build of Spector.js embedded in it, which is a WebGL inspector
* that allows for live inspection of your WebGL calls. Although it's easy to add the Spector
* extension to a desktop browsr, by embedding it in Phaser we can make it available in mobile
* browsers too, making it a powerful tool for debugging WebGL games on mobile devices where
* extensions are not permitted.
*
* See https://github.com/BabylonJS/Spector.js for more details.
*
* This method will stop the current capture and returns the result in JSON. It displays the
* result if the UI has been displayed. This returns undefined if the capture has not been completed
* or did not find any commands.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#stopCapture
* @since 3.60.0
*
* @return {object} The current capture.
*/
stopCapture: function() {
if (DEBUG && this.spector && this._debugCapture) {
return this.spector.stopCapture();
}
},
/**
* This method is only available in the Debug Build of Phaser, or a build with the
* `WEBGL_DEBUG` flag set in the Webpack Config.
*
* Internal onCapture handler.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#onCapture
* @private
* @since 3.60.0
*
* @param {object} capture - The capture data.
*/
onCapture: function(capture) {
if (DEBUG) {
var view = this.spector.getResultUI();
view.display(capture);
this._debugCapture = false;
}
},
/**
* The event handler that manages the `resize` event dispatched by the Scale Manager.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#onResize
* @since 3.16.0
*
* @param {Phaser.Structs.Size} gameSize - The default Game Size object. This is the un-modified game dimensions.
* @param {Phaser.Structs.Size} baseSize - The base Size object. The game dimensions. The canvas width / height values match this.
*/
onResize: function(gameSize, baseSize) {
if (baseSize.width !== this.width || baseSize.height !== this.height) {
this.resize(baseSize.width, baseSize.height);
}
},
/**
* Binds the WebGL Renderers Render Target, so all drawn content is now redirected to it.
*
* Make sure to call `endCapture` when you are finished.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#beginCapture
* @since 3.50.0
*
* @param {number} [width] - Optional new width of the Render Target.
* @param {number} [height] - Optional new height of the Render Target.
*/
beginCapture: function(width, height) {
if (width === void 0) {
width = this.width;
}
if (height === void 0) {
height = this.height;
}
this.renderTarget.bind(true, width, height);
this.setProjectionMatrix(width, height);
},
/**
* Unbinds the WebGL Renderers Render Target and returns it, stopping any further content being drawn to it.
*
* If the viewport or scissors were modified during the capture, you should reset them by calling
* `resetViewport` and `resetScissor` accordingly.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#endCapture
* @since 3.50.0
*
* @return {Phaser.Renderer.WebGL.RenderTarget} A reference to the WebGL Renderer Render Target.
*/
endCapture: function() {
this.renderTarget.unbind(true);
this.resetProjectionMatrix();
return this.renderTarget;
},
/**
* Resizes the drawing buffer to match that required by the Scale Manager.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#resize
* @fires Phaser.Renderer.Events#RESIZE
* @since 3.0.0
*
* @param {number} [width] - The new width of the renderer.
* @param {number} [height] - The new height of the renderer.
*
* @return {this} This WebGLRenderer instance.
*/
resize: function(width, height) {
var gl = this.gl;
this.width = width;
this.height = height;
this.setProjectionMatrix(width, height);
gl.viewport(0, 0, width, height);
this.drawingBufferHeight = gl.drawingBufferHeight;
gl.scissor(0, gl.drawingBufferHeight - height, width, height);
this.defaultScissor[2] = width;
this.defaultScissor[3] = height;
this.emit(Events.RESIZE, width, height);
return this;
},
/**
* Determines which compressed texture formats this browser and device supports.
*
* Called automatically as part of the WebGL Renderer init process. If you need to investigate
* which formats it supports, see the `Phaser.Renderer.WebGL.WebGLRenderer#compression` property instead.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#getCompressedTextures
* @since 3.60.0
*
* @return {Phaser.Types.Renderer.WebGL.WebGLTextureCompression} The compression object.
*/
getCompressedTextures: function() {
var extString = "WEBGL_compressed_texture_";
var wkExtString = "WEBKIT_" + extString;
var extEXTString = "EXT_texture_compression_";
var hasExt = function(gl2, format) {
var results = gl2.getExtension(extString + format) || gl2.getExtension(wkExtString + format) || gl2.getExtension(extEXTString + format);
if (results) {
var glEnums = {};
for (var key in results) {
glEnums[results[key]] = key;
}
return glEnums;
}
};
var gl = this.gl;
return {
ETC: hasExt(gl, "etc"),
ETC1: hasExt(gl, "etc1"),
ATC: hasExt(gl, "atc"),
ASTC: hasExt(gl, "astc"),
BPTC: hasExt(gl, "bptc"),
RGTC: hasExt(gl, "rgtc"),
PVRTC: hasExt(gl, "pvrtc"),
S3TC: hasExt(gl, "s3tc"),
S3TCSRGB: hasExt(gl, "s3tc_srgb"),
IMG: true
};
},
/**
* Returns a compressed texture format GLenum name based on the given format.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#getCompressedTextureName
* @since 3.60.0
*
* @param {string} baseFormat - The Base Format to check.
* @param {GLenum} [format] - An optional GLenum format to check within the base format.
*
* @return {string} The compressed texture format name, as a string.
*/
getCompressedTextureName: function(baseFormat, format) {
var supportedFormats = this.compression[baseFormat.toUpperCase()];
if (format in supportedFormats) {
return supportedFormats[format];
}
},
/**
* Checks if the given compressed texture format is supported, or not.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#supportsCompressedTexture
* @since 3.60.0
*
* @param {string} baseFormat - The Base Format to check.
* @param {GLenum} [format] - An optional GLenum format to check within the base format.
*
* @return {boolean} True if the format is supported, otherwise false.
*/
supportsCompressedTexture: function(baseFormat, format) {
var supportedFormats = this.compression[baseFormat.toUpperCase()];
if (supportedFormats) {
if (format) {
return format in supportedFormats;
} else {
return true;
}
}
return false;
},
/**
* Gets the aspect ratio of the WebGLRenderer dimensions.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#getAspectRatio
* @since 3.50.0
*
* @return {number} The aspect ratio of the WebGLRenderer dimensions.
*/
getAspectRatio: function() {
return this.width / this.height;
},
/**
* Sets the Projection Matrix of this renderer to the given dimensions.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setProjectionMatrix
* @since 3.50.0
*
* @param {number} width - The new width of the Projection Matrix.
* @param {number} height - The new height of the Projection Matrix.
*
* @return {this} This WebGLRenderer instance.
*/
setProjectionMatrix: function(width, height) {
if (width !== this.projectionWidth || height !== this.projectionHeight) {
this.projectionWidth = width;
this.projectionHeight = height;
this.projectionMatrix.ortho(0, width, height, 0, -1e3, 1e3);
}
return this;
},
/**
* Resets the Projection Matrix back to this renderers width and height.
*
* This is called during `endCapture`, should the matrix have been changed
* as a result of the capture process.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#resetProjectionMatrix
* @since 3.50.0
*
* @return {this} This WebGLRenderer instance.
*/
resetProjectionMatrix: function() {
return this.setProjectionMatrix(this.width, this.height);
},
/**
* Checks if a WebGL extension is supported
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#hasExtension
* @since 3.0.0
*
* @param {string} extensionName - Name of the WebGL extension
*
* @return {boolean} `true` if the extension is supported, otherwise `false`.
*/
hasExtension: function(extensionName) {
return this.supportedExtensions ? this.supportedExtensions.indexOf(extensionName) : false;
},
/**
* Loads a WebGL extension
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#getExtension
* @since 3.0.0
*
* @param {string} extensionName - The name of the extension to load.
*
* @return {object} WebGL extension if the extension is supported
*/
getExtension: function(extensionName) {
if (!this.hasExtension(extensionName)) {
return null;
}
if (!(extensionName in this.extensions)) {
this.extensions[extensionName] = this.gl.getExtension(extensionName);
}
return this.extensions[extensionName];
},
/**
* Flushes the current pipeline if the pipeline is bound
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#flush
* @since 3.0.0
*/
flush: function() {
this.pipelines.flush();
},
/**
* Pushes a new scissor state. This is used to set nested scissor states.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#pushScissor
* @since 3.0.0
*
* @param {number} x - The x position of the scissor.
* @param {number} y - The y position of the scissor.
* @param {number} width - The width of the scissor.
* @param {number} height - The height of the scissor.
* @param {number} [drawingBufferHeight] - Optional drawingBufferHeight override value.
*
* @return {number[]} An array containing the scissor values.
*/
pushScissor: function(x, y, width, height, drawingBufferHeight) {
if (drawingBufferHeight === void 0) {
drawingBufferHeight = this.drawingBufferHeight;
}
var scissorStack = this.scissorStack;
var scissor = [x, y, width, height];
scissorStack.push(scissor);
this.setScissor(x, y, width, height, drawingBufferHeight);
this.currentScissor = scissor;
return scissor;
},
/**
* Sets the current scissor state.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setScissor
* @since 3.0.0
*
* @param {number} x - The x position of the scissor.
* @param {number} y - The y position of the scissor.
* @param {number} width - The width of the scissor.
* @param {number} height - The height of the scissor.
* @param {number} [drawingBufferHeight] - Optional drawingBufferHeight override value.
*/
setScissor: function(x, y, width, height, drawingBufferHeight) {
if (drawingBufferHeight === void 0) {
drawingBufferHeight = this.drawingBufferHeight;
}
var gl = this.gl;
var current = this.currentScissor;
var setScissor = width > 0 && height > 0;
if (current && setScissor) {
var cx = current[0];
var cy = current[1];
var cw = current[2];
var ch = current[3];
setScissor = cx !== x || cy !== y || cw !== width || ch !== height;
}
if (setScissor) {
this.flush();
gl.scissor(x, drawingBufferHeight - y - height, width, height);
}
},
/**
* Resets the gl scissor state to be whatever the current scissor is, if there is one, without
* modifying the scissor stack.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#resetScissor
* @since 3.50.0
*/
resetScissor: function() {
var gl = this.gl;
gl.enable(gl.SCISSOR_TEST);
var current = this.currentScissor;
if (current) {
var x = current[0];
var y = current[1];
var width = current[2];
var height = current[3];
if (width > 0 && height > 0) {
gl.scissor(x, this.drawingBufferHeight - y - height, width, height);
}
}
},
/**
* Pops the last scissor state and sets it.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#popScissor
* @since 3.0.0
*/
popScissor: function() {
var scissorStack = this.scissorStack;
scissorStack.pop();
var scissor = scissorStack[scissorStack.length - 1];
if (scissor) {
this.setScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
}
this.currentScissor = scissor;
},
/**
* Is there an active stencil mask?
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#hasActiveStencilMask
* @since 3.17.0
*
* @return {boolean} `true` if there is an active stencil mask, otherwise `false`.
*/
hasActiveStencilMask: function() {
var mask = this.currentMask.mask;
var camMask = this.currentCameraMask.mask;
return mask && mask.isStencil || camMask && camMask.isStencil;
},
/**
* Resets the gl viewport to the current renderer dimensions.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#resetViewport
* @since 3.50.0
*/
resetViewport: function() {
var gl = this.gl;
gl.viewport(0, 0, this.width, this.height);
this.drawingBufferHeight = gl.drawingBufferHeight;
},
/**
* Sets the blend mode to the value given.
*
* If the current blend mode is different from the one given, the pipeline is flushed and the new
* blend mode is enabled.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setBlendMode
* @since 3.0.0
*
* @param {number} blendModeId - The blend mode to be set. Can be a `BlendModes` const or an integer value.
* @param {boolean} [force=false] - Force the blend mode to be set, regardless of the currently set blend mode.
*
* @return {boolean} `true` if the blend mode was changed as a result of this call, forcing a flush, otherwise `false`.
*/
setBlendMode: function(blendModeId, force) {
if (force === void 0) {
force = false;
}
var gl = this.gl;
var blendMode = this.blendModes[blendModeId];
if (force || blendModeId !== CONST.BlendModes.SKIP_CHECK && this.currentBlendMode !== blendModeId) {
this.flush();
gl.enable(gl.BLEND);
gl.blendEquation(blendMode.equation);
if (blendMode.func.length > 2) {
gl.blendFuncSeparate(blendMode.func[0], blendMode.func[1], blendMode.func[2], blendMode.func[3]);
} else {
gl.blendFunc(blendMode.func[0], blendMode.func[1]);
}
this.currentBlendMode = blendModeId;
return true;
}
return false;
},
/**
* Creates a new custom blend mode for the renderer.
*
* See https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Constants#Blending_modes
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#addBlendMode
* @since 3.0.0
*
* @param {GLenum[]} func - An array containing the WebGL functions to use for the source and the destination blending factors, respectively. See the possible constants for {@link WebGLRenderingContext#blendFunc()}.
* @param {GLenum} equation - The equation to use for combining the RGB and alpha components of a new pixel with a rendered one. See the possible constants for {@link WebGLRenderingContext#blendEquation()}.
*
* @return {number} The index of the new blend mode, used for referencing it in the future.
*/
addBlendMode: function(func, equation) {
var index = this.blendModes.push({ func, equation });
return index - 1;
},
/**
* Updates the function bound to a given custom blend mode.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#updateBlendMode
* @since 3.0.0
*
* @param {number} index - The index of the custom blend mode.
* @param {function} func - The function to use for the blend mode.
* @param {function} equation - The equation to use for the blend mode.
*
* @return {this} This WebGLRenderer instance.
*/
updateBlendMode: function(index, func, equation) {
if (this.blendModes[index]) {
this.blendModes[index].func = func;
if (equation) {
this.blendModes[index].equation = equation;
}
}
return this;
},
/**
* Removes a custom blend mode from the renderer.
* Any Game Objects still using this blend mode will error, so be sure to clear them first.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#removeBlendMode
* @since 3.0.0
*
* @param {number} index - The index of the custom blend mode to be removed.
*
* @return {this} This WebGLRenderer instance.
*/
removeBlendMode: function(index) {
if (index > 17 && this.blendModes[index]) {
this.blendModes.splice(index, 1);
}
return this;
},
/**
* Pushes a new framebuffer onto the FBO stack and makes it the currently bound framebuffer.
*
* If there was another framebuffer already bound it will force a pipeline flush.
*
* Call `popFramebuffer` to remove it again.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#pushFramebuffer
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLFramebufferWrapper} framebuffer - The framebuffer that needs to be bound.
* @param {boolean} [updateScissor=false] - Set the gl scissor to match the frame buffer size? Or, if `null` given, pop the scissor from the stack.
* @param {boolean} [setViewport=true] - Should the WebGL viewport be set?
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} [texture=null] - Bind the given frame buffer texture?
* @param {boolean} [clear=false] - Clear the frame buffer after binding?
*
* @return {this} This WebGLRenderer instance.
*/
pushFramebuffer: function(framebuffer, updateScissor, setViewport, texture, clear) {
if (framebuffer === this.currentFramebuffer) {
return this;
}
this.fboStack.push(framebuffer);
return this.setFramebuffer(framebuffer, updateScissor, setViewport, texture, clear);
},
/**
* Sets the given framebuffer as the active and currently bound framebuffer.
*
* If there was another framebuffer already bound it will force a pipeline flush.
*
* Typically, you should call `pushFramebuffer` instead of this method.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setFramebuffer
* @since 3.0.0
*
* @param {(Phaser.Renderer.WebGL.Wrappers.WebGLFramebufferWrapper|null)} framebuffer - The framebuffer that needs to be bound, or `null` to bind back to the default framebuffer.
* @param {boolean} [updateScissor=false] - If a framebuffer is given, set the gl scissor to match the frame buffer size? Or, if `null` given, pop the scissor from the stack.
* @param {boolean} [setViewport=true] - Should the WebGL viewport be set?
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} [texture=null] - Bind the given frame buffer texture?
* @param {boolean} [clear=false] - Clear the frame buffer after binding?
*
* @return {this} This WebGLRenderer instance.
*/
setFramebuffer: function(framebuffer, updateScissor, setViewport, texture, clear) {
if (updateScissor === void 0) {
updateScissor = false;
}
if (setViewport === void 0) {
setViewport = true;
}
if (texture === void 0) {
texture = null;
}
if (clear === void 0) {
clear = false;
}
if (framebuffer === this.currentFramebuffer) {
return this;
}
var gl = this.gl;
var width = this.width;
var height = this.height;
if (framebuffer && framebuffer.renderTexture && setViewport) {
width = framebuffer.renderTexture.width;
height = framebuffer.renderTexture.height;
} else {
this.flush();
}
if (framebuffer) {
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer.webGLFramebuffer);
} else {
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
}
if (setViewport) {
gl.viewport(0, 0, width, height);
}
if (texture) {
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture.webGLTexture, 0);
}
if (clear) {
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
}
if (updateScissor) {
if (framebuffer) {
this.drawingBufferHeight = height;
this.pushScissor(0, 0, width, height);
} else {
this.drawingBufferHeight = this.height;
this.popScissor();
}
}
this.currentFramebuffer = framebuffer;
return this;
},
/**
* Pops the previous framebuffer from the fbo stack and sets it.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#popFramebuffer
* @since 3.50.0
*
* @param {boolean} [updateScissor=false] - If a framebuffer is given, set the gl scissor to match the frame buffer size? Or, if `null` given, pop the scissor from the stack.
* @param {boolean} [setViewport=true] - Should the WebGL viewport be set?
*
* @return {Phaser.Renderer.WebGL.Wrappers.WebGLFramebufferWrapper} The Framebuffer that was set, or `null` if there aren't any more in the stack.
*/
popFramebuffer: function(updateScissor, setViewport) {
if (updateScissor === void 0) {
updateScissor = false;
}
if (setViewport === void 0) {
setViewport = true;
}
var fboStack = this.fboStack;
fboStack.pop();
var framebuffer = fboStack[fboStack.length - 1];
if (!framebuffer) {
framebuffer = null;
}
this.setFramebuffer(framebuffer, updateScissor, setViewport);
return framebuffer;
},
/**
* Restores the previous framebuffer from the fbo stack and sets it.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#restoreFramebuffer
* @since 3.60.0
*
* @param {boolean} [updateScissor=false] - If a framebuffer is given, set the gl scissor to match the frame buffer size? Or, if `null` given, pop the scissor from the stack.
* @param {boolean} [setViewport=true] - Should the WebGL viewport be set?
*/
restoreFramebuffer: function(updateScissor, setViewport) {
if (updateScissor === void 0) {
updateScissor = false;
}
if (setViewport === void 0) {
setViewport = true;
}
var fboStack = this.fboStack;
var framebuffer = fboStack[fboStack.length - 1];
if (!framebuffer) {
framebuffer = null;
}
this.currentFramebuffer = null;
this.setFramebuffer(framebuffer, updateScissor, setViewport);
},
/**
* Binds a shader program.
*
* If there was a different program already bound it will force a pipeline flush first.
*
* If the same program given to this method is already set as the current program, no change
* will take place and this method will return `false`.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setProgram
* @since 3.0.0
*
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLProgramWrapper} program - The program that needs to be bound.
*
* @return {boolean} `true` if the given program was bound, otherwise `false`.
*/
setProgram: function(program) {
if (program !== this.currentProgram) {
this.flush();
this.gl.useProgram(program.webGLProgram);
this.currentProgram = program;
return true;
}
return false;
},
/**
* Rebinds whatever program `WebGLRenderer.currentProgram` is set as, without
* changing anything, or flushing.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#resetProgram
* @since 3.50.0
*
* @return {this} This WebGLRenderer instance.
*/
resetProgram: function() {
this.gl.useProgram(this.currentProgram.webGLProgramWrapper);
return this;
},
/**
* Creates a texture from an image source. If the source is not valid it creates an empty texture.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#createTextureFromSource
* @since 3.0.0
*
* @param {object} source - The source of the texture.
* @param {number} width - The width of the texture.
* @param {number} height - The height of the texture.
* @param {number} scaleMode - The scale mode to be used by the texture.
* @param {boolean} [forceClamp=false] - Force the texture to use the CLAMP_TO_EDGE wrap mode, even if a power of two?
*
* @return {?Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} The WebGLTextureWrapper that was created, or `null` if it couldn't be created.
*/
createTextureFromSource: function(source, width, height, scaleMode, forceClamp) {
if (forceClamp === void 0) {
forceClamp = false;
}
var gl = this.gl;
var minFilter = gl.NEAREST;
var magFilter = gl.NEAREST;
var wrap = gl.CLAMP_TO_EDGE;
var texture = null;
width = source ? source.width : width;
height = source ? source.height : height;
var pow = IsSizePowerOfTwo(width, height);
if (pow && !forceClamp) {
wrap = gl.REPEAT;
}
if (scaleMode === CONST.ScaleModes.LINEAR && this.config.antialias) {
var isCompressed = source && source.compressed;
var isMip = !isCompressed && pow || isCompressed && source.mipmaps.length > 1;
minFilter = this.mipmapFilter && isMip ? this.mipmapFilter : gl.LINEAR;
magFilter = gl.LINEAR;
}
if (!source && typeof width === "number" && typeof height === "number") {
texture = this.createTexture2D(0, minFilter, magFilter, wrap, wrap, gl.RGBA, null, width, height);
} else {
texture = this.createTexture2D(0, minFilter, magFilter, wrap, wrap, gl.RGBA, source);
}
return texture;
},
/**
* A wrapper for creating a WebGLTextureWrapper. If no pixel data is passed it will create an empty texture.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#createTexture2D
* @since 3.0.0
*
* @param {number} mipLevel - Mip level of the texture.
* @param {number} minFilter - Filtering of the texture.
* @param {number} magFilter - Filtering of the texture.
* @param {number} wrapT - Wrapping mode of the texture.
* @param {number} wrapS - Wrapping mode of the texture.
* @param {number} format - Which format does the texture use.
* @param {?object} pixels - pixel data.
* @param {?number} width - Width of the texture in pixels. If not supplied, it must be derived from `pixels`.
* @param {?number} height - Height of the texture in pixels. If not supplied, it must be derived from `pixels`.
* @param {boolean} [pma=true] - Does the texture have premultiplied alpha?
* @param {boolean} [forceSize=false] - If `true` it will use the width and height passed to this method, regardless of the pixels dimension.
* @param {boolean} [flipY=false] - Sets the `UNPACK_FLIP_Y_WEBGL` flag the WebGL Texture uses during upload.
*
* @return {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} The WebGLTextureWrapper that was created.
*/
createTexture2D: function(mipLevel, minFilter, magFilter, wrapT, wrapS, format, pixels, width, height, pma, forceSize, flipY) {
if (typeof width !== "number") {
width = pixels ? pixels.width : 1;
}
if (typeof height !== "number") {
height = pixels ? pixels.height : 1;
}
var texture = new WebGLTextureWrapper(this.gl, mipLevel, minFilter, magFilter, wrapT, wrapS, format, pixels, width, height, pma, forceSize, flipY);
this.glTextureWrappers.push(texture);
return texture;
},
/**
* Creates a WebGL Framebuffer object and optionally binds a depth stencil render buffer.
*
* This will unbind any currently bound framebuffer.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#createFramebuffer
* @since 3.0.0
*
* @param {number} width - If `addDepthStencilBuffer` is true, this controls the width of the depth stencil.
* @param {number} height - If `addDepthStencilBuffer` is true, this controls the height of the depth stencil.
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} renderTexture - The color texture where the color pixels are written.
* @param {boolean} [addDepthStencilBuffer=false] - Create a Renderbuffer for the depth stencil?
*
* @return {Phaser.Renderer.WebGL.Wrappers.WebGLFramebufferWrapper} Wrapped framebuffer which is safe to use with the renderer.
*/
createFramebuffer: function(width, height, renderTexture, addDepthStencilBuffer) {
this.currentFramebuffer = null;
var framebuffer = new WebGLFramebufferWrapper(this.gl, width, height, renderTexture, addDepthStencilBuffer);
this.glFramebufferWrappers.push(framebuffer);
return framebuffer;
},
/**
* Binds necessary resources and renders the mask to a separated framebuffer.
* The framebuffer for the masked object is also bound for further use.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#beginBitmapMask
* @since 3.60.0
*
* @param {Phaser.Display.Masks.BitmapMask} mask - The BitmapMask instance that called beginMask.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The camera rendering the current mask.
*/
beginBitmapMask: function(bitmapMask, camera) {
var gl = this.gl;
if (gl) {
this.flush();
this.maskTarget.bind(true);
if (this.currentCameraMask.mask !== bitmapMask) {
this.currentMask.mask = bitmapMask;
this.currentMask.camera = camera;
}
}
},
/**
* Binds necessary resources and renders the mask to a separated framebuffer.
* The framebuffer for the masked object is also bound for further use.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#drawBitmapMask
* @since 3.60.0
*
* @param {Phaser.Display.Masks.BitmapMask} mask - The BitmapMask instance that called beginMask.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The camera rendering the current mask.
* @param {Phaser.Renderer.WebGL.Pipelines.BitmapMaskPipeline} bitmapMaskPipeline - The BitmapMask Pipeline instance that is requesting the draw.
*/
drawBitmapMask: function(bitmapMask, camera, bitmapMaskPipeline) {
this.flush();
this.maskSource.bind();
this.setBlendMode(0, true);
bitmapMask.renderWebGL(this, bitmapMask, camera);
this.maskSource.unbind(true);
this.maskTarget.unbind();
var gl = this.gl;
var prev = this.getCurrentStencilMask();
if (prev) {
gl.enable(gl.STENCIL_TEST);
prev.mask.applyStencil(this, prev.camera, true);
} else {
this.currentMask.mask = null;
}
this.pipelines.set(bitmapMaskPipeline);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, this.maskTarget.texture.webGLTexture);
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, this.maskSource.texture.webGLTexture);
},
/**
* Creates a WebGLProgram instance based on the given vertex and fragment shader source.
*
* Then compiles, attaches and links the program before wrapping and returning it.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#createProgram
* @since 3.0.0
*
* @param {string} vertexShader - The vertex shader source code as a single string.
* @param {string} fragmentShader - The fragment shader source code as a single string.
*
* @return {Phaser.Renderer.WebGL.Wrappers.WebGLProgramWrapper} The wrapped, linked WebGLProgram created from the given shader source.
*/
createProgram: function(vertexShader, fragmentShader) {
var wrapper = new WebGLProgramWrapper(this.gl, vertexShader, fragmentShader);
this.glProgramWrappers.push(wrapper);
return wrapper;
},
/**
* Wrapper for creating a vertex buffer.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#createVertexBuffer
* @since 3.0.0
*
* @param {ArrayBuffer} initialDataOrSize - It's either ArrayBuffer or an integer indicating the size of the vbo
* @param {number} bufferUsage - How the buffer is used. gl.DYNAMIC_DRAW, gl.STATIC_DRAW or gl.STREAM_DRAW
*
* @return {Phaser.Renderer.WebGL.Wrappers.WebGLBufferWrapper} Wrapped vertex buffer
*/
createVertexBuffer: function(initialDataOrSize, bufferUsage) {
var gl = this.gl;
var vertexBuffer = new WebGLBufferWrapper(gl, initialDataOrSize, gl.ARRAY_BUFFER, bufferUsage);
this.glBufferWrappers.push(vertexBuffer);
return vertexBuffer;
},
/**
* Creates a WebGLAttribLocationWrapper instance based on the given WebGLProgramWrapper and attribute name.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#createAttribLocation
* @since 3.80.0
*
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLProgramWrapper} program - The WebGLProgramWrapper instance.
* @param {string} name - The name of the attribute.
*/
createAttribLocation: function(program, name) {
var attrib = new WebGLAttribLocationWrapper(this.gl, program, name);
this.glAttribLocationWrappers.push(attrib);
return attrib;
},
/**
* Creates a WebGLUniformLocationWrapper instance based on the given WebGLProgramWrapper and uniform name.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#createUniformLocation
* @since 3.80.0
*
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLProgramWrapper} program - The WebGLProgramWrapper instance.
* @param {string} name - The name of the uniform.
*/
createUniformLocation: function(program, name) {
var uniform = new WebGLUniformLocationWrapper(this.gl, program, name);
this.glUniformLocationWrappers.push(uniform);
return uniform;
},
/**
* Wrapper for creating a vertex buffer.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#createIndexBuffer
* @since 3.0.0
*
* @param {ArrayBuffer} initialDataOrSize - Either ArrayBuffer or an integer indicating the size of the vbo.
* @param {number} bufferUsage - How the buffer is used. gl.DYNAMIC_DRAW, gl.STATIC_DRAW or gl.STREAM_DRAW.
*
* @return {Phaser.Renderer.WebGL.Wrappers.WebGLBufferWrapper} Wrapped index buffer
*/
createIndexBuffer: function(initialDataOrSize, bufferUsage) {
var gl = this.gl;
var indexBuffer = new WebGLBufferWrapper(gl, initialDataOrSize, gl.ELEMENT_ARRAY_BUFFER, bufferUsage);
this.glBufferWrappers.push(indexBuffer);
return indexBuffer;
},
/**
* Removes a texture from the GPU.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#deleteTexture
* @since 3.0.0
*
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} texture - The WebGL Texture to be deleted.
*
* @return {this} This WebGLRenderer instance.
*/
deleteTexture: function(texture) {
if (!texture) {
return;
}
ArrayRemove(this.glTextureWrappers, texture);
texture.destroy();
return this;
},
/**
* Deletes a Framebuffer from the GL instance.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#deleteFramebuffer
* @since 3.0.0
*
* @param {(Phaser.Renderer.WebGL.Wrappers.WebGLFramebufferWrapper|null)} framebuffer - The Framebuffer to be deleted.
*
* @return {this} This WebGLRenderer instance.
*/
deleteFramebuffer: function(framebuffer) {
if (!framebuffer) {
return this;
}
ArrayRemove(this.fboStack, framebuffer);
ArrayRemove(this.glFramebufferWrappers, framebuffer);
framebuffer.destroy();
return this;
},
/**
* Deletes a WebGLProgram from the GL instance.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#deleteProgram
* @since 3.0.0
*
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLProgramWrapper} program - The shader program to be deleted.
*
* @return {this} This WebGLRenderer instance.
*/
deleteProgram: function(program) {
if (program) {
ArrayRemove(this.glProgramWrappers, program);
program.destroy();
}
return this;
},
/**
* Deletes a WebGLAttribLocation from the GL instance.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#deleteAttribLocation
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLAttribLocationWrapper} attrib - The attrib location to be deleted.
* @since 3.80.0
*/
deleteAttribLocation: function(attrib) {
if (attrib) {
ArrayRemove(this.glAttribLocationWrappers, attrib);
attrib.destroy();
}
return this;
},
/**
* Deletes a WebGLUniformLocation from the GL instance.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#deleteUniformLocation
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLUniformLocationWrapper} uniform - The uniform location to be deleted.
* @since 3.80.0
*/
deleteUniformLocation: function(uniform) {
if (uniform) {
ArrayRemove(this.glUniformLocationWrappers, uniform);
uniform.destroy();
}
return this;
},
/**
* Deletes a WebGLBuffer from the GL instance.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#deleteBuffer
* @since 3.0.0
*
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLBufferWrapper} vertexBuffer - The WebGLBuffer to be deleted.
*
* @return {this} This WebGLRenderer instance.
*/
deleteBuffer: function(buffer) {
if (!buffer) {
return this;
}
ArrayRemove(this.glBufferWrappers, buffer);
buffer.destroy();
return this;
},
/**
* Controls the pre-render operations for the given camera.
* Handles any clipping needed by the camera and renders the background color if a color is visible.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#preRenderCamera
* @since 3.0.0
*
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to pre-render.
*/
preRenderCamera: function(camera) {
var cx = camera.x;
var cy = camera.y;
var cw = camera.width;
var ch = camera.height;
var color = camera.backgroundColor;
camera.emit(CameraEvents.PRE_RENDER, camera);
this.pipelines.preBatchCamera(camera);
this.pushScissor(cx, cy, cw, ch);
if (camera.mask) {
this.currentCameraMask.mask = camera.mask;
this.currentCameraMask.camera = camera._maskCamera;
camera.mask.preRenderWebGL(this, camera, camera._maskCamera);
}
if (color.alphaGL > 0) {
var pipeline = this.pipelines.setMulti();
pipeline.drawFillRect(
cx,
cy,
cw,
ch,
Utils.getTintFromFloats(color.blueGL, color.greenGL, color.redGL, 1),
color.alphaGL
);
}
},
/**
* Return the current stencil mask.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#getCurrentStencilMask
* @private
* @since 3.50.0
*/
getCurrentStencilMask: function() {
var prev = null;
var stack = this.maskStack;
var cameraMask = this.currentCameraMask;
if (stack.length > 0) {
prev = stack[stack.length - 1];
} else if (cameraMask.mask && cameraMask.mask.isStencil) {
prev = cameraMask;
}
return prev;
},
/**
* Controls the post-render operations for the given camera.
*
* Renders the foreground camera effects like flash and fading, then resets the current scissor state.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#postRenderCamera
* @since 3.0.0
*
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to post-render.
*/
postRenderCamera: function(camera) {
var flashEffect = camera.flashEffect;
var fadeEffect = camera.fadeEffect;
if (flashEffect.isRunning || (fadeEffect.isRunning || fadeEffect.isComplete)) {
var pipeline = this.pipelines.setMulti();
flashEffect.postRenderWebGL(pipeline, Utils.getTintFromFloats);
fadeEffect.postRenderWebGL(pipeline, Utils.getTintFromFloats);
}
camera.dirty = false;
this.popScissor();
if (camera.mask) {
this.currentCameraMask.mask = null;
camera.mask.postRenderWebGL(this, camera._maskCamera);
}
this.pipelines.postBatchCamera(camera);
camera.emit(CameraEvents.POST_RENDER, camera);
},
/**
* Clears the current vertex buffer and updates pipelines.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#preRender
* @fires Phaser.Renderer.Events#PRE_RENDER_CLEAR
* @fires Phaser.Renderer.Events#PRE_RENDER
* @since 3.0.0
*/
preRender: function() {
if (this.contextLost) {
return;
}
var gl = this.gl;
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
this.emit(Events.PRE_RENDER_CLEAR);
if (this.config.clearBeforeRender) {
var clearColor = this.config.backgroundColor;
gl.clearColor(clearColor.redGL, clearColor.greenGL, clearColor.blueGL, clearColor.alphaGL);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
}
gl.enable(gl.SCISSOR_TEST);
this.currentScissor = this.defaultScissor;
this.scissorStack.length = 0;
this.scissorStack.push(this.currentScissor);
if (this.game.scene.customViewports) {
gl.scissor(0, this.drawingBufferHeight - this.height, this.width, this.height);
}
this.currentMask.mask = null;
this.currentCameraMask.mask = null;
this.maskStack.length = 0;
this.emit(Events.PRE_RENDER);
},
/**
* The core render step for a Scene Camera.
*
* Iterates through the given array of Game Objects and renders them with the given Camera.
*
* This is called by the `CameraManager.render` method. The Camera Manager instance belongs to a Scene, and is invoked
* by the Scene Systems.render method.
*
* This method is not called if `Camera.visible` is `false`, or `Camera.alpha` is zero.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#render
* @fires Phaser.Renderer.Events#RENDER
* @since 3.0.0
*
* @param {Phaser.Scene} scene - The Scene to render.
* @param {Phaser.GameObjects.GameObject[]} children - An array of filtered Game Objects that can be rendered by the given Camera.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Scene Camera to render with.
*/
render: function(scene, children, camera) {
if (this.contextLost) {
return;
}
var childCount = children.length;
this.emit(Events.RENDER, scene, camera);
this.preRenderCamera(camera);
if (childCount === 0) {
this.setBlendMode(CONST.BlendModes.NORMAL);
this.postRenderCamera(camera);
return;
}
this.currentType = "";
var current = this.currentMask;
for (var i = 0; i < childCount; i++) {
this.finalType = i === childCount - 1;
var child = children[i];
var mask = child.mask;
current = this.currentMask;
if (current.mask && current.mask !== mask) {
current.mask.postRenderWebGL(this, current.camera);
}
if (mask && current.mask !== mask) {
mask.preRenderWebGL(this, child, camera);
}
if (child.blendMode !== this.currentBlendMode) {
this.setBlendMode(child.blendMode);
}
var type = child.type;
if (type !== this.currentType) {
this.newType = true;
this.currentType = type;
}
if (!this.finalType) {
this.nextTypeMatch = children[i + 1].type === this.currentType;
} else {
this.nextTypeMatch = false;
}
child.renderWebGL(this, child, camera);
this.newType = false;
}
current = this.currentMask;
if (current.mask) {
current.mask.postRenderWebGL(this, current.camera);
}
this.setBlendMode(CONST.BlendModes.NORMAL);
this.postRenderCamera(camera);
},
/**
* The post-render step happens after all Cameras in all Scenes have been rendered.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#postRender
* @fires Phaser.Renderer.Events#POST_RENDER
* @since 3.0.0
*/
postRender: function() {
if (this.contextLost) {
return;
}
this.flush();
this.emit(Events.POST_RENDER);
var state = this.snapshotState;
if (state.callback) {
WebGLSnapshot(this.gl, state);
state.callback = null;
}
},
/**
* Disables the STENCIL_TEST but does not change the status
* of the current stencil mask.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#clearStencilMask
* @since 3.60.0
*/
clearStencilMask: function() {
this.gl.disable(this.gl.STENCIL_TEST);
},
/**
* Restores the current stencil function to the one that was in place
* before `clearStencilMask` was called.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#restoreStencilMask
* @since 3.60.0
*/
restoreStencilMask: function() {
var gl = this.gl;
var current = this.getCurrentStencilMask();
if (current) {
var mask = current.mask;
gl.enable(gl.STENCIL_TEST);
if (mask.invertAlpha) {
gl.stencilFunc(gl.NOTEQUAL, mask.level, 255);
} else {
gl.stencilFunc(gl.EQUAL, mask.level, 255);
}
}
},
/**
* Schedules a snapshot of the entire game viewport to be taken after the current frame is rendered.
*
* To capture a specific area see the `snapshotArea` method. To capture a specific pixel, see `snapshotPixel`.
*
* Only one snapshot can be active _per frame_. If you have already called `snapshotPixel`, for example, then
* calling this method will override it.
*
* Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer into an ArrayBufferView.
* It then parses this, copying the contents to a temporary Canvas and finally creating an Image object from it,
* which is the image returned to the callback provided. All in all, this is a computationally expensive and blocking process,
* which gets more expensive the larger the canvas size gets, so please be careful how you employ this in your game.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#snapshot
* @since 3.0.0
*
* @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created.
* @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`.
* @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`.
*
* @return {this} This WebGL Renderer.
*/
snapshot: function(callback, type, encoderOptions) {
return this.snapshotArea(0, 0, this.gl.drawingBufferWidth, this.gl.drawingBufferHeight, callback, type, encoderOptions);
},
/**
* Schedules a snapshot of the given area of the game viewport to be taken after the current frame is rendered.
*
* To capture the whole game viewport see the `snapshot` method. To capture a specific pixel, see `snapshotPixel`.
*
* Only one snapshot can be active _per frame_. If you have already called `snapshotPixel`, for example, then
* calling this method will override it.
*
* Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer into an ArrayBufferView.
* It then parses this, copying the contents to a temporary Canvas and finally creating an Image object from it,
* which is the image returned to the callback provided. All in all, this is a computationally expensive and blocking process,
* which gets more expensive the larger the canvas size gets, so please be careful how you employ this in your game.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#snapshotArea
* @since 3.16.0
*
* @param {number} x - The x coordinate to grab from. This is based on the game viewport, not the world.
* @param {number} y - The y coordinate to grab from. This is based on the game viewport, not the world.
* @param {number} width - The width of the area to grab.
* @param {number} height - The height of the area to grab.
* @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created.
* @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`.
* @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`.
*
* @return {this} This WebGL Renderer.
*/
snapshotArea: function(x, y, width, height, callback, type, encoderOptions) {
var state = this.snapshotState;
state.callback = callback;
state.type = type;
state.encoder = encoderOptions;
state.getPixel = false;
state.x = x;
state.y = y;
state.width = width;
state.height = height;
return this;
},
/**
* Schedules a snapshot of the given pixel from the game viewport to be taken after the current frame is rendered.
*
* To capture the whole game viewport see the `snapshot` method. To capture a specific area, see `snapshotArea`.
*
* Only one snapshot can be active _per frame_. If you have already called `snapshotArea`, for example, then
* calling this method will override it.
*
* Unlike the other two snapshot methods, this one will return a `Color` object containing the color data for
* the requested pixel. It doesn't need to create an internal Canvas or Image object, so is a lot faster to execute,
* using less memory.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#snapshotPixel
* @since 3.16.0
*
* @param {number} x - The x coordinate of the pixel to get. This is based on the game viewport, not the world.
* @param {number} y - The y coordinate of the pixel to get. This is based on the game viewport, not the world.
* @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot pixel data is extracted.
*
* @return {this} This WebGL Renderer.
*/
snapshotPixel: function(x, y, callback) {
this.snapshotArea(x, y, 1, 1, callback);
this.snapshotState.getPixel = true;
return this;
},
/**
* Takes a snapshot of the given area of the given frame buffer.
*
* Unlike the other snapshot methods, this one is processed immediately and doesn't wait for the next render.
*
* Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer into an ArrayBufferView.
* It then parses this, copying the contents to a temporary Canvas and finally creating an Image object from it,
* which is the image returned to the callback provided. All in all, this is a computationally expensive and blocking process,
* which gets more expensive the larger the canvas size gets, so please be careful how you employ this in your game.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#snapshotFramebuffer
* @since 3.19.0
*
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLFramebufferWrapper} framebuffer - The framebuffer to grab from.
* @param {number} bufferWidth - The width of the framebuffer.
* @param {number} bufferHeight - The height of the framebuffer.
* @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created.
* @param {boolean} [getPixel=false] - Grab a single pixel as a Color object, or an area as an Image object?
* @param {number} [x=0] - The x coordinate to grab from. This is based on the framebuffer, not the world.
* @param {number} [y=0] - The y coordinate to grab from. This is based on the framebuffer, not the world.
* @param {number} [width=bufferWidth] - The width of the area to grab.
* @param {number} [height=bufferHeight] - The height of the area to grab.
* @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`.
* @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`.
*
* @return {this} This WebGL Renderer.
*/
snapshotFramebuffer: function(framebuffer, bufferWidth, bufferHeight, callback, getPixel, x, y, width, height, type, encoderOptions) {
if (getPixel === void 0) {
getPixel = false;
}
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (width === void 0) {
width = bufferWidth;
}
if (height === void 0) {
height = bufferHeight;
}
if (type === "pixel") {
getPixel = true;
type = "image/png";
}
var currentFramebuffer = this.currentFramebuffer;
this.snapshotArea(x, y, width, height, callback, type, encoderOptions);
var state = this.snapshotState;
state.getPixel = getPixel;
state.isFramebuffer = true;
state.bufferWidth = bufferWidth;
state.bufferHeight = bufferHeight;
state.width = Math.min(state.width, bufferWidth);
state.height = Math.min(state.height, bufferHeight);
this.setFramebuffer(framebuffer);
WebGLSnapshot(this.gl, state);
this.setFramebuffer(currentFramebuffer);
state.callback = null;
state.isFramebuffer = false;
return this;
},
/**
* Creates a new WebGL Texture based on the given Canvas Element.
*
* If the `dstTexture` parameter is given, the WebGL Texture is updated, rather than created fresh.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#canvasToTexture
* @since 3.0.0
*
* @param {HTMLCanvasElement} srcCanvas - The Canvas to create the WebGL Texture from
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} [dstTexture] - The destination WebGLTextureWrapper to set.
* @param {boolean} [noRepeat=false] - Should this canvas be allowed to set `REPEAT` (such as for Text objects?)
* @param {boolean} [flipY=false] - Should the WebGL Texture set `UNPACK_MULTIPLY_FLIP_Y`?
*
* @return {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} The newly created, or updated, WebGLTextureWrapper.
*/
canvasToTexture: function(srcCanvas, dstTexture, noRepeat, flipY) {
if (noRepeat === void 0) {
noRepeat = false;
}
if (flipY === void 0) {
flipY = false;
}
var gl = this.gl;
var minFilter = gl.NEAREST;
var magFilter = gl.NEAREST;
var width = srcCanvas.width;
var height = srcCanvas.height;
var wrapping = gl.CLAMP_TO_EDGE;
var pow = IsSizePowerOfTwo(width, height);
if (!noRepeat && pow) {
wrapping = gl.REPEAT;
}
if (this.config.antialias) {
minFilter = pow && this.mipmapFilter ? this.mipmapFilter : gl.LINEAR;
magFilter = gl.LINEAR;
}
if (!dstTexture) {
return this.createTexture2D(0, minFilter, magFilter, wrapping, wrapping, gl.RGBA, srcCanvas, width, height, true, false, flipY);
} else {
dstTexture.update(srcCanvas, width, height, flipY, wrapping, wrapping, minFilter, magFilter, dstTexture.format);
return dstTexture;
}
},
/**
* Creates a new WebGL Texture based on the given Canvas Element.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#createCanvasTexture
* @since 3.20.0
*
* @param {HTMLCanvasElement} srcCanvas - The Canvas to create the WebGL Texture from.
* @param {boolean} [noRepeat=false] - Should this canvas be allowed to set `REPEAT` (such as for Text objects?)
* @param {boolean} [flipY=false] - Should the WebGL Texture set `UNPACK_MULTIPLY_FLIP_Y`?
*
* @return {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} The newly created WebGLTextureWrapper.
*/
createCanvasTexture: function(srcCanvas, noRepeat, flipY) {
if (noRepeat === void 0) {
noRepeat = false;
}
if (flipY === void 0) {
flipY = false;
}
return this.canvasToTexture(srcCanvas, null, noRepeat, flipY);
},
/**
* Updates a WebGL Texture based on the given Canvas Element.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#updateCanvasTexture
* @since 3.20.0
*
* @param {HTMLCanvasElement} srcCanvas - The Canvas to update the WebGL Texture from.
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} dstTexture - The destination WebGLTextureWrapper to update.
* @param {boolean} [flipY=false] - Should the WebGL Texture set `UNPACK_MULTIPLY_FLIP_Y`?
* @param {boolean} [noRepeat=false] - Should this canvas be allowed to set `REPEAT` (such as for Text objects?)
*
* @return {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} The updated WebGLTextureWrapper. This is the same wrapper object as `dstTexture`.
*/
updateCanvasTexture: function(srcCanvas, dstTexture, flipY, noRepeat) {
if (flipY === void 0) {
flipY = false;
}
if (noRepeat === void 0) {
noRepeat = false;
}
return this.canvasToTexture(srcCanvas, dstTexture, noRepeat, flipY);
},
/**
* Creates or updates a WebGL Texture based on the given HTML Video Element.
*
* If the `dstTexture` parameter is given, the WebGL Texture is updated, rather than created fresh.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#videoToTexture
* @since 3.85.0
*
* @param {HTMLVideoElement} srcVideo - The Video to create the WebGL Texture from
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} [dstTexture] - The destination WebGLTextureWrapper to set.
* @param {boolean} [noRepeat=false] - Should this canvas be allowed to set `REPEAT`?
* @param {boolean} [flipY=false] - Should the WebGL Texture set `UNPACK_MULTIPLY_FLIP_Y`?
*
* @return {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} The newly created, or updated, WebGLTextureWrapper.
*/
videoToTexture: function(srcVideo, dstTexture, noRepeat, flipY) {
if (noRepeat === void 0) {
noRepeat = false;
}
if (flipY === void 0) {
flipY = false;
}
var gl = this.gl;
var minFilter = gl.NEAREST;
var magFilter = gl.NEAREST;
var width = srcVideo.videoWidth;
var height = srcVideo.videoHeight;
var wrapping = gl.CLAMP_TO_EDGE;
var pow = IsSizePowerOfTwo(width, height);
if (!noRepeat && pow) {
wrapping = gl.REPEAT;
}
if (this.config.antialias) {
minFilter = pow && this.mipmapFilter ? this.mipmapFilter : gl.LINEAR;
magFilter = gl.LINEAR;
}
if (!dstTexture) {
return this.createTexture2D(0, minFilter, magFilter, wrapping, wrapping, gl.RGBA, srcVideo, width, height, true, true, flipY);
} else {
dstTexture.update(srcVideo, width, height, flipY, wrapping, wrapping, minFilter, magFilter, dstTexture.format);
return dstTexture;
}
},
/**
* Creates a new WebGL Texture based on the given HTML Video Element.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#createVideoTexture
* @since 3.20.0
*
* @param {HTMLVideoElement} srcVideo - The Video to create the WebGL Texture from
* @param {boolean} [noRepeat=false] - Should this canvas be allowed to set `REPEAT`?
* @param {boolean} [flipY=false] - Should the WebGL Texture set `UNPACK_MULTIPLY_FLIP_Y`?
*
* @return {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} The newly created WebGLTextureWrapper.
*/
createVideoTexture: function(srcVideo, noRepeat, flipY) {
if (noRepeat === void 0) {
noRepeat = false;
}
if (flipY === void 0) {
flipY = false;
}
return this.videoToTexture(srcVideo, null, noRepeat, flipY);
},
/**
* Updates a WebGL Texture based on the given HTML Video Element.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#updateVideoTexture
* @since 3.20.0
*
* @param {HTMLVideoElement} srcVideo - The Video to update the WebGL Texture with.
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} dstTexture - The destination WebGLTextureWrapper to update.
* @param {boolean} [flipY=false] - Should the WebGL Texture set `UNPACK_MULTIPLY_FLIP_Y`?
* @param {boolean} [noRepeat=false] - Should this canvas be allowed to set `REPEAT`?
*
* @return {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} The updated WebGLTextureWrapper. This is the same wrapper object as `dstTexture`.
*/
updateVideoTexture: function(srcVideo, dstTexture, flipY, noRepeat) {
if (flipY === void 0) {
flipY = false;
}
if (noRepeat === void 0) {
noRepeat = false;
}
return this.videoToTexture(srcVideo, dstTexture, noRepeat, flipY);
},
/**
* Create a WebGLTexture from a Uint8Array.
*
* The Uint8Array is assumed to be RGBA values, one byte per color component.
*
* The texture will be filtered with `gl.NEAREST` and will not be mipped.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#createUint8ArrayTexture
* @since 3.80.0
* @param {Uint8Array} data - The Uint8Array to create the texture from.
* @param {number} width - The width of the texture.
* @param {number} height - The height of the texture.
* @return {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} The newly created WebGLTextureWrapper.
*/
createUint8ArrayTexture: function(data, width, height) {
var gl = this.gl;
var minFilter = gl.NEAREST;
var magFilter = gl.NEAREST;
var wrap = gl.CLAMP_TO_EDGE;
var pow = IsSizePowerOfTwo(width, height);
if (pow) {
wrap = gl.REPEAT;
}
return this.createTexture2D(0, minFilter, magFilter, wrap, wrap, gl.RGBA, data, width, height);
},
/**
* Sets the minification and magnification filter for a texture.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#setTextureFilter
* @since 3.0.0
*
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} texture - The texture to set the filter for.
* @param {number} filter - The filter to set. 0 for linear filtering, 1 for nearest neighbor (blocky) filtering.
*
* @return {this} This WebGL Renderer instance.
*/
setTextureFilter: function(texture, filter) {
var gl = this.gl;
var glFilter = filter === 0 ? gl.LINEAR : gl.NEAREST;
gl.activeTexture(gl.TEXTURE0);
var currentTexture = gl.getParameter(gl.TEXTURE_BINDING_2D);
gl.bindTexture(gl.TEXTURE_2D, texture.webGLTexture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, glFilter);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, glFilter);
texture.minFilter = glFilter;
texture.magFilter = glFilter;
if (currentTexture) {
gl.bindTexture(gl.TEXTURE_2D, currentTexture);
}
return this;
},
/**
* Returns the largest texture size (either width or height) that can be created.
* Note that VRAM may not allow a texture of any given size, it just expresses
* hardware / driver support for a given size.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#getMaxTextureSize
* @since 3.8.0
*
* @return {number} The maximum supported texture size.
*/
getMaxTextureSize: function() {
return this.config.maxTextureSize;
},
/**
* Destroy this WebGLRenderer, cleaning up all related resources such as pipelines, native textures, etc.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#destroy
* @since 3.0.0
*/
destroy: function() {
this.canvas.removeEventListener("webglcontextlost", this.contextLostHandler, false);
this.canvas.removeEventListener("webglcontextrestored", this.contextRestoredHandler, false);
var wrapperDestroy = function(wrapper) {
wrapper.destroy();
};
ArrayEach(this.glAttribLocationWrappers, wrapperDestroy);
ArrayEach(this.glBufferWrappers, wrapperDestroy);
ArrayEach(this.glFramebufferWrappers, wrapperDestroy);
ArrayEach(this.glProgramWrappers, wrapperDestroy);
ArrayEach(this.glTextureWrappers, wrapperDestroy);
ArrayEach(this.glUniformLocationWrappers, wrapperDestroy);
this.maskTarget.destroy();
this.maskSource.destroy();
this.pipelines.destroy();
this.removeAllListeners();
this.fboStack = [];
this.maskStack = [];
this.extensions = {};
this.textureIndexes = [];
this.gl = null;
this.game = null;
this.canvas = null;
this.contextLost = true;
this.currentMask = null;
this.currentCameraMask = null;
if (DEBUG) {
this.spector = null;
}
}
});
module2.exports = WebGLRenderer;
}
),
/***/
38683: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var ArrayEach = __webpack_require__2(95428);
var GetFastValue = __webpack_require__2(95540);
var WEBGL_CONST = __webpack_require__2(14500);
var WebGLShader = new Class({
initialize: function WebGLShader2(pipeline, name, vertexShader, fragmentShader, attributes) {
this.pipeline = pipeline;
this.name = name;
this.renderer = pipeline.renderer;
this.gl = this.renderer.gl;
this.fragSrc = fragmentShader;
this.vertSrc = vertexShader;
this.program = this.renderer.createProgram(vertexShader, fragmentShader);
this.attributes;
this.vertexComponentCount = 0;
this.vertexSize = 0;
this.uniforms = {};
this.createAttributes(attributes);
this.createUniforms();
},
/**
* Takes the vertex attributes config and parses it, creating the resulting array that is stored
* in this shaders `attributes` property, calculating the offset, normalization and location
* in the process.
*
* Calling this method resets `WebGLShader.attributes`, `WebGLShader.vertexSize` and
* `WebGLShader.vertexComponentCount`.
*
* It is called automatically when this class is created, but can be called manually if required.
*
* @method Phaser.Renderer.WebGL.WebGLShader#createAttributes
* @since 3.50.0
*
* @param {Phaser.Types.Renderer.WebGL.WebGLPipelineAttributeConfig[]} attributes - An array of attributes configs.
*/
createAttributes: function(attributes) {
var count = 0;
var offset = 0;
var result = [];
this.vertexComponentCount = 0;
for (var i = 0; i < attributes.length; i++) {
var element = attributes[i];
var name = element.name;
var size = GetFastValue(element, "size", 1);
var glType = GetFastValue(element, "type", WEBGL_CONST.FLOAT);
var type = glType.enum;
var typeSize = glType.size;
var normalized = element.normalized ? true : false;
result.push({
name,
size,
type,
normalized,
offset,
enabled: false,
location: -1
});
if (typeSize === 4) {
count += size;
} else {
count++;
}
offset += size * typeSize;
}
this.vertexSize = offset;
this.vertexComponentCount = count;
this.attributes = result;
},
/**
* Sets the program this shader uses as being the active shader in the WebGL Renderer.
*
* This method is called every time the parent pipeline is made the current active pipeline.
*
* @method Phaser.Renderer.WebGL.WebGLShader#bind
* @since 3.50.0
*
* @param {boolean} [setAttributes=false] - Should the vertex attribute pointers be set?
* @param {boolean} [flush=false] - Flush the pipeline before binding this shader?
*
* @return {this} This WebGLShader instance.
*/
bind: function(setAttributes, flush) {
if (setAttributes === void 0) {
setAttributes = false;
}
if (flush === void 0) {
flush = false;
}
if (flush) {
this.pipeline.flush();
}
this.renderer.setProgram(this.program);
if (setAttributes) {
this.setAttribPointers();
}
return this;
},
/**
* Sets the program this shader uses as being the active shader in the WebGL Renderer.
*
* Then resets all of the attribute pointers.
*
* @method Phaser.Renderer.WebGL.WebGLShader#rebind
* @since 3.50.0
*
* @return {this} This WebGLShader instance.
*/
rebind: function() {
this.renderer.setProgram(this.program);
this.setAttribPointers(true);
return this;
},
/**
* Sets the vertex attribute pointers.
*
* This should only be called after the vertex buffer has been bound.
*
* It is called automatically during the `bind` method.
*
* @method Phaser.Renderer.WebGL.WebGLShader#setAttribPointers
* @since 3.50.0
*
* @param {boolean} [reset=false] - Reset the vertex attribute locations?
*
* @return {this} This WebGLShader instance.
*/
setAttribPointers: function(reset) {
if (reset === void 0) {
reset = false;
}
var gl = this.gl;
var renderer = this.renderer;
var vertexSize = this.vertexSize;
var attributes = this.attributes;
var program = this.program;
for (var i = 0; i < attributes.length; i++) {
var element = attributes[i];
var size = element.size;
var type = element.type;
var offset = element.offset;
var enabled = element.enabled;
var location = element.location;
var normalized = element.normalized ? true : false;
if (reset) {
if (location !== -1) {
renderer.deleteAttribLocation(location);
}
var attribLocation = this.renderer.createAttribLocation(program, element.name);
if (attribLocation.webGLAttribLocation >= 0) {
gl.enableVertexAttribArray(attribLocation.webGLAttribLocation);
gl.vertexAttribPointer(attribLocation.webGLAttribLocation, size, type, normalized, vertexSize, offset);
element.enabled = true;
element.location = attribLocation;
} else if (attribLocation.webGLAttribLocation !== -1) {
gl.disableVertexAttribArray(attribLocation.webGLAttribLocation);
}
} else if (enabled) {
gl.vertexAttribPointer(location.webGLAttribLocation, size, type, normalized, vertexSize, offset);
} else if (!enabled && location !== -1 && location.webGLAttribLocation > -1) {
gl.disableVertexAttribArray(location.webGLAttribLocation);
element.location = -1;
}
}
return this;
},
/**
* Sets up the `WebGLShader.uniforms` object, populating it with the names
* and locations of the shader uniforms this shader requires.
*
* It works by first calling `gl.getProgramParameter(program.webGLProgram, gl.ACTIVE_UNIFORMS)` to
* find out how many active uniforms this shader has. It then iterates through them,
* calling `gl.getActiveUniform` to get the WebGL Active Info from each one. Finally,
* the name and location are stored in the local array.
*
* This method is called automatically when this class is created.
*
* @method Phaser.Renderer.WebGL.WebGLShader#createUniforms
* @since 3.50.0
*
* @return {this} This WebGLShader instance.
*/
createUniforms: function() {
var gl = this.gl;
var program = this.program;
var uniforms = this.uniforms;
var i;
var name;
var location;
var totalUniforms = gl.getProgramParameter(program.webGLProgram, gl.ACTIVE_UNIFORMS);
for (i = 0; i < totalUniforms; i++) {
var info = gl.getActiveUniform(program.webGLProgram, i);
if (info) {
name = info.name;
location = this.renderer.createUniformLocation(program, name);
if (location !== null) {
uniforms[name] = {
name,
location,
setter: null,
value1: null,
value2: null,
value3: null,
value4: null
};
}
var struct = name.indexOf("[");
if (struct > 0) {
name = name.substr(0, struct);
if (!uniforms.hasOwnProperty(name)) {
location = this.renderer.createUniformLocation(program, name);
if (location !== null) {
uniforms[name] = {
name,
location,
setter: null,
value1: null,
value2: null,
value3: null,
value4: null
};
}
}
}
}
}
return this;
},
/**
* Repopulate uniforms on the GPU.
*
* This is called automatically by the pipeline when the context is
* lost and then recovered. By the time this method is called,
* the WebGL resources are already recreated, so we just need to
* re-populate them.
*
* @method Phaser.Renderer.WebGL.WebGLShader#syncUniforms
* @since 3.80.0
*/
syncUniforms: function() {
var gl = this.gl;
this.renderer.setProgram(this.program);
for (var name in this.uniforms) {
var uniform = this.uniforms[name];
if (uniform.setter) {
uniform.setter.call(gl, uniform.location.webGLUniformLocation, uniform.value1, uniform.value2, uniform.value3, uniform.value4);
}
}
},
/**
* Checks to see if the given uniform name exists and is active in this shader.
*
* @method Phaser.Renderer.WebGL.WebGLShader#hasUniform
* @since 3.50.0
*
* @param {string} name - The name of the uniform to check for.
*
* @return {boolean} `true` if the uniform exists, otherwise `false`.
*/
hasUniform: function(name) {
return this.uniforms.hasOwnProperty(name);
},
/**
* Resets the cached values of the given uniform.
*
* @method Phaser.Renderer.WebGL.WebGLShader#resetUniform
* @since 3.50.0
*
* @param {string} name - The name of the uniform to reset.
*
* @return {this} This WebGLShader instance.
*/
resetUniform: function(name) {
var uniform = this.uniforms[name];
if (uniform) {
uniform.value1 = null;
uniform.value2 = null;
uniform.value3 = null;
uniform.value4 = null;
}
return this;
},
/**
* Sets the given uniform value/s based on the name and GL function.
*
* This method is called internally by other methods such as `set1f` and `set3iv`.
*
* The uniform is only set if the value/s given are different to those previously set.
*
* This method works by first setting this shader as being the current shader within the
* WebGL Renderer, if it isn't already. It also sets this shader as being the current
* one within the pipeline it belongs to.
*
* @method Phaser.Renderer.WebGL.WebGLShader#setUniform1
* @since 3.50.0
*
* @param {function} setter - The GL function to call.
* @param {string} name - The name of the uniform to set.
* @param {(boolean|number|number[]|Float32Array)} value1 - The new value of the uniform.
* @param {boolean} [skipCheck=false] - Skip the value comparison?
*
* @return {this} This WebGLShader instance.
*/
setUniform1: function(setter, name, value1, skipCheck) {
var uniform = this.uniforms[name];
if (!uniform) {
return this;
}
if (skipCheck || uniform.value1 !== value1) {
if (!uniform.setter) {
uniform.setter = setter;
}
uniform.value1 = value1;
this.renderer.setProgram(this.program);
setter.call(this.gl, uniform.location.webGLUniformLocation, value1);
this.pipeline.currentShader = this;
}
return this;
},
/**
* Sets the given uniform value/s based on the name and GL function.
*
* This method is called internally by other methods such as `set1f` and `set3iv`.
*
* The uniform is only set if the value/s given are different to those previously set.
*
* This method works by first setting this shader as being the current shader within the
* WebGL Renderer, if it isn't already. It also sets this shader as being the current
* one within the pipeline it belongs to.
*
* @method Phaser.Renderer.WebGL.WebGLShader#setUniform2
* @since 3.50.0
*
* @param {function} setter - The GL function to call.
* @param {string} name - The name of the uniform to set.
* @param {(boolean|number|number[]|Float32Array)} value1 - The new value of the uniform.
* @param {(boolean|number|number[]|Float32Array)} value2 - The new value of the uniform.
* @param {boolean} [skipCheck=false] - Skip the value comparison?
*
* @return {this} This WebGLShader instance.
*/
setUniform2: function(setter, name, value1, value2, skipCheck) {
var uniform = this.uniforms[name];
if (!uniform) {
return this;
}
if (skipCheck || uniform.value1 !== value1 || uniform.value2 !== value2) {
if (!uniform.setter) {
uniform.setter = setter;
}
uniform.value1 = value1;
uniform.value2 = value2;
this.renderer.setProgram(this.program);
setter.call(this.gl, uniform.location.webGLUniformLocation, value1, value2);
this.pipeline.currentShader = this;
}
return this;
},
/**
* Sets the given uniform value/s based on the name and GL function.
*
* This method is called internally by other methods such as `set1f` and `set3iv`.
*
* The uniform is only set if the value/s given are different to those previously set.
*
* This method works by first setting this shader as being the current shader within the
* WebGL Renderer, if it isn't already. It also sets this shader as being the current
* one within the pipeline it belongs to.
*
* @method Phaser.Renderer.WebGL.WebGLShader#setUniform3
* @since 3.50.0
*
* @param {function} setter - The GL function to call.
* @param {string} name - The name of the uniform to set.
* @param {(boolean|number|number[]|Float32Array)} value1 - The new value of the uniform.
* @param {(boolean|number|number[]|Float32Array)} value2 - The new value of the uniform.
* @param {(boolean|number|number[]|Float32Array)} value3 - The new value of the uniform.
* @param {boolean} [skipCheck=false] - Skip the value comparison?
*
* @return {this} This WebGLShader instance.
*/
setUniform3: function(setter, name, value1, value2, value3, skipCheck) {
var uniform = this.uniforms[name];
if (!uniform) {
return this;
}
if (skipCheck || uniform.value1 !== value1 || uniform.value2 !== value2 || uniform.value3 !== value3) {
if (!uniform.setter) {
uniform.setter = setter;
}
uniform.value1 = value1;
uniform.value2 = value2;
uniform.value3 = value3;
this.renderer.setProgram(this.program);
setter.call(this.gl, uniform.location.webGLUniformLocation, value1, value2, value3);
this.pipeline.currentShader = this;
}
return this;
},
/**
* Sets the given uniform value/s based on the name and GL function.
*
* This method is called internally by other methods such as `set1f` and `set3iv`.
*
* The uniform is only set if the value/s given are different to those previously set.
*
* This method works by first setting this shader as being the current shader within the
* WebGL Renderer, if it isn't already. It also sets this shader as being the current
* one within the pipeline it belongs to.
*
* @method Phaser.Renderer.WebGL.WebGLShader#setUniform4
* @since 3.50.0
*
* @param {function} setter - The GL function to call.
* @param {string} name - The name of the uniform to set.
* @param {(boolean|number|number[]|Float32Array)} value1 - The new value of the uniform.
* @param {(boolean|number|number[]|Float32Array)} value2 - The new value of the uniform.
* @param {(boolean|number|number[]|Float32Array)} value3 - The new value of the uniform.
* @param {(boolean|number|number[]|Float32Array)} value4 - The new value of the uniform.
* @param {boolean} [skipCheck=false] - Skip the value comparison?
*
* @return {this} This WebGLShader instance.
*/
setUniform4: function(setter, name, value1, value2, value3, value4, skipCheck) {
var uniform = this.uniforms[name];
if (!uniform) {
return this;
}
if (skipCheck || uniform.value1 !== value1 || uniform.value2 !== value2 || uniform.value3 !== value3 || uniform.value4 !== value4) {
if (!uniform.setter) {
uniform.setter = setter;
}
uniform.value1 = value1;
uniform.value2 = value2;
uniform.value3 = value3;
uniform.value4 = value4;
this.renderer.setProgram(this.program);
setter.call(this.gl, uniform.location.webGLUniformLocation, value1, value2, value3, value4);
this.pipeline.currentShader = this;
}
return this;
},
/**
* Sets a boolean uniform value based on the given name on this shader.
*
* The uniform is only set if the value/s given are different to those previously set.
*
* This method works by first setting this shader as being the current shader within the
* WebGL Renderer, if it isn't already. It also sets this shader as being the current
* one within the pipeline it belongs to.
*
* @method Phaser.Renderer.WebGL.WebGLShader#setBoolean
* @since 3.60.0
*
* @param {string} name - The name of the uniform to set.
* @param {boolean} value - The new value of the `boolean` uniform.
*
* @return {this} This WebGLShader instance.
*/
setBoolean: function(name, value) {
return this.setUniform1(this.gl.uniform1i, name, Number(value));
},
/**
* Sets a 1f uniform value based on the given name on this shader.
*
* The uniform is only set if the value/s given are different to those previously set.
*
* This method works by first setting this shader as being the current shader within the
* WebGL Renderer, if it isn't already. It also sets this shader as being the current
* one within the pipeline it belongs to.
*
* @method Phaser.Renderer.WebGL.WebGLShader#set1f
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number} x - The new value of the `float` uniform.
*
* @return {this} This WebGLShader instance.
*/
set1f: function(name, x) {
return this.setUniform1(this.gl.uniform1f, name, x);
},
/**
* Sets a 2f uniform value based on the given name on this shader.
*
* The uniform is only set if the value/s given are different to those previously set.
*
* This method works by first setting this shader as being the current shader within the
* WebGL Renderer, if it isn't already. It also sets this shader as being the current
* one within the pipeline it belongs to.
*
* @method Phaser.Renderer.WebGL.WebGLShader#set2f
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number} x - The new X component of the `vec2` uniform.
* @param {number} y - The new Y component of the `vec2` uniform.
*
* @return {this} This WebGLShader instance.
*/
set2f: function(name, x, y) {
return this.setUniform2(this.gl.uniform2f, name, x, y);
},
/**
* Sets a 3f uniform value based on the given name on this shader.
*
* The uniform is only set if the value/s given are different to those previously set.
*
* This method works by first setting this shader as being the current shader within the
* WebGL Renderer, if it isn't already. It also sets this shader as being the current
* one within the pipeline it belongs to.
*
* @method Phaser.Renderer.WebGL.WebGLShader#set3f
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number} x - The new X component of the `vec3` uniform.
* @param {number} y - The new Y component of the `vec3` uniform.
* @param {number} z - The new Z component of the `vec3` uniform.
*
* @return {this} This WebGLShader instance.
*/
set3f: function(name, x, y, z) {
return this.setUniform3(this.gl.uniform3f, name, x, y, z);
},
/**
* Sets a 4f uniform value based on the given name on this shader.
*
* The uniform is only set if the value/s given are different to those previously set.
*
* This method works by first setting this shader as being the current shader within the
* WebGL Renderer, if it isn't already. It also sets this shader as being the current
* one within the pipeline it belongs to.
*
* @method Phaser.Renderer.WebGL.WebGLShader#set4f
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number} x - X component of the uniform
* @param {number} y - Y component of the uniform
* @param {number} z - Z component of the uniform
* @param {number} w - W component of the uniform
*
* @return {this} This WebGLShader instance.
*/
set4f: function(name, x, y, z, w) {
return this.setUniform4(this.gl.uniform4f, name, x, y, z, w);
},
/**
* Sets a 1fv uniform value based on the given name on this shader.
*
* The uniform is only set if the value/s given are different to those previously set.
*
* This method works by first setting this shader as being the current shader within the
* WebGL Renderer, if it isn't already. It also sets this shader as being the current
* one within the pipeline it belongs to.
*
* @method Phaser.Renderer.WebGL.WebGLShader#set1fv
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number[]|Float32Array} arr - The new value to be used for the uniform variable.
*
* @return {this} This WebGLShader instance.
*/
set1fv: function(name, arr) {
return this.setUniform1(this.gl.uniform1fv, name, arr, true);
},
/**
* Sets a 2fv uniform value based on the given name on this shader.
*
* The uniform is only set if the value/s given are different to those previously set.
*
* This method works by first setting this shader as being the current shader within the
* WebGL Renderer, if it isn't already. It also sets this shader as being the current
* one within the pipeline it belongs to.
*
* @method Phaser.Renderer.WebGL.WebGLShader#set2fv
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number[]|Float32Array} arr - The new value to be used for the uniform variable.
*
* @return {this} This WebGLShader instance.
*/
set2fv: function(name, arr) {
return this.setUniform1(this.gl.uniform2fv, name, arr, true);
},
/**
* Sets a 3fv uniform value based on the given name on this shader.
*
* The uniform is only set if the value/s given are different to those previously set.
*
* This method works by first setting this shader as being the current shader within the
* WebGL Renderer, if it isn't already. It also sets this shader as being the current
* one within the pipeline it belongs to.
*
* @method Phaser.Renderer.WebGL.WebGLShader#set3fv
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number[]|Float32Array} arr - The new value to be used for the uniform variable.
*
* @return {this} This WebGLShader instance.
*/
set3fv: function(name, arr) {
return this.setUniform1(this.gl.uniform3fv, name, arr, true);
},
/**
* Sets a 4fv uniform value based on the given name on this shader.
*
* The uniform is only set if the value/s given are different to those previously set.
*
* This method works by first setting this shader as being the current shader within the
* WebGL Renderer, if it isn't already. It also sets this shader as being the current
* one within the pipeline it belongs to.
*
* @method Phaser.Renderer.WebGL.WebGLShader#set4fv
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number[]|Float32Array} arr - The new value to be used for the uniform variable.
*
* @return {this} This WebGLShader instance.
*/
set4fv: function(name, arr) {
return this.setUniform1(this.gl.uniform4fv, name, arr, true);
},
/**
* Sets a 1iv uniform value based on the given name on this shader.
*
* The uniform is only set if the value/s given are different to those previously set.
*
* This method works by first setting this shader as being the current shader within the
* WebGL Renderer, if it isn't already. It also sets this shader as being the current
* one within the pipeline it belongs to.
*
* @method Phaser.Renderer.WebGL.WebGLShader#set1iv
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number[]|Float32Array} arr - The new value to be used for the uniform variable.
*
* @return {this} This WebGLShader instance.
*/
set1iv: function(name, arr) {
return this.setUniform1(this.gl.uniform1iv, name, arr, true);
},
/**
* Sets a 2iv uniform value based on the given name on this shader.
*
* The uniform is only set if the value/s given are different to those previously set.
*
* This method works by first setting this shader as being the current shader within the
* WebGL Renderer, if it isn't already. It also sets this shader as being the current
* one within the pipeline it belongs to.
*
* @method Phaser.Renderer.WebGL.WebGLShader#set2iv
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number[]|Float32Array} arr - The new value to be used for the uniform variable.
*
* @return {this} This WebGLShader instance.
*/
set2iv: function(name, arr) {
return this.setUniform1(this.gl.uniform2iv, name, arr, true);
},
/**
* Sets a 3iv uniform value based on the given name on this shader.
*
* The uniform is only set if the value/s given are different to those previously set.
*
* This method works by first setting this shader as being the current shader within the
* WebGL Renderer, if it isn't already. It also sets this shader as being the current
* one within the pipeline it belongs to.
*
* @method Phaser.Renderer.WebGL.WebGLShader#set3iv
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number[]|Float32Array} arr - The new value to be used for the uniform variable.
*
* @return {this} This WebGLShader instance.
*/
set3iv: function(name, arr) {
return this.setUniform1(this.gl.uniform3iv, name, arr, true);
},
/**
* Sets a 4iv uniform value based on the given name on this shader.
*
* The uniform is only set if the value/s given are different to those previously set.
*
* This method works by first setting this shader as being the current shader within the
* WebGL Renderer, if it isn't already. It also sets this shader as being the current
* one within the pipeline it belongs to.
*
* @method Phaser.Renderer.WebGL.WebGLShader#set4iv
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number[]|Float32Array} arr - The new value to be used for the uniform variable.
*
* @return {this} This WebGLShader instance.
*/
set4iv: function(name, arr) {
return this.setUniform1(this.gl.uniform4iv, name, arr, true);
},
/**
* Sets a 1i uniform value based on the given name on this shader.
*
* The uniform is only set if the value/s given are different to those previously set.
*
* This method works by first setting this shader as being the current shader within the
* WebGL Renderer, if it isn't already. It also sets this shader as being the current
* one within the pipeline it belongs to.
*
* @method Phaser.Renderer.WebGL.WebGLShader#set1i
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number} x - The new value of the `int` uniform.
*
* @return {this} This WebGLShader instance.
*/
set1i: function(name, x) {
return this.setUniform1(this.gl.uniform1i, name, x);
},
/**
* Sets a 2i uniform value based on the given name on this shader.
*
* The uniform is only set if the value/s given are different to those previously set.
*
* This method works by first setting this shader as being the current shader within the
* WebGL Renderer, if it isn't already. It also sets this shader as being the current
* one within the pipeline it belongs to.
*
* @method Phaser.Renderer.WebGL.WebGLShader#set2i
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number} x - The new X component of the `ivec2` uniform.
* @param {number} y - The new Y component of the `ivec2` uniform.
*
* @return {this} This WebGLShader instance.
*/
set2i: function(name, x, y) {
return this.setUniform2(this.gl.uniform2i, name, x, y);
},
/**
* Sets a 3i uniform value based on the given name on this shader.
*
* The uniform is only set if the value/s given are different to those previously set.
*
* This method works by first setting this shader as being the current shader within the
* WebGL Renderer, if it isn't already. It also sets this shader as being the current
* one within the pipeline it belongs to.
*
* @method Phaser.Renderer.WebGL.WebGLShader#set3i
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number} x - The new X component of the `ivec3` uniform.
* @param {number} y - The new Y component of the `ivec3` uniform.
* @param {number} z - The new Z component of the `ivec3` uniform.
*
* @return {this} This WebGLShader instance.
*/
set3i: function(name, x, y, z) {
return this.setUniform3(this.gl.uniform3i, name, x, y, z);
},
/**
* Sets a 4i uniform value based on the given name on this shader.
*
* The uniform is only set if the value/s given are different to those previously set.
*
* This method works by first setting this shader as being the current shader within the
* WebGL Renderer, if it isn't already. It also sets this shader as being the current
* one within the pipeline it belongs to.
*
* @method Phaser.Renderer.WebGL.WebGLShader#set4i
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {number} x - X component of the uniform
* @param {number} y - Y component of the uniform
* @param {number} z - Z component of the uniform
* @param {number} w - W component of the uniform
*
* @return {this} This WebGLShader instance.
*/
set4i: function(name, x, y, z, w) {
return this.setUniform4(this.gl.uniform4i, name, x, y, z, w);
},
/**
* Sets a matrix 2fv uniform value based on the given name on this shader.
*
* The uniform is only set if the value/s given are different to those previously set.
*
* This method works by first setting this shader as being the current shader within the
* WebGL Renderer, if it isn't already. It also sets this shader as being the current
* one within the pipeline it belongs to.
*
* @method Phaser.Renderer.WebGL.WebGLShader#setMatrix2fv
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {boolean} transpose - Whether to transpose the matrix. Should be `false`.
* @param {number[]|Float32Array} matrix - The new values for the `mat2` uniform.
*
* @return {this} This WebGLShader instance.
*/
setMatrix2fv: function(name, transpose, matrix) {
return this.setUniform2(this.gl.uniformMatrix2fv, name, transpose, matrix, true);
},
/**
* Sets a matrix 3fv uniform value based on the given name on this shader.
*
* The uniform is only set if the value/s given are different to those previously set.
*
* This method works by first setting this shader as being the current shader within the
* WebGL Renderer, if it isn't already. It also sets this shader as being the current
* one within the pipeline it belongs to.
*
* @method Phaser.Renderer.WebGL.WebGLShader#setMatrix3fv
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {boolean} transpose - Whether to transpose the matrix. Should be `false`.
* @param {Float32Array} matrix - The new values for the `mat3` uniform.
*
* @return {this} This WebGLShader instance.
*/
setMatrix3fv: function(name, transpose, matrix) {
return this.setUniform2(this.gl.uniformMatrix3fv, name, transpose, matrix, true);
},
/**
* Sets a matrix 4fv uniform value based on the given name on this shader.
*
* The uniform is only set if the value/s given are different to those previously set.
*
* This method works by first setting this shader as being the current shader within the
* WebGL Renderer, if it isn't already. It also sets this shader as being the current
* one within the pipeline it belongs to.
*
* @method Phaser.Renderer.WebGL.WebGLShader#setMatrix4fv
* @since 3.50.0
*
* @param {string} name - The name of the uniform to set.
* @param {boolean} transpose - Should the matrix be transpose
* @param {Float32Array} matrix - Matrix data
*
* @return {this} This WebGLShader instance.
*/
setMatrix4fv: function(name, transpose, matrix) {
return this.setUniform2(this.gl.uniformMatrix4fv, name, transpose, matrix, true);
},
/**
* This method will create the Shader Program on the current GL context.
*
* If a program already exists, it will be destroyed and the new one will take its place.
*
* After the program is created the uniforms will be reset and
* this shader will be rebound.
*
* This is a very expensive process and if your shader is referenced elsewhere in
* your game those references may then be lost, so be sure to use this carefully.
*
* However, if you need to update say the fragment shader source, then you can pass
* the new source into this method and it'll rebuild the program using it. If you
* don't want to change the vertex shader src, pass `undefined` as the parameter.
*
* @method Phaser.Renderer.WebGL.WebGLShader#createProgram
* @since 3.60.0
*
* @param {string} [vertSrc] - The source code of the vertex shader. If not given, uses the source already defined in this Shader.
* @param {string} [fragSrc] - The source code of the fragment shader. If not given, uses the source already defined in this Shader.
*
* @return {this} This WebGLShader instance.
*/
createProgram: function(vertSrc, fragSrc) {
if (vertSrc === void 0) {
vertSrc = this.vertSrc;
}
if (fragSrc === void 0) {
fragSrc = this.fragSrc;
}
if (this.program) {
this.renderer.deleteProgram(this.program);
}
this.vertSrc = vertSrc;
this.fragSrc = fragSrc;
this.program = this.renderer.createProgram(vertSrc, fragSrc);
this.createUniforms();
return this.rebind();
},
/**
* Removes all external references from this class and deletes the WebGL program from the WebGL context.
*
* Does not remove this shader from the parent pipeline.
*
* @method Phaser.Renderer.WebGL.WebGLShader#destroy
* @since 3.50.0
*/
destroy: function() {
var renderer = this.renderer;
ArrayEach(this.uniforms, function(uniform) {
renderer.deleteUniformLocation(uniform.location);
});
this.uniforms = null;
ArrayEach(this.attributes, function(attrib) {
renderer.deleteAttribLocation(attrib.location);
});
this.attributes = null;
renderer.deleteProgram(this.program);
this.pipeline = null;
this.renderer = null;
this.gl = null;
this.program = null;
}
});
module2.exports = WebGLShader;
}
),
/***/
14500: (
/***/
(module2) => {
var WEBGL_CONST = {
/**
* 8-bit twos complement signed integer.
*
* @name Phaser.Renderer.WebGL.BYTE
* @type {Phaser.Types.Renderer.WebGL.WebGLConst}
* @since 3.50.0
*/
BYTE: { enum: 5120, size: 1 },
/**
* 8-bit twos complement unsigned integer.
*
* @name Phaser.Renderer.WebGL.UNSIGNED_BYTE
* @type {Phaser.Types.Renderer.WebGL.WebGLConst}
* @since 3.50.0
*/
UNSIGNED_BYTE: { enum: 5121, size: 1 },
/**
* 16-bit twos complement signed integer.
*
* @name Phaser.Renderer.WebGL.SHORT
* @type {Phaser.Types.Renderer.WebGL.WebGLConst}
* @since 3.50.0
*/
SHORT: { enum: 5122, size: 2 },
/**
* 16-bit twos complement unsigned integer.
*
* @name Phaser.Renderer.WebGL.UNSIGNED_SHORT
* @type {Phaser.Types.Renderer.WebGL.WebGLConst}
* @since 3.50.0
*/
UNSIGNED_SHORT: { enum: 5123, size: 2 },
/**
* 32-bit twos complement signed integer.
*
* @name Phaser.Renderer.WebGL.INT
* @type {Phaser.Types.Renderer.WebGL.WebGLConst}
* @since 3.50.0
*/
INT: { enum: 5124, size: 4 },
/**
* 32-bit twos complement unsigned integer.
*
* @name Phaser.Renderer.WebGL.UNSIGNED_INT
* @type {Phaser.Types.Renderer.WebGL.WebGLConst}
* @since 3.50.0
*/
UNSIGNED_INT: { enum: 5125, size: 4 },
/**
* 32-bit IEEE floating point number.
*
* @name Phaser.Renderer.WebGL.FLOAT
* @type {Phaser.Types.Renderer.WebGL.WebGLConst}
* @since 3.50.0
*/
FLOAT: { enum: 5126, size: 4 }
};
module2.exports = WEBGL_CONST;
}
),
/***/
4159: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var WEBGL_CONST = __webpack_require__2(14500);
var Extend = __webpack_require__2(79291);
var WebGL = {
PipelineManager: __webpack_require__2(7530),
Pipelines: __webpack_require__2(96615),
RenderTarget: __webpack_require__2(32302),
Utils: __webpack_require__2(70554),
WebGLPipeline: __webpack_require__2(29100),
WebGLRenderer: __webpack_require__2(74797),
WebGLShader: __webpack_require__2(38683),
Wrappers: __webpack_require__2(9503)
};
WebGL = Extend(false, WebGL, WEBGL_CONST);
module2.exports = WebGL;
}
),
/***/
31302: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var GetFastValue = __webpack_require__2(95540);
var ShaderSourceFS = __webpack_require__2(78908);
var ShaderSourceVS = __webpack_require__2(85191);
var WEBGL_CONST = __webpack_require__2(14500);
var WebGLPipeline = __webpack_require__2(29100);
var BitmapMaskPipeline = new Class({
Extends: WebGLPipeline,
initialize: function BitmapMaskPipeline2(config) {
config.fragShader = GetFastValue(config, "fragShader", ShaderSourceFS), config.vertShader = GetFastValue(config, "vertShader", ShaderSourceVS), config.batchSize = GetFastValue(config, "batchSize", 1), config.vertices = GetFastValue(config, "vertices", [-1, 1, -1, -7, 7, 1]), config.attributes = GetFastValue(config, "attributes", [
{
name: "inPosition",
size: 2,
type: WEBGL_CONST.FLOAT
}
]);
WebGLPipeline.call(this, config);
},
boot: function() {
WebGLPipeline.prototype.boot.call(this);
this.set1i("uMainSampler", 0);
this.set1i("uMaskSampler", 1);
},
resize: function(width, height) {
WebGLPipeline.prototype.resize.call(this, width, height);
this.set2f("uResolution", width, height);
},
/**
* Binds necessary resources and renders the mask to a separated framebuffer.
* The framebuffer for the masked object is also bound for further use.
*
* @method Phaser.Renderer.WebGL.Pipelines.BitmapMaskPipeline#beginMask
* @since 3.0.0
*
* @param {Phaser.Display.Masks.BitmapMask} mask - The BitmapMask instance that called beginMask.
* @param {Phaser.GameObjects.GameObject} maskedObject - GameObject masked by the mask GameObject.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The camera rendering the current mask.
*/
beginMask: function(mask, maskedObject, camera) {
this.renderer.beginBitmapMask(mask, camera);
},
/**
* The masked game objects framebuffer is unbound and its texture
* is bound together with the mask texture and the mask shader and
* a draw call with a single quad is processed. Here is where the
* masking effect is applied.
*
* @method Phaser.Renderer.WebGL.Pipelines.BitmapMaskPipeline#endMask
* @since 3.0.0
*
* @param {Phaser.Display.Masks.BitmapMask} mask - The BitmapMask instance that called endMask.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to render to.
* @param {Phaser.Renderer.WebGL.RenderTarget} [renderTarget] - Optional WebGL RenderTarget.
*/
endMask: function(mask, camera, renderTarget) {
var gl = this.gl;
var renderer = this.renderer;
var bitmapMask = mask.bitmapMask;
if (bitmapMask && gl) {
renderer.drawBitmapMask(bitmapMask, camera, this);
if (renderTarget) {
this.set2f("uResolution", renderTarget.width, renderTarget.height);
}
this.set1i("uInvertMaskAlpha", mask.invertAlpha);
gl.drawArrays(this.topology, 0, 3);
if (renderTarget) {
this.set2f("uResolution", this.width, this.height);
}
gl.bindTexture(gl.TEXTURE_2D, null);
}
}
});
module2.exports = BitmapMaskPipeline;
}
),
/***/
92651: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var FX = __webpack_require__2(58918);
var FX_CONST = __webpack_require__2(14811);
var GetFastValue = __webpack_require__2(95540);
var PreFXPipeline = __webpack_require__2(43558);
var Shaders = __webpack_require__2(89350);
var Utils = __webpack_require__2(70554);
var FXPipeline = new Class({
Extends: PreFXPipeline,
initialize: function FXPipeline2(config) {
config.shaders = [
Utils.setGlowQuality(Shaders.FXGlowFrag, config.game),
Shaders.FXShadowFrag,
Shaders.FXPixelateFrag,
Shaders.FXVignetteFrag,
Shaders.FXShineFrag,
Shaders.FXBlurLowFrag,
Shaders.FXBlurMedFrag,
Shaders.FXBlurHighFrag,
Shaders.FXGradientFrag,
Shaders.FXBloomFrag,
Shaders.ColorMatrixFrag,
Shaders.FXCircleFrag,
Shaders.FXBarrelFrag,
Shaders.FXDisplacementFrag,
Shaders.FXWipeFrag,
Shaders.FXBokehFrag
];
PreFXPipeline.call(this, config);
var game = this.game;
this.glow = new FX.Glow(game);
this.shadow = new FX.Shadow(game);
this.pixelate = new FX.Pixelate(game);
this.vignette = new FX.Vignette(game);
this.shine = new FX.Shine(game);
this.gradient = new FX.Gradient(game);
this.circle = new FX.Circle(game);
this.barrel = new FX.Barrel(game);
this.wipe = new FX.Wipe(game);
this.bokeh = new FX.Bokeh(game);
var fxHandlers = [];
fxHandlers[FX_CONST.GLOW] = this.onGlow;
fxHandlers[FX_CONST.SHADOW] = this.onShadow;
fxHandlers[FX_CONST.PIXELATE] = this.onPixelate;
fxHandlers[FX_CONST.VIGNETTE] = this.onVignette;
fxHandlers[FX_CONST.SHINE] = this.onShine;
fxHandlers[FX_CONST.BLUR] = this.onBlur;
fxHandlers[FX_CONST.GRADIENT] = this.onGradient;
fxHandlers[FX_CONST.BLOOM] = this.onBloom;
fxHandlers[FX_CONST.COLOR_MATRIX] = this.onColorMatrix;
fxHandlers[FX_CONST.CIRCLE] = this.onCircle;
fxHandlers[FX_CONST.BARREL] = this.onBarrel;
fxHandlers[FX_CONST.DISPLACEMENT] = this.onDisplacement;
fxHandlers[FX_CONST.WIPE] = this.onWipe;
fxHandlers[FX_CONST.BOKEH] = this.onBokeh;
this.fxHandlers = fxHandlers;
this.source;
this.target;
this.swap;
},
/**
* Takes the currently bound Game Object and runs all of its pre-render effects,
* using the given Render Target as the source.
*
* Finally calls `drawToGame` to copy the result to the Game Canvas.
*
* @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onDraw
* @since 3.60.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} target1 - The source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} target2 - The target Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} target3 - The swap Render Target.
*/
onDraw: function(target1, target2, target3) {
this.source = target1;
this.target = target2;
this.swap = target3;
var width = target1.width;
var height = target1.height;
var sprite = this.tempSprite;
var handlers = this.fxHandlers;
if (sprite && sprite.preFX) {
var fx = sprite.preFX.list;
for (var i = 0; i < fx.length; i++) {
var controller = fx[i];
if (controller.active) {
handlers[controller.type].call(this, controller, width, height);
}
}
}
this.drawToGame(this.source);
},
/**
* Takes the source and target and runs a copy from source to target.
*
* This will use the current shader and pipeline.
*
* @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#runDraw
* @since 3.60.0
*/
runDraw: function() {
var source = this.source;
var target = this.target;
this.copy(source, target);
this.source = target;
this.target = source;
},
/**
* Runs the Glow FX controller.
*
* @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onGlow
* @since 3.60.0
*
* @param {Phaser.FX.Glow} config - The Glow FX controller.
* @param {number} width - The width of the target.
* @param {number} height - The height of the target.
*/
onGlow: function(config, width, height) {
var shader = this.shaders[FX_CONST.GLOW];
this.setShader(shader);
this.glow.onPreRender(config, shader, width, height);
this.runDraw();
},
/**
* Runs the Shadow FX controller.
*
* @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onShadow
* @since 3.60.0
*
* @param {Phaser.FX.Shadow} config - The Shadow FX controller.
*/
onShadow: function(config) {
var shader = this.shaders[FX_CONST.SHADOW];
this.setShader(shader);
this.shadow.onPreRender(config, shader);
this.runDraw();
},
/**
* Runs the Pixelate FX controller.
*
* @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onPixelate
* @since 3.60.0
*
* @param {Phaser.FX.Pixelate} config - The Pixelate FX controller.
* @param {number} width - The width of the target.
* @param {number} height - The height of the target.
*/
onPixelate: function(config, width, height) {
var shader = this.shaders[FX_CONST.PIXELATE];
this.setShader(shader);
this.pixelate.onPreRender(config, shader, width, height);
this.runDraw();
},
/**
* Runs the Vignette FX controller.
*
* @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onVignette
* @since 3.60.0
*
* @param {Phaser.FX.Vignette} config - The Vignette FX controller.
*/
onVignette: function(config) {
var shader = this.shaders[FX_CONST.VIGNETTE];
this.setShader(shader);
this.vignette.onPreRender(config, shader);
this.runDraw();
},
/**
* Runs the Shine FX controller.
*
* @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onShine
* @since 3.60.0
*
* @param {Phaser.FX.Shine} config - The Shine FX controller.
* @param {number} width - The width of the target.
* @param {number} height - The height of the target.
*/
onShine: function(config, width, height) {
var shader = this.shaders[FX_CONST.SHINE];
this.setShader(shader);
this.shine.onPreRender(config, shader, width, height);
this.runDraw();
},
/**
* Runs the Blur FX controller.
*
* @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onBlur
* @since 3.60.0
*
* @param {Phaser.FX.Blur} config - The Blur FX controller.
* @param {number} width - The width of the target.
* @param {number} height - The height of the target.
*/
onBlur: function(config, width, height) {
var quality = GetFastValue(config, "quality");
var shader = this.shaders[FX_CONST.BLUR + quality];
this.setShader(shader);
this.set1i("uMainSampler", 0);
this.set2f("resolution", width, height);
this.set1f("strength", GetFastValue(config, "strength"));
this.set3fv("color", GetFastValue(config, "glcolor"));
var x = GetFastValue(config, "x");
var y = GetFastValue(config, "y");
var steps = GetFastValue(config, "steps");
for (var i = 0; i < steps; i++) {
this.set2f("offset", x, 0);
this.runDraw();
this.set2f("offset", 0, y);
this.runDraw();
}
},
/**
* Runs the Gradient FX controller.
*
* @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onGradient
* @since 3.60.0
*
* @param {Phaser.FX.Gradient} config - The Gradient FX controller.
*/
onGradient: function(config) {
var shader = this.shaders[FX_CONST.GRADIENT];
this.setShader(shader);
this.gradient.onPreRender(config, shader);
this.runDraw();
},
/**
* Runs the Bloom FX controller.
*
* @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onBloom
* @since 3.60.0
*
* @param {Phaser.FX.Bloom} config - The Bloom FX controller.
* @param {number} width - The width of the target.
* @param {number} height - The height of the target.
*/
onBloom: function(config, width, height) {
var shader = this.shaders[FX_CONST.BLOOM];
this.copySprite(this.source, this.swap);
this.setShader(shader);
this.set1i("uMainSampler", 0);
this.set1f("strength", GetFastValue(config, "blurStrength"));
this.set3fv("color", GetFastValue(config, "glcolor"));
var x = 2 / width * GetFastValue(config, "offsetX");
var y = 2 / height * GetFastValue(config, "offsetY");
var steps = GetFastValue(config, "steps");
for (var i = 0; i < steps; i++) {
this.set2f("offset", x, 0);
this.runDraw();
this.set2f("offset", 0, y);
this.runDraw();
}
this.blendFrames(this.swap, this.source, this.target, GetFastValue(config, "strength"));
this.copySprite(this.target, this.source);
},
/**
* Runs the ColorMatrix FX controller.
*
* @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onColorMatrix
* @since 3.60.0
*
* @param {Phaser.FX.ColorMatrix} config - The ColorMatrix FX controller.
*/
onColorMatrix: function(config) {
this.setShader(this.colorMatrixShader);
this.set1fv("uColorMatrix", config.getData());
this.set1f("uAlpha", config.alpha);
this.runDraw();
},
/**
* Runs the Circle FX controller.
*
* @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onCircle
* @since 3.60.0
*
* @param {Phaser.FX.Circle} config - The Circle FX controller.
* @param {number} width - The width of the target.
* @param {number} height - The height of the target.
*/
onCircle: function(config, width, height) {
var shader = this.shaders[FX_CONST.CIRCLE];
this.setShader(shader);
this.circle.onPreRender(config, shader, width, height);
this.runDraw();
},
/**
* Runs the Barrel FX controller.
*
* @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onBarrel
* @since 3.60.0
*
* @param {Phaser.FX.Barrel} config - The Barrel FX controller.
*/
onBarrel: function(config) {
var shader = this.shaders[FX_CONST.BARREL];
this.setShader(shader);
this.barrel.onPreRender(config, shader);
this.runDraw();
},
/**
* Runs the Displacement FX controller.
*
* @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onDisplacement
* @since 3.60.0
*
* @param {Phaser.FX.Displacement} config - The Displacement FX controller.
*/
onDisplacement: function(config) {
this.setShader(this.shaders[FX_CONST.DISPLACEMENT]);
this.set1i("uDisplacementSampler", 1);
this.set2f("amount", config.x, config.y);
this.bindTexture(config.glTexture, 1);
this.runDraw();
},
/**
* Runs the Wipe FX controller.
*
* @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onWipe
* @since 3.60.0
*
* @param {Phaser.FX.Wipe} config - The Wipe FX controller.
*/
onWipe: function(config) {
var shader = this.shaders[FX_CONST.WIPE];
this.setShader(shader);
this.wipe.onPreRender(config, shader);
this.runDraw();
},
/**
* Runs the Bokeh FX controller.
*
* @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#onBokeh
* @since 3.60.0
*
* @param {Phaser.FX.Bokeh} config - The Bokeh FX controller.
*/
onBokeh: function(config, width, height) {
var shader = this.shaders[FX_CONST.BOKEH];
this.setShader(shader);
this.bokeh.onPreRender(config, shader, width, height);
this.runDraw();
},
/**
* Destroys all shader instances, removes all object references and nulls all external references.
*
* @method Phaser.Renderer.WebGL.Pipelines.FXPipeline#destroy
* @since 3.60.0
*
* @return {this} This WebGLPipeline instance.
*/
destroy: function() {
this.glow.destroy();
this.shadow.destroy();
this.pixelate.destroy();
this.vignette.destroy();
this.shine.destroy();
this.gradient.destroy();
this.circle.destroy();
this.barrel.destroy();
this.wipe.destroy();
this.bokeh.destroy();
this.fxHandlers = null;
this.source = null;
this.target = null;
this.swap = null;
PreFXPipeline.prototype.destroy.call(this);
return this;
}
});
module2.exports = FXPipeline;
}
),
/***/
96569: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var GetFastValue = __webpack_require__2(95540);
var LightShaderSourceFS = __webpack_require__2(31063);
var MultiPipeline = __webpack_require__2(57516);
var TransformMatrix = __webpack_require__2(61340);
var Vec2 = __webpack_require__2(26099);
var WebGLPipeline = __webpack_require__2(29100);
var LightPipeline = new Class({
Extends: MultiPipeline,
initialize: function LightPipeline2(config) {
var fragShader = GetFastValue(config, "fragShader", LightShaderSourceFS);
config.fragShader = fragShader.replace("%LIGHT_COUNT%", config.game.renderer.config.maxLights);
MultiPipeline.call(this, config);
this.inverseRotationMatrix = new Float32Array([
1,
0,
0,
0,
1,
0,
0,
0,
1
]);
this.currentNormalMap;
this.lightsActive = true;
this.tempVec2 = new Vec2();
this._tempMatrix = new TransformMatrix();
this._tempMatrix2 = new TransformMatrix();
},
/**
* Called when the Game has fully booted and the Renderer has finished setting up.
*
* By this stage all Game level systems are now in place and you can perform any final
* tasks that the pipeline may need that relied on game systems such as the Texture Manager.
*
* @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#boot
* @since 3.11.0
*/
boot: function() {
WebGLPipeline.prototype.boot.call(this);
},
/**
* This function sets all the needed resources for each camera pass.
*
* @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#onRender
* @ignore
* @since 3.0.0
*
* @param {Phaser.Scene} scene - The Scene being rendered.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Scene Camera being rendered with.
*/
onRender: function(scene, camera) {
var lightManager = scene.sys.lights;
this.lightsActive = false;
if (!lightManager || !lightManager.active) {
return;
}
var lights = lightManager.getLights(camera);
var lightsCount = lights.length;
this.lightsActive = true;
var i;
var renderer = this.renderer;
var height = renderer.height;
var cameraMatrix = camera.matrix;
var tempVec2 = this.tempVec2;
this.set1i("uMainSampler", 0);
this.set1i("uNormSampler", 1);
this.set2f("uResolution", this.width / 2, this.height / 2);
this.set4f("uCamera", camera.x, camera.y, camera.rotation, camera.zoom);
this.set3f("uAmbientLightColor", lightManager.ambientColor.r, lightManager.ambientColor.g, lightManager.ambientColor.b);
this.set1i("uLightCount", lightsCount);
for (i = 0; i < lightsCount; i++) {
var light = lights[i].light;
var color = light.color;
var lightName = "uLights[" + i + "].";
cameraMatrix.transformPoint(light.x, light.y, tempVec2);
this.set2f(lightName + "position", tempVec2.x - camera.scrollX * light.scrollFactorX * camera.zoom, height - (tempVec2.y - camera.scrollY * light.scrollFactorY * camera.zoom));
this.set3f(lightName + "color", color.r, color.g, color.b);
this.set1f(lightName + "intensity", light.intensity);
this.set1f(lightName + "radius", light.radius);
}
this.currentNormalMapRotation = null;
},
/**
* Rotates the normal map vectors inversely by the given angle.
* Only works in 2D space.
*
* @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#setNormalMapRotation
* @since 3.16.0
*
* @param {number} rotation - The angle of rotation in radians.
*/
setNormalMapRotation: function(rotation) {
if (rotation !== this.currentNormalMapRotation || this.vertexCount === 0) {
if (this.vertexCount > 0) {
this.flush();
}
var inverseRotationMatrix = this.inverseRotationMatrix;
if (rotation) {
var rot = -rotation;
var c = Math.cos(rot);
var s = Math.sin(rot);
inverseRotationMatrix[1] = s;
inverseRotationMatrix[3] = -s;
inverseRotationMatrix[0] = inverseRotationMatrix[4] = c;
} else {
inverseRotationMatrix[0] = inverseRotationMatrix[4] = 1;
inverseRotationMatrix[1] = inverseRotationMatrix[3] = 0;
}
this.setMatrix3fv("uInverseRotationMatrix", false, inverseRotationMatrix);
this.currentNormalMapRotation = rotation;
}
},
/**
* Assigns a texture to the current batch. If a different texture is already set it creates a new batch object.
*
* @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#setTexture2D
* @ignore
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} [texture] - Texture that will be assigned to the current batch. If not given uses blankTexture.
* @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object being rendered or added to the batch.
*/
setTexture2D: function(texture, gameObject) {
var renderer = this.renderer;
if (texture === void 0) {
texture = renderer.whiteTexture;
}
var normalMap = this.getNormalMap(gameObject);
if (this.isNewNormalMap(texture, normalMap)) {
this.flush();
this.createBatch(texture);
this.addTextureToBatch(normalMap);
this.currentNormalMap = normalMap;
}
var rotation = 0;
if (gameObject && gameObject.parentContainer) {
var matrix = gameObject.getWorldTransformMatrix(this._tempMatrix, this._tempMatrix2);
rotation = matrix.rotationNormalized;
} else if (gameObject) {
rotation = gameObject.rotation;
}
if (this.currentBatch === null) {
this.createBatch(texture);
this.addTextureToBatch(normalMap);
}
this.setNormalMapRotation(rotation);
return 0;
},
/**
* Custom pipelines can use this method in order to perform any required pre-batch tasks
* for the given Game Object. It must return the texture unit the Game Object was assigned.
*
* @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#setGameObject
* @ignore
* @since 3.50.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object being rendered or added to the batch.
* @param {Phaser.Textures.Frame} [frame] - Optional frame to use. Can override that of the Game Object.
*
* @return {number} The texture unit the Game Object has been assigned.
*/
setGameObject: function(gameObject, frame) {
if (frame === void 0) {
frame = gameObject.frame;
}
var texture = frame.glTexture;
var normalMap = this.getNormalMap(gameObject);
if (this.isNewNormalMap(texture, normalMap)) {
this.flush();
this.createBatch(texture);
this.addTextureToBatch(normalMap);
this.currentNormalMap = normalMap;
}
if (gameObject.parentContainer) {
var matrix = gameObject.getWorldTransformMatrix(this._tempMatrix, this._tempMatrix2);
this.setNormalMapRotation(matrix.rotationNormalized);
} else {
this.setNormalMapRotation(gameObject.rotation);
}
if (this.currentBatch === null) {
this.createBatch(texture);
this.addTextureToBatch(normalMap);
}
return 0;
},
/**
* Checks to see if the given diffuse and normal map textures are already bound, or not.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#isNewNormalMap
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} texture - The diffuse texture.
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} normalMap - The normal map texture.
*
* @return {boolean} Returns `false` if this combination is already set, or `true` if it's a new combination.
*/
isNewNormalMap: function(texture, normalMap) {
return this.currentTexture !== texture || this.currentNormalMap !== normalMap;
},
/**
* Returns the normal map WebGLTextureWrapper from the given Game Object.
* If the Game Object doesn't have one, it returns the default normal map from this pipeline instead.
*
* @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#getNormalMap
* @since 3.50.0
*
* @param {Phaser.GameObjects.GameObject} [gameObject] - The Game Object to get the normal map from.
*
* @return {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} The normal map texture.
*/
getNormalMap: function(gameObject) {
var normalMap;
if (!gameObject) {
return this.renderer.normalTexture;
} else if (gameObject.displayTexture) {
normalMap = gameObject.displayTexture.dataSource[gameObject.displayFrame.sourceIndex];
} else if (gameObject.texture) {
normalMap = gameObject.texture.dataSource[gameObject.frame.sourceIndex];
} else if (gameObject.tileset) {
if (Array.isArray(gameObject.tileset)) {
normalMap = gameObject.tileset[0].image.dataSource[0];
} else {
normalMap = gameObject.tileset.image.dataSource[0];
}
}
if (!normalMap) {
return this.renderer.normalTexture;
}
return normalMap.glTexture;
},
/**
* Takes a Sprite Game Object, or any object that extends it, and adds it to the batch.
*
* @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#batchSprite
* @since 3.50.0
*
* @param {(Phaser.GameObjects.Image|Phaser.GameObjects.Sprite)} gameObject - The texture based Game Object to add to the batch.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use for the rendering transform.
* @param {Phaser.GameObjects.Components.TransformMatrix} [parentTransformMatrix] - The transform matrix of the parent container, if set.
*/
batchSprite: function(gameObject, camera, parentTransformMatrix) {
if (this.lightsActive) {
MultiPipeline.prototype.batchSprite.call(this, gameObject, camera, parentTransformMatrix);
}
},
/**
* Generic function for batching a textured quad using argument values instead of a Game Object.
*
* @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#batchTexture
* @since 3.50.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - Source GameObject.
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} texture - Texture associated with the quad.
* @param {number} textureWidth - Real texture width.
* @param {number} textureHeight - Real texture height.
* @param {number} srcX - X coordinate of the quad.
* @param {number} srcY - Y coordinate of the quad.
* @param {number} srcWidth - Width of the quad.
* @param {number} srcHeight - Height of the quad.
* @param {number} scaleX - X component of scale.
* @param {number} scaleY - Y component of scale.
* @param {number} rotation - Rotation of the quad.
* @param {boolean} flipX - Indicates if the quad is horizontally flipped.
* @param {boolean} flipY - Indicates if the quad is vertically flipped.
* @param {number} scrollFactorX - By which factor is the quad affected by the camera horizontal scroll.
* @param {number} scrollFactorY - By which factor is the quad effected by the camera vertical scroll.
* @param {number} displayOriginX - Horizontal origin in pixels.
* @param {number} displayOriginY - Vertical origin in pixels.
* @param {number} frameX - X coordinate of the texture frame.
* @param {number} frameY - Y coordinate of the texture frame.
* @param {number} frameWidth - Width of the texture frame.
* @param {number} frameHeight - Height of the texture frame.
* @param {number} tintTL - Tint for top left.
* @param {number} tintTR - Tint for top right.
* @param {number} tintBL - Tint for bottom left.
* @param {number} tintBR - Tint for bottom right.
* @param {number} tintEffect - The tint effect.
* @param {number} uOffset - Horizontal offset on texture coordinate.
* @param {number} vOffset - Vertical offset on texture coordinate.
* @param {Phaser.Cameras.Scene2D.Camera} camera - Current used camera.
* @param {Phaser.GameObjects.Components.TransformMatrix} parentTransformMatrix - Parent container.
* @param {boolean} [skipFlip=false] - Skip the renderTexture check.
* @param {number} [textureUnit] - Use the currently bound texture unit?
*/
batchTexture: function(gameObject, texture, textureWidth, textureHeight, srcX, srcY, srcWidth, srcHeight, scaleX, scaleY, rotation, flipX, flipY, scrollFactorX, scrollFactorY, displayOriginX, displayOriginY, frameX, frameY, frameWidth, frameHeight, tintTL, tintTR, tintBL, tintBR, tintEffect, uOffset, vOffset, camera, parentTransformMatrix, skipFlip, textureUnit) {
if (this.lightsActive) {
MultiPipeline.prototype.batchTexture.call(
this,
gameObject,
texture,
textureWidth,
textureHeight,
srcX,
srcY,
srcWidth,
srcHeight,
scaleX,
scaleY,
rotation,
flipX,
flipY,
scrollFactorX,
scrollFactorY,
displayOriginX,
displayOriginY,
frameX,
frameY,
frameWidth,
frameHeight,
tintTL,
tintTR,
tintBL,
tintBR,
tintEffect,
uOffset,
vOffset,
camera,
parentTransformMatrix,
skipFlip,
textureUnit
);
}
},
/**
* Adds a Texture Frame into the batch for rendering.
*
* @method Phaser.Renderer.WebGL.Pipelines.LightPipeline#batchTextureFrame
* @since 3.50.0
*
* @param {Phaser.Textures.Frame} frame - The Texture Frame to be rendered.
* @param {number} x - The horizontal position to render the texture at.
* @param {number} y - The vertical position to render the texture at.
* @param {number} tint - The tint color.
* @param {number} alpha - The alpha value.
* @param {Phaser.GameObjects.Components.TransformMatrix} transformMatrix - The Transform Matrix to use for the texture.
* @param {Phaser.GameObjects.Components.TransformMatrix} [parentTransformMatrix] - A parent Transform Matrix.
*/
batchTextureFrame: function(frame, x, y, tint, alpha, transformMatrix, parentTransformMatrix) {
if (this.lightsActive) {
MultiPipeline.prototype.batchTextureFrame.call(
this,
frame,
x,
y,
tint,
alpha,
transformMatrix,
parentTransformMatrix
);
}
}
});
module2.exports = LightPipeline;
}
),
/***/
56527: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var GetFastValue = __webpack_require__2(95540);
var MultiPipeline = __webpack_require__2(57516);
var ShaderSourceFS = __webpack_require__2(45561);
var ShaderSourceVS = __webpack_require__2(60722);
var WEBGL_CONST = __webpack_require__2(14500);
var WebGLPipeline = __webpack_require__2(29100);
var MobilePipeline = new Class({
Extends: MultiPipeline,
initialize: function MobilePipeline2(config) {
config.fragShader = GetFastValue(config, "fragShader", ShaderSourceFS);
config.vertShader = GetFastValue(config, "vertShader", ShaderSourceVS);
config.attributes = GetFastValue(config, "attributes", [
{
name: "inPosition",
size: 2
},
{
name: "inTexCoord",
size: 2
},
{
name: "inTexId"
},
{
name: "inTintEffect"
},
{
name: "inTint",
size: 4,
type: WEBGL_CONST.UNSIGNED_BYTE,
normalized: true
}
]);
config.forceZero = true;
config.resizeUniform = "uResolution";
MultiPipeline.call(this, config);
},
/**
* Called when the Game has fully booted and the Renderer has finished setting up.
*
* By this stage all Game level systems are now in place and you can perform any final
* tasks that the pipeline may need that relied on game systems such as the Texture Manager.
*
* @method Phaser.Renderer.WebGL.Pipelines.MobilePipeline#boot
* @since 3.60.0
*/
boot: function() {
WebGLPipeline.prototype.boot.call(this);
var renderer = this.renderer;
this.set1i("uMainSampler", 0);
this.set2f("uResolution", renderer.width, renderer.height);
}
});
module2.exports = MobilePipeline;
}
),
/***/
57516: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Earcut = __webpack_require__2(94811);
var GetFastValue = __webpack_require__2(95540);
var ShaderSourceFS = __webpack_require__2(98840);
var ShaderSourceVS = __webpack_require__2(44667);
var TransformMatrix = __webpack_require__2(61340);
var Utils = __webpack_require__2(70554);
var WEBGL_CONST = __webpack_require__2(14500);
var WebGLPipeline = __webpack_require__2(29100);
var MultiPipeline = new Class({
Extends: WebGLPipeline,
initialize: function MultiPipeline2(config) {
var renderer = config.game.renderer;
var fragmentShaderSource = GetFastValue(config, "fragShader", ShaderSourceFS);
config.fragShader = Utils.parseFragmentShaderMaxTextures(fragmentShaderSource, renderer.maxTextures);
config.vertShader = GetFastValue(config, "vertShader", ShaderSourceVS);
config.attributes = GetFastValue(config, "attributes", [
{
name: "inPosition",
size: 2
},
{
name: "inTexCoord",
size: 2
},
{
name: "inTexId"
},
{
name: "inTintEffect"
},
{
name: "inTint",
size: 4,
type: WEBGL_CONST.UNSIGNED_BYTE,
normalized: true
}
]);
config.resizeUniform = "uResolution";
WebGLPipeline.call(this, config);
this._tempMatrix1 = new TransformMatrix();
this._tempMatrix2 = new TransformMatrix();
this._tempMatrix3 = new TransformMatrix();
this.calcMatrix = new TransformMatrix();
this.tempTriangle = [
{ x: 0, y: 0, width: 0 },
{ x: 0, y: 0, width: 0 },
{ x: 0, y: 0, width: 0 },
{ x: 0, y: 0, width: 0 }
];
this.strokeTint = { TL: 0, TR: 0, BL: 0, BR: 0 };
this.fillTint = { TL: 0, TR: 0, BL: 0, BR: 0 };
this.currentFrame = { u0: 0, v0: 0, u1: 1, v1: 1 };
this.firstQuad = [0, 0, 0, 0, 0];
this.prevQuad = [0, 0, 0, 0, 0];
this.polygonCache = [];
},
/**
* Called every time the pipeline is bound by the renderer.
* Sets the shader program, vertex buffer and other resources.
* Should only be called when changing pipeline.
*
* @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#boot
* @since 3.50.0
*/
boot: function() {
WebGLPipeline.prototype.boot.call(this);
var renderer = this.renderer;
this.set1iv("uMainSampler", renderer.textureIndexes);
this.set2f("uResolution", renderer.width, renderer.height);
},
/**
* Takes a Sprite Game Object, or any object that extends it, and adds it to the batch.
*
* @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchSprite
* @since 3.0.0
*
* @param {(Phaser.GameObjects.Image|Phaser.GameObjects.Sprite)} gameObject - The texture based Game Object to add to the batch.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to use for the rendering transform.
* @param {Phaser.GameObjects.Components.TransformMatrix} [parentTransformMatrix] - The transform matrix of the parent container, if set.
*/
batchSprite: function(gameObject, camera, parentTransformMatrix) {
this.manager.set(this, gameObject);
var camMatrix = this._tempMatrix1;
var spriteMatrix = this._tempMatrix2;
var calcMatrix = this._tempMatrix3;
var frame = gameObject.frame;
var texture = frame.glTexture;
var u0 = frame.u0;
var v0 = frame.v0;
var u1 = frame.u1;
var v1 = frame.v1;
var frameX = frame.x;
var frameY = frame.y;
var frameWidth = frame.cutWidth;
var frameHeight = frame.cutHeight;
var customPivot = frame.customPivot;
var displayOriginX = gameObject.displayOriginX;
var displayOriginY = gameObject.displayOriginY;
var x = -displayOriginX + frameX;
var y = -displayOriginY + frameY;
if (gameObject.isCropped) {
var crop = gameObject._crop;
if (crop.flipX !== gameObject.flipX || crop.flipY !== gameObject.flipY) {
frame.updateCropUVs(crop, gameObject.flipX, gameObject.flipY);
}
u0 = crop.u0;
v0 = crop.v0;
u1 = crop.u1;
v1 = crop.v1;
frameWidth = crop.width;
frameHeight = crop.height;
frameX = crop.x;
frameY = crop.y;
x = -displayOriginX + frameX;
y = -displayOriginY + frameY;
}
var flipX = 1;
var flipY = 1;
if (gameObject.flipX) {
if (!customPivot) {
x += -frame.realWidth + displayOriginX * 2;
}
flipX = -1;
}
if (gameObject.flipY) {
if (!customPivot) {
y += -frame.realHeight + displayOriginY * 2;
}
flipY = -1;
}
var gx = gameObject.x;
var gy = gameObject.y;
if (camera.roundPixels) {
gx = Math.floor(gx);
gy = Math.floor(gy);
}
spriteMatrix.applyITRS(gx, gy, gameObject.rotation, gameObject.scaleX * flipX, gameObject.scaleY * flipY);
camMatrix.copyFrom(camera.matrix);
if (parentTransformMatrix) {
camMatrix.multiplyWithOffset(parentTransformMatrix, -camera.scrollX * gameObject.scrollFactorX, -camera.scrollY * gameObject.scrollFactorY);
spriteMatrix.e = gx;
spriteMatrix.f = gy;
} else {
spriteMatrix.e -= camera.scrollX * gameObject.scrollFactorX;
spriteMatrix.f -= camera.scrollY * gameObject.scrollFactorY;
}
camMatrix.multiply(spriteMatrix, calcMatrix);
var quad = calcMatrix.setQuad(x, y, x + frameWidth, y + frameHeight, camera.renderRoundPixels);
var getTint = Utils.getTintAppendFloatAlpha;
var cameraAlpha = camera.alpha;
var tintTL = getTint(gameObject.tintTopLeft, cameraAlpha * gameObject._alphaTL);
var tintTR = getTint(gameObject.tintTopRight, cameraAlpha * gameObject._alphaTR);
var tintBL = getTint(gameObject.tintBottomLeft, cameraAlpha * gameObject._alphaBL);
var tintBR = getTint(gameObject.tintBottomRight, cameraAlpha * gameObject._alphaBR);
if (this.shouldFlush(6)) {
this.flush();
}
var unit = this.setGameObject(gameObject, frame);
this.manager.preBatch(gameObject);
this.batchQuad(gameObject, quad[0], quad[1], quad[2], quad[3], quad[4], quad[5], quad[6], quad[7], u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, gameObject.tintFill, texture, unit);
this.manager.postBatch(gameObject);
},
/**
* Generic function for batching a textured quad using argument values instead of a Game Object.
*
* @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchTexture
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - Source GameObject.
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} texture - Texture associated with the quad.
* @param {number} textureWidth - Real texture width.
* @param {number} textureHeight - Real texture height.
* @param {number} srcX - X coordinate of the quad.
* @param {number} srcY - Y coordinate of the quad.
* @param {number} srcWidth - Width of the quad.
* @param {number} srcHeight - Height of the quad.
* @param {number} scaleX - X component of scale.
* @param {number} scaleY - Y component of scale.
* @param {number} rotation - Rotation of the quad.
* @param {boolean} flipX - Indicates if the quad is horizontally flipped.
* @param {boolean} flipY - Indicates if the quad is vertically flipped.
* @param {number} scrollFactorX - By which factor is the quad affected by the camera horizontal scroll.
* @param {number} scrollFactorY - By which factor is the quad effected by the camera vertical scroll.
* @param {number} displayOriginX - Horizontal origin in pixels.
* @param {number} displayOriginY - Vertical origin in pixels.
* @param {number} frameX - X coordinate of the texture frame.
* @param {number} frameY - Y coordinate of the texture frame.
* @param {number} frameWidth - Width of the texture frame.
* @param {number} frameHeight - Height of the texture frame.
* @param {number} tintTL - Tint for top left.
* @param {number} tintTR - Tint for top right.
* @param {number} tintBL - Tint for bottom left.
* @param {number} tintBR - Tint for bottom right.
* @param {number} tintEffect - The tint effect.
* @param {number} uOffset - Horizontal offset on texture coordinate.
* @param {number} vOffset - Vertical offset on texture coordinate.
* @param {Phaser.Cameras.Scene2D.Camera} camera - Current used camera.
* @param {Phaser.GameObjects.Components.TransformMatrix} parentTransformMatrix - Parent container.
* @param {boolean} [skipFlip=false] - Skip the renderTexture check.
* @param {number} [textureUnit] - The texture unit to set (defaults to currently bound if undefined or null)
* @param {boolean} [skipPrePost=false] - Skip the pre and post manager calls?
*/
batchTexture: function(gameObject, texture, textureWidth, textureHeight, srcX, srcY, srcWidth, srcHeight, scaleX, scaleY, rotation, flipX, flipY, scrollFactorX, scrollFactorY, displayOriginX, displayOriginY, frameX, frameY, frameWidth, frameHeight, tintTL, tintTR, tintBL, tintBR, tintEffect, uOffset, vOffset, camera, parentTransformMatrix, skipFlip, textureUnit, skipPrePost) {
if (skipPrePost === void 0) {
skipPrePost = false;
}
this.manager.set(this, gameObject);
var camMatrix = this._tempMatrix1;
var spriteMatrix = this._tempMatrix2;
var calcMatrix = this._tempMatrix3;
var u0 = frameX / textureWidth + uOffset;
var v0 = frameY / textureHeight + vOffset;
var u1 = (frameX + frameWidth) / textureWidth + uOffset;
var v1 = (frameY + frameHeight) / textureHeight + vOffset;
var width = srcWidth;
var height = srcHeight;
var x = -displayOriginX;
var y = -displayOriginY;
if (gameObject.isCropped) {
var crop = gameObject._crop;
var cropWidth = crop.width;
var cropHeight = crop.height;
width = cropWidth;
height = cropHeight;
srcWidth = cropWidth;
srcHeight = cropHeight;
frameX = crop.x;
frameY = crop.y;
var ox = frameX;
var oy = frameY;
if (flipX) {
ox = frameWidth - crop.x - cropWidth;
}
if (flipY) {
oy = frameHeight - crop.y - cropHeight;
}
u0 = ox / textureWidth + uOffset;
v0 = oy / textureHeight + vOffset;
u1 = (ox + cropWidth) / textureWidth + uOffset;
v1 = (oy + cropHeight) / textureHeight + vOffset;
x = -displayOriginX + frameX;
y = -displayOriginY + frameY;
}
flipY = flipY ^ (!skipFlip && texture.isRenderTexture ? 1 : 0);
if (flipX) {
width *= -1;
x += srcWidth;
}
if (flipY) {
height *= -1;
y += srcHeight;
}
if (camera.roundPixels) {
srcX = Math.floor(srcX);
srcY = Math.floor(srcY);
}
spriteMatrix.applyITRS(srcX, srcY, rotation, scaleX, scaleY);
camMatrix.copyFrom(camera.matrix);
if (parentTransformMatrix) {
camMatrix.multiplyWithOffset(parentTransformMatrix, -camera.scrollX * scrollFactorX, -camera.scrollY * scrollFactorY);
spriteMatrix.e = srcX;
spriteMatrix.f = srcY;
} else {
spriteMatrix.e -= camera.scrollX * scrollFactorX;
spriteMatrix.f -= camera.scrollY * scrollFactorY;
}
camMatrix.multiply(spriteMatrix, calcMatrix);
var quad = calcMatrix.setQuad(x, y, x + width, y + height, camera.renderRoundPixels);
if (textureUnit === void 0 || textureUnit === null) {
textureUnit = this.setTexture2D(texture);
}
if (gameObject && !skipPrePost) {
this.manager.preBatch(gameObject);
}
this.batchQuad(gameObject, quad[0], quad[1], quad[2], quad[3], quad[4], quad[5], quad[6], quad[7], u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, tintEffect, texture, textureUnit);
if (gameObject && !skipPrePost) {
this.manager.postBatch(gameObject);
}
},
/**
* Adds a Texture Frame into the batch for rendering.
*
* @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchTextureFrame
* @since 3.12.0
*
* @param {Phaser.Textures.Frame} frame - The Texture Frame to be rendered.
* @param {number} x - The horizontal position to render the texture at.
* @param {number} y - The vertical position to render the texture at.
* @param {number} tint - The tint color.
* @param {number} alpha - The alpha value.
* @param {Phaser.GameObjects.Components.TransformMatrix} transformMatrix - The Transform Matrix to use for the texture.
* @param {Phaser.GameObjects.Components.TransformMatrix} [parentTransformMatrix] - A parent Transform Matrix.
*/
batchTextureFrame: function(frame, x, y, tint, alpha, transformMatrix, parentTransformMatrix) {
this.manager.set(this);
var spriteMatrix = this._tempMatrix1.copyFrom(transformMatrix);
var calcMatrix = this._tempMatrix2;
if (parentTransformMatrix) {
spriteMatrix.multiply(parentTransformMatrix, calcMatrix);
} else {
calcMatrix = spriteMatrix;
}
var quad = calcMatrix.setQuad(x, y, x + frame.width, y + frame.height);
var unit = this.setTexture2D(frame.source.glTexture);
tint = Utils.getTintAppendFloatAlpha(tint, alpha);
this.batchQuad(null, quad[0], quad[1], quad[2], quad[3], quad[4], quad[5], quad[6], quad[7], frame.u0, frame.v0, frame.u1, frame.v1, tint, tint, tint, tint, 0, frame.glTexture, unit);
},
/**
* Pushes a filled rectangle into the vertex batch.
*
* Rectangle factors in the given transform matrices before adding to the batch.
*
* @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchFillRect
* @since 3.55.0
*
* @param {number} x - Horizontal top left coordinate of the rectangle.
* @param {number} y - Vertical top left coordinate of the rectangle.
* @param {number} width - Width of the rectangle.
* @param {number} height - Height of the rectangle.
* @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform.
* @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - The parent transform.
*/
batchFillRect: function(x, y, width, height, currentMatrix, parentMatrix) {
this.renderer.pipelines.set(this);
var calcMatrix = this.calcMatrix;
if (parentMatrix) {
parentMatrix.multiply(currentMatrix, calcMatrix);
}
var quad = calcMatrix.setQuad(x, y, x + width, y + height);
var tint = this.fillTint;
this.batchQuad(null, quad[0], quad[1], quad[2], quad[3], quad[4], quad[5], quad[6], quad[7], 0, 0, 1, 1, tint.TL, tint.TR, tint.BL, tint.BR, 2);
},
/**
* Pushes a filled triangle into the vertex batch.
*
* Triangle factors in the given transform matrices before adding to the batch.
*
* @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchFillTriangle
* @since 3.55.0
*
* @param {number} x0 - Point 0 x coordinate.
* @param {number} y0 - Point 0 y coordinate.
* @param {number} x1 - Point 1 x coordinate.
* @param {number} y1 - Point 1 y coordinate.
* @param {number} x2 - Point 2 x coordinate.
* @param {number} y2 - Point 2 y coordinate.
* @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform.
* @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - The parent transform.
*/
batchFillTriangle: function(x0, y0, x1, y1, x2, y2, currentMatrix, parentMatrix) {
this.renderer.pipelines.set(this);
var calcMatrix = this.calcMatrix;
if (parentMatrix) {
parentMatrix.multiply(currentMatrix, calcMatrix);
}
var tx0 = calcMatrix.getX(x0, y0);
var ty0 = calcMatrix.getY(x0, y0);
var tx1 = calcMatrix.getX(x1, y1);
var ty1 = calcMatrix.getY(x1, y1);
var tx2 = calcMatrix.getX(x2, y2);
var ty2 = calcMatrix.getY(x2, y2);
var tint = this.fillTint;
this.batchTri(null, tx0, ty0, tx1, ty1, tx2, ty2, 0, 0, 1, 1, tint.TL, tint.TR, tint.BL, 2);
},
/**
* Pushes a stroked triangle into the vertex batch.
*
* Triangle factors in the given transform matrices before adding to the batch.
*
* The triangle is created from 3 lines and drawn using the `batchStrokePath` method.
*
* @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchStrokeTriangle
* @since 3.55.0
*
* @param {number} x0 - Point 0 x coordinate.
* @param {number} y0 - Point 0 y coordinate.
* @param {number} x1 - Point 1 x coordinate.
* @param {number} y1 - Point 1 y coordinate.
* @param {number} x2 - Point 2 x coordinate.
* @param {number} y2 - Point 2 y coordinate.
* @param {number} lineWidth - The width of the line in pixels.
* @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform.
* @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - The parent transform.
*/
batchStrokeTriangle: function(x0, y0, x1, y1, x2, y2, lineWidth, currentMatrix, parentMatrix) {
var tempTriangle = this.tempTriangle;
tempTriangle[0].x = x0;
tempTriangle[0].y = y0;
tempTriangle[0].width = lineWidth;
tempTriangle[1].x = x1;
tempTriangle[1].y = y1;
tempTriangle[1].width = lineWidth;
tempTriangle[2].x = x2;
tempTriangle[2].y = y2;
tempTriangle[2].width = lineWidth;
tempTriangle[3].x = x0;
tempTriangle[3].y = y0;
tempTriangle[3].width = lineWidth;
this.batchStrokePath(tempTriangle, lineWidth, false, currentMatrix, parentMatrix);
},
/**
* Adds the given path to the vertex batch for rendering.
*
* It works by taking the array of path data and then passing it through Earcut, which
* creates a list of polygons. Each polygon is then added to the batch.
*
* The path is always automatically closed because it's filled.
*
* @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchFillPath
* @since 3.55.0
*
* @param {Phaser.Types.Math.Vector2Like[]} path - Collection of points that represent the path.
* @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform.
* @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - The parent transform.
*/
batchFillPath: function(path, currentMatrix, parentMatrix) {
this.renderer.pipelines.set(this);
var calcMatrix = this.calcMatrix;
if (parentMatrix) {
parentMatrix.multiply(currentMatrix, calcMatrix);
}
var length = path.length;
var polygonCache = this.polygonCache;
var polygonIndexArray;
var point;
var tintTL = this.fillTint.TL;
var tintTR = this.fillTint.TR;
var tintBL = this.fillTint.BL;
for (var pathIndex = 0; pathIndex < length; ++pathIndex) {
point = path[pathIndex];
polygonCache.push(point.x, point.y);
}
polygonIndexArray = Earcut(polygonCache);
length = polygonIndexArray.length;
for (var index = 0; index < length; index += 3) {
var p0 = polygonIndexArray[index + 0] * 2;
var p1 = polygonIndexArray[index + 1] * 2;
var p2 = polygonIndexArray[index + 2] * 2;
var x0 = polygonCache[p0 + 0];
var y0 = polygonCache[p0 + 1];
var x1 = polygonCache[p1 + 0];
var y1 = polygonCache[p1 + 1];
var x2 = polygonCache[p2 + 0];
var y2 = polygonCache[p2 + 1];
var tx0 = calcMatrix.getX(x0, y0);
var ty0 = calcMatrix.getY(x0, y0);
var tx1 = calcMatrix.getX(x1, y1);
var ty1 = calcMatrix.getY(x1, y1);
var tx2 = calcMatrix.getX(x2, y2);
var ty2 = calcMatrix.getY(x2, y2);
this.batchTri(null, tx0, ty0, tx1, ty1, tx2, ty2, 0, 0, 1, 1, tintTL, tintTR, tintBL, 2);
}
polygonCache.length = 0;
},
/**
* Adds the given path to the vertex batch for rendering.
*
* It works by taking the array of path data and calling `batchLine` for each section
* of the path.
*
* The path is optionally closed at the end.
*
* @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchStrokePath
* @since 3.55.0
*
* @param {Phaser.Types.Math.Vector2Like[]} path - Collection of points that represent the path.
* @param {number} lineWidth - The width of the line segments in pixels.
* @param {boolean} pathOpen - Indicates if the path should be closed or left open.
* @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform.
* @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - The parent transform.
*/
batchStrokePath: function(path, lineWidth, pathOpen, currentMatrix, parentMatrix) {
this.renderer.pipelines.set(this);
this.prevQuad[4] = 0;
this.firstQuad[4] = 0;
var pathLength = path.length - 1;
for (var pathIndex = 0; pathIndex < pathLength; pathIndex++) {
var point0 = path[pathIndex];
var point1 = path[pathIndex + 1];
this.batchLine(
point0.x,
point0.y,
point1.x,
point1.y,
point0.width / 2,
point1.width / 2,
lineWidth,
pathIndex,
!pathOpen && pathIndex === pathLength - 1,
currentMatrix,
parentMatrix
);
}
},
/**
* Creates a line out of 4 quads and adds it to the vertex batch based on the given line values.
*
* @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#batchLine
* @since 3.55.0
*
* @param {number} ax - x coordinate of the start of the line.
* @param {number} ay - y coordinate of the start of the line.
* @param {number} bx - x coordinate of the end of the line.
* @param {number} by - y coordinate of the end of the line.
* @param {number} aLineWidth - Width of the start of the line.
* @param {number} bLineWidth - Width of the end of the line.
* @param {number} index - If this line is part of a multi-line draw, the index of the line in the draw.
* @param {boolean} closePath - Does this line close a multi-line path?
* @param {Phaser.GameObjects.Components.TransformMatrix} currentMatrix - The current transform.
* @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - The parent transform.
*/
batchLine: function(ax, ay, bx, by, aLineWidth, bLineWidth, lineWidth, index, closePath, currentMatrix, parentMatrix) {
this.renderer.pipelines.set(this);
var calcMatrix = this.calcMatrix;
if (parentMatrix) {
parentMatrix.multiply(currentMatrix, calcMatrix);
}
var dx = bx - ax;
var dy = by - ay;
var len = Math.sqrt(dx * dx + dy * dy);
if (len === 0) {
return;
}
var al0 = aLineWidth * (by - ay) / len;
var al1 = aLineWidth * (ax - bx) / len;
var bl0 = bLineWidth * (by - ay) / len;
var bl1 = bLineWidth * (ax - bx) / len;
var lx0 = bx - bl0;
var ly0 = by - bl1;
var lx1 = ax - al0;
var ly1 = ay - al1;
var lx2 = bx + bl0;
var ly2 = by + bl1;
var lx3 = ax + al0;
var ly3 = ay + al1;
var brX = calcMatrix.getX(lx0, ly0);
var brY = calcMatrix.getY(lx0, ly0);
var blX = calcMatrix.getX(lx1, ly1);
var blY = calcMatrix.getY(lx1, ly1);
var trX = calcMatrix.getX(lx2, ly2);
var trY = calcMatrix.getY(lx2, ly2);
var tlX = calcMatrix.getX(lx3, ly3);
var tlY = calcMatrix.getY(lx3, ly3);
var tint = this.strokeTint;
var tintTL = tint.TL;
var tintTR = tint.TR;
var tintBL = tint.BL;
var tintBR = tint.BR;
this.batchQuad(null, tlX, tlY, blX, blY, brX, brY, trX, trY, 0, 0, 1, 1, tintTL, tintTR, tintBL, tintBR, 2);
if (lineWidth <= 2) {
return;
}
var prev = this.prevQuad;
var first = this.firstQuad;
if (index > 0 && prev[4]) {
this.batchQuad(null, tlX, tlY, blX, blY, prev[0], prev[1], prev[2], prev[3], 0, 0, 1, 1, tintTL, tintTR, tintBL, tintBR, 2);
} else {
first[0] = tlX;
first[1] = tlY;
first[2] = blX;
first[3] = blY;
first[4] = 1;
}
if (closePath && first[4]) {
this.batchQuad(null, brX, brY, trX, trY, first[0], first[1], first[2], first[3], 0, 0, 1, 1, tintTL, tintTR, tintBL, tintBR, 2);
} else {
prev[0] = brX;
prev[1] = brY;
prev[2] = trX;
prev[3] = trY;
prev[4] = 1;
}
},
/**
* Destroys all shader instances, removes all object references and nulls all external references.
*
* @method Phaser.Renderer.WebGL.Pipelines.MultiPipeline#destroy
* @fires Phaser.Renderer.WebGL.Pipelines.Events#DESTROY
* @since 3.60.0
*
* @return {this} This WebGLPipeline instance.
*/
destroy: function() {
this._tempMatrix1.destroy();
this._tempMatrix2.destroy();
this._tempMatrix3.destroy();
this._tempMatrix1 = null;
this._tempMatrix1 = null;
this._tempMatrix1 = null;
WebGLPipeline.prototype.destroy.call(this);
return this;
}
});
module2.exports = MultiPipeline;
}
),
/***/
43439: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var GetFastValue = __webpack_require__2(95540);
var PointLightShaderSourceFS = __webpack_require__2(4127);
var PointLightShaderSourceVS = __webpack_require__2(89924);
var WebGLPipeline = __webpack_require__2(29100);
var PointLightPipeline = new Class({
Extends: WebGLPipeline,
initialize: function PointLightPipeline2(config) {
config.vertShader = GetFastValue(config, "vertShader", PointLightShaderSourceVS);
config.fragShader = GetFastValue(config, "fragShader", PointLightShaderSourceFS);
config.attributes = GetFastValue(config, "attributes", [
{
name: "inPosition",
size: 2
},
{
name: "inLightPosition",
size: 2
},
{
name: "inLightRadius"
},
{
name: "inLightAttenuation"
},
{
name: "inLightColor",
size: 4
}
]);
WebGLPipeline.call(this, config);
},
onRender: function(scene, camera) {
this.set2f("uResolution", this.width, this.height);
this.set1f("uCameraZoom", camera.zoom);
},
/**
* Adds a Point Light Game Object to the batch, flushing if required.
*
* @method Phaser.Renderer.WebGL.Pipelines.PointLightPipeline#batchPointLight
* @since 3.50.0
*
* @param {Phaser.GameObjects.PointLight} light - The Point Light Game Object.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The camera rendering the Point Light.
* @param {number} x0 - The top-left x position.
* @param {number} y0 - The top-left y position.
* @param {number} x1 - The bottom-left x position.
* @param {number} y1 - The bottom-left y position.
* @param {number} x2 - The bottom-right x position.
* @param {number} y2 - The bottom-right y position.
* @param {number} x3 - The top-right x position.
* @param {number} y3 - The top-right y position.
* @param {number} lightX - The horizontal center of the light.
* @param {number} lightY - The vertical center of the light.
*/
batchPointLight: function(light, camera, x0, y0, x1, y1, x2, y2, x3, y3, lightX, lightY) {
var color = light.color;
var intensity = light.intensity;
var radius = light.radius;
var attenuation = light.attenuation;
var r = color.r * intensity;
var g = color.g * intensity;
var b = color.b * intensity;
var a = camera.alpha * light.alpha;
if (this.shouldFlush(6)) {
this.flush();
}
if (!this.currentBatch) {
this.setTexture2D();
}
this.batchLightVert(x0, y0, lightX, lightY, radius, attenuation, r, g, b, a);
this.batchLightVert(x1, y1, lightX, lightY, radius, attenuation, r, g, b, a);
this.batchLightVert(x2, y2, lightX, lightY, radius, attenuation, r, g, b, a);
this.batchLightVert(x0, y0, lightX, lightY, radius, attenuation, r, g, b, a);
this.batchLightVert(x2, y2, lightX, lightY, radius, attenuation, r, g, b, a);
this.batchLightVert(x3, y3, lightX, lightY, radius, attenuation, r, g, b, a);
this.currentBatch.count = this.vertexCount - this.currentBatch.start;
},
/**
* Adds a single Point Light vertex to the current vertex buffer and increments the
* `vertexCount` property by 1.
*
* This method is called directly by `batchPointLight`.
*
* @method Phaser.Renderer.WebGL.Pipelines.PointLightPipeline#batchLightVert
* @since 3.50.0
*
* @param {number} x - The vertex x position.
* @param {number} y - The vertex y position.
* @param {number} lightX - The horizontal center of the light.
* @param {number} lightY - The vertical center of the light.
* @param {number} radius - The radius of the light.
* @param {number} attenuation - The attenuation of the light.
* @param {number} r - The red color channel of the light.
* @param {number} g - The green color channel of the light.
* @param {number} b - The blue color channel of the light.
* @param {number} a - The alpha color channel of the light.
*/
batchLightVert: function(x, y, lightX, lightY, radius, attenuation, r, g, b, a) {
var vertexViewF32 = this.vertexViewF32;
var vertexOffset = this.vertexCount * this.currentShader.vertexComponentCount - 1;
vertexViewF32[++vertexOffset] = x;
vertexViewF32[++vertexOffset] = y;
vertexViewF32[++vertexOffset] = lightX;
vertexViewF32[++vertexOffset] = lightY;
vertexViewF32[++vertexOffset] = radius;
vertexViewF32[++vertexOffset] = attenuation;
vertexViewF32[++vertexOffset] = r;
vertexViewF32[++vertexOffset] = g;
vertexViewF32[++vertexOffset] = b;
vertexViewF32[++vertexOffset] = a;
this.vertexCount++;
}
});
module2.exports = PointLightPipeline;
}
),
/***/
84057: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var ColorMatrix = __webpack_require__2(89422);
var GetFastValue = __webpack_require__2(95540);
var ShaderSourceFS = __webpack_require__2(27681);
var ShaderSourceVS = __webpack_require__2(49627);
var WebGLPipeline = __webpack_require__2(29100);
var PostFXPipeline = new Class({
Extends: WebGLPipeline,
initialize: function PostFXPipeline2(config) {
config.renderTarget = GetFastValue(config, "renderTarget", 1);
config.fragShader = GetFastValue(config, "fragShader", ShaderSourceFS);
config.vertShader = GetFastValue(config, "vertShader", ShaderSourceVS);
config.attributes = GetFastValue(config, "attributes", [
{
name: "inPosition",
size: 2
},
{
name: "inTexCoord",
size: 2
}
]);
config.batchSize = 1;
config.vertices = [
-1,
-1,
0,
0,
-1,
1,
0,
1,
1,
1,
1,
1,
-1,
-1,
0,
0,
1,
1,
1,
1,
1,
-1,
1,
0
];
WebGLPipeline.call(this, config);
this.isPostFX = true;
this.gameObject;
this.controller;
this.colorMatrix = new ColorMatrix();
this.fullFrame1;
this.fullFrame2;
this.halfFrame1;
this.halfFrame2;
if (this.renderer.isBooted) {
this.manager = this.renderer.pipelines;
}
},
/**
* This method is called once, when this Post FX Pipeline needs to be used.
*
* Normally, pipelines will boot automatically, ready for instant-use, but Post FX
* Pipelines create quite a lot of internal resources, such as Render Targets, so
* they don't boot until they are told to do so by the Pipeline Manager, when an
* actual Game Object needs to use them.
*
* @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#bootFX
* @since 3.70.0
*/
bootFX: function() {
WebGLPipeline.prototype.boot.call(this);
var utility = this.manager.UTILITY_PIPELINE;
this.fullFrame1 = utility.fullFrame1;
this.fullFrame2 = utility.fullFrame2;
this.halfFrame1 = utility.halfFrame1;
this.halfFrame2 = utility.halfFrame2;
var renderer = this.renderer;
this.set1i("uMainSampler", 0);
this.set2f("uResolution", renderer.width, renderer.height);
var targets = this.renderTargets;
for (var i = 0; i < targets.length; i++) {
targets[i].autoResize = true;
}
},
/**
* This method is called as a result of the `WebGLPipeline.batchQuad` method, right after a quad
* belonging to a Game Object has been added to the batch. When this is called, the
* renderer has just performed a flush.
*
* It calls the `onDraw` hook followed by the `onPostBatch` hook, which can be used to perform
* additional Post FX Pipeline processing.
*
* It is also called as part of the `PipelineManager.postBatch` method when processing Post FX Pipelines.
*
* @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#postBatch
* @since 3.70.0
*
* @param {(Phaser.GameObjects.GameObject|Phaser.Cameras.Scene2D.Camera)} [gameObject] - The Game Object or Camera that invoked this pipeline, if any.
*
* @return {this} This WebGLPipeline instance.
*/
postBatch: function(gameObject) {
if (!this.hasBooted) {
this.bootFX();
if (this.currentRenderTarget) {
this.currentRenderTarget.bind();
}
}
this.onDraw(this.currentRenderTarget);
this.onPostBatch(gameObject);
return this;
},
onDraw: function(renderTarget) {
this.bindAndDraw(renderTarget);
},
/**
* Returns the FX Controller for this Post FX Pipeline.
*
* This is called internally and not typically required outside.
*
* @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#getController
* @since 3.60.0
*
* @param {Phaser.FX.Controller} [controller] - An FX Controller, or undefined.
*
* @return {Phaser.FX.Controller|Phaser.Renderer.WebGL.Pipelines.PostFXPipeline} The FX Controller responsible, or this Pipeline.
*/
getController: function(controller) {
if (controller !== void 0) {
return controller;
} else if (this.controller) {
return this.controller;
} else {
return this;
}
},
/**
* Copy the `source` Render Target to the `target` Render Target.
*
* This method does _not_ bind a shader. It uses whatever shader
* is currently bound in this pipeline. It also does _not_ clear
* the frame buffers after use. You should take care of both of
* these things if you call this method directly.
*
* @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#copySprite
* @since 3.60.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} target - The target Render Target.
*/
copySprite: function(source, target, reset) {
if (reset === void 0) {
reset = false;
}
var gl = this.gl;
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, source.texture.webGLTexture);
var currentFBO = gl.getParameter(gl.FRAMEBUFFER_BINDING);
gl.bindFramebuffer(gl.FRAMEBUFFER, target.framebuffer.webGLFramebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, target.texture.webGLTexture, 0);
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.STATIC_DRAW);
gl.drawArrays(gl.TRIANGLES, 0, 6);
if (reset) {
gl.bindTexture(gl.TEXTURE_2D, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, currentFBO);
}
},
/**
* Copy the `source` Render Target to the `target` Render Target.
*
* You can optionally set the brightness factor of the copy.
*
* The difference between this method and `drawFrame` is that this method
* uses a faster copy shader, where only the brightness can be modified.
* If you need color level manipulation, see `drawFrame` instead.
*
* @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#copyFrame
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target.
* @param {number} [brightness=1] - The brightness value applied to the frame copy.
* @param {boolean} [clear=true] - Clear the target before copying?
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
*/
copyFrame: function(source, target, brightness, clear, clearAlpha) {
this.manager.copyFrame(source, target, brightness, clear, clearAlpha);
},
/**
* Pops the framebuffer from the renderers FBO stack and sets that as the active target,
* then draws the `source` Render Target to it. It then resets the renderer textures.
*
* This should be done when you need to draw the _final_ results of a pipeline to the game
* canvas, or the next framebuffer in line on the FBO stack. You should only call this once
* in the `onDraw` handler and it should be the final thing called. Be careful not to call
* this if you need to actually use the pipeline shader, instead of the copy shader. In
* those cases, use the `bindAndDraw` method.
*
* @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#copyToGame
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The Render Target to draw from.
*/
copyToGame: function(source) {
this.manager.copyToGame(source);
},
/**
* Copy the `source` Render Target to the `target` Render Target, using this pipelines
* Color Matrix.
*
* The difference between this method and `copyFrame` is that this method
* uses a color matrix shader, where you have full control over the luminance
* values used during the copy. If you don't need this, you can use the faster
* `copyFrame` method instead.
*
* @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#drawFrame
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target.
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
*/
drawFrame: function(source, target, clearAlpha) {
this.manager.drawFrame(source, target, clearAlpha, this.colorMatrix);
},
/**
* Draws the `source1` and `source2` Render Targets to the `target` Render Target
* using a linear blend effect, which is controlled by the `strength` parameter.
*
* @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#blendFrames
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source1 - The first source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} source2 - The second source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target.
* @param {number} [strength=1] - The strength of the blend.
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
*/
blendFrames: function(source1, source2, target, strength, clearAlpha) {
this.manager.blendFrames(source1, source2, target, strength, clearAlpha);
},
/**
* Draws the `source1` and `source2` Render Targets to the `target` Render Target
* using an additive blend effect, which is controlled by the `strength` parameter.
*
* @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#blendFramesAdditive
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source1 - The first source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} source2 - The second source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target.
* @param {number} [strength=1] - The strength of the blend.
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
*/
blendFramesAdditive: function(source1, source2, target, strength, clearAlpha) {
this.manager.blendFramesAdditive(source1, source2, target, strength, clearAlpha);
},
/**
* Clears the given Render Target.
*
* @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#clearFrame
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} target - The Render Target to clear.
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
*/
clearFrame: function(target, clearAlpha) {
this.manager.clearFrame(target, clearAlpha);
},
/**
* Copy the `source` Render Target to the `target` Render Target.
*
* The difference with this copy is that no resizing takes place. If the `source`
* Render Target is larger than the `target` then only a portion the same size as
* the `target` dimensions is copied across.
*
* You can optionally set the brightness factor of the copy.
*
* @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#blitFrame
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} target - The target Render Target.
* @param {number} [brightness=1] - The brightness value applied to the frame copy.
* @param {boolean} [clear=true] - Clear the target before copying?
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
* @param {boolean} [eraseMode=false] - Erase source from target using ERASE Blend Mode?
*/
blitFrame: function(source, target, brightness, clear, clearAlpha, eraseMode) {
this.manager.blitFrame(source, target, brightness, clear, clearAlpha, eraseMode);
},
/**
* Binds the `source` Render Target and then copies a section of it to the `target` Render Target.
*
* This method is extremely fast because it uses `gl.copyTexSubImage2D` and doesn't
* require the use of any shaders. Remember the coordinates are given in standard WebGL format,
* where x and y specify the lower-left corner of the section, not the top-left. Also, the
* copy entirely replaces the contents of the target texture, no 'merging' or 'blending' takes
* place.
*
* @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#copyFrameRect
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} target - The target Render Target.
* @param {number} x - The x coordinate of the lower left corner where to start copying.
* @param {number} y - The y coordinate of the lower left corner where to start copying.
* @param {number} width - The width of the texture.
* @param {number} height - The height of the texture.
* @param {boolean} [clear=true] - Clear the target before copying?
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
*/
copyFrameRect: function(source, target, x, y, width, height, clear, clearAlpha) {
this.manager.copyFrameRect(source, target, x, y, width, height, clear, clearAlpha);
},
/**
* Binds this pipeline and draws the `source` Render Target to the `target` Render Target.
*
* If no `target` is specified, it will pop the framebuffer from the Renderers FBO stack
* and use that instead, which should be done when you need to draw the final results of
* this pipeline to the game canvas.
*
* You can optionally set the shader to be used for the draw here, if this is a multi-shader
* pipeline. By default `currentShader` will be used. If you need to set a shader but not
* a target, just pass `null` as the `target` parameter.
*
* @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#bindAndDraw
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The Render Target to draw from.
* @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The Render Target to draw to. If not set, it will pop the fbo from the stack.
* @param {boolean} [clear=true] - Clear the target before copying? Only used if `target` parameter is set.
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
* @param {Phaser.Renderer.WebGL.WebGLShader} [currentShader] - The shader to use during the draw.
*/
bindAndDraw: function(source, target, clear, clearAlpha, currentShader) {
if (clear === void 0) {
clear = true;
}
if (clearAlpha === void 0) {
clearAlpha = true;
}
var gl = this.gl;
var renderer = this.renderer;
this.bind(currentShader);
this.set1i("uMainSampler", 0);
if (target) {
gl.viewport(0, 0, target.width, target.height);
gl.bindFramebuffer(gl.FRAMEBUFFER, target.framebuffer.webGLFramebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, target.texture.webGLTexture, 0);
if (clear) {
if (clearAlpha) {
gl.clearColor(0, 0, 0, 0);
} else {
gl.clearColor(0, 0, 0, 1);
}
gl.clear(gl.COLOR_BUFFER_BIT);
}
} else {
renderer.popFramebuffer(false, false);
if (!renderer.currentFramebuffer) {
gl.viewport(0, 0, renderer.width, renderer.height);
}
}
renderer.restoreStencilMask();
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, source.texture.webGLTexture);
gl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.STATIC_DRAW);
gl.drawArrays(gl.TRIANGLES, 0, 6);
if (target) {
gl.bindTexture(gl.TEXTURE_2D, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, renderer.currentFramebuffer.webGLFramebuffer);
}
},
/**
* Destroys all shader instances, removes all object references and nulls all external references.
*
* @method Phaser.Renderer.WebGL.Pipelines.PostFXPipeline#destroy
* @since 3.60.0
*
* @return {this} This WebGLPipeline instance.
*/
destroy: function() {
if (this.controller) {
this.controller.destroy();
}
this.gameObject = null;
this.controller = null;
this.colorMatrix = null;
this.fullFrame1 = null;
this.fullFrame2 = null;
this.halfFrame1 = null;
this.halfFrame2 = null;
this.manager.removePostPipeline(this);
WebGLPipeline.prototype.destroy.call(this);
return this;
}
});
module2.exports = PostFXPipeline;
}
),
/***/
43558: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BlendModes = __webpack_require__2(10312);
var CenterOn = __webpack_require__2(67502);
var Class = __webpack_require__2(83419);
var ColorMatrixFS = __webpack_require__2(96293);
var GetFastValue = __webpack_require__2(95540);
var MultiPipeline = __webpack_require__2(57516);
var PostFXFS = __webpack_require__2(27681);
var Rectangle = __webpack_require__2(87841);
var RenderTarget = __webpack_require__2(32302);
var SingleQuadFS = __webpack_require__2(45561);
var SingleQuadVS = __webpack_require__2(60722);
var WebGLPipeline = __webpack_require__2(29100);
var PreFXPipeline = new Class({
Extends: MultiPipeline,
initialize: function PreFXPipeline2(config) {
var fragShader = GetFastValue(config, "fragShader", PostFXFS);
var vertShader = GetFastValue(config, "vertShader", SingleQuadVS);
var drawShader = GetFastValue(config, "drawShader", PostFXFS);
var defaultShaders = [
{
name: "DrawSprite",
fragShader: SingleQuadFS,
vertShader: SingleQuadVS
},
{
name: "CopySprite",
fragShader,
vertShader
},
{
name: "DrawGame",
fragShader: drawShader,
vertShader: SingleQuadVS
},
{
name: "ColorMatrix",
fragShader: ColorMatrixFS
}
];
var configShaders = GetFastValue(config, "shaders", []);
config.shaders = defaultShaders.concat(configShaders);
if (!config.vertShader) {
config.vertShader = vertShader;
}
config.batchSize = 1;
MultiPipeline.call(this, config);
this.isPreFX = true;
this.customMainSampler = null;
this.drawSpriteShader;
this.copyShader;
this.gameShader;
this.colorMatrixShader;
this.quadVertexData;
this.quadVertexBuffer;
this.quadVertexViewF32;
this.spriteBounds = new Rectangle();
this.targetBounds = new Rectangle();
this.fsTarget;
this.tempSprite;
if (this.renderer.isBooted) {
this.manager = this.renderer.pipelines;
this.boot();
}
},
boot: function() {
WebGLPipeline.prototype.boot.call(this);
var shaders = this.shaders;
var renderer = this.renderer;
this.drawSpriteShader = shaders[0];
this.copyShader = shaders[1];
this.gameShader = shaders[2];
this.colorMatrixShader = shaders[3];
this.fsTarget = new RenderTarget(renderer, renderer.width, renderer.height, 1, 0, true, true);
this.renderTargets = this.manager.renderTargets.concat(this.fsTarget);
var data = new ArrayBuffer(168);
this.quadVertexData = data;
this.quadVertexViewF32 = new Float32Array(data);
this.quadVertexBuffer = renderer.createVertexBuffer(data, this.gl.STATIC_DRAW);
this.onResize(renderer.width, renderer.height);
this.currentShader = this.copyShader;
this.set2f("uResolution", renderer.width, renderer.height);
},
/**
* Handles the resizing of the quad vertex data.
*
* @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#onResize
* @since 3.60.0
*
* @param {number} width - The new width of the quad.
* @param {number} height - The new height of the quad.
*/
onResize: function(width, height) {
var vertexViewF32 = this.quadVertexViewF32;
vertexViewF32[1] = height;
vertexViewF32[22] = height;
vertexViewF32[14] = width;
vertexViewF32[28] = width;
vertexViewF32[35] = width;
vertexViewF32[36] = height;
},
/**
* Adds the vertices data into the batch and flushes if full.
*
* Assumes 6 vertices in the following arrangement:
*
* ```
* 0----3
* |\ B|
* | \ |
* | \ |
* | A \|
* | \
* 1----2
* ```
*
* Where x0 / y0 = 0, x1 / y1 = 1, x2 / y2 = 2 and x3 / y3 = 3
*
* @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#batchQuad
* @since 3.60.0
*
* @param {(Phaser.GameObjects.GameObject|null)} gameObject - The Game Object, if any, drawing this quad.
* @param {number} x0 - The top-left x position.
* @param {number} y0 - The top-left y position.
* @param {number} x1 - The bottom-left x position.
* @param {number} y1 - The bottom-left y position.
* @param {number} x2 - The bottom-right x position.
* @param {number} y2 - The bottom-right y position.
* @param {number} x3 - The top-right x position.
* @param {number} y3 - The top-right y position.
* @param {number} u0 - UV u0 value.
* @param {number} v0 - UV v0 value.
* @param {number} u1 - UV u1 value.
* @param {number} v1 - UV v1 value.
* @param {number} tintTL - The top-left tint color value.
* @param {number} tintTR - The top-right tint color value.
* @param {number} tintBL - The bottom-left tint color value.
* @param {number} tintBR - The bottom-right tint color value.
* @param {(number|boolean)} tintEffect - The tint effect for the shader to use.
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} [texture] - Texture that will be assigned to the current batch if a flush occurs.
*
* @return {boolean} `true` if this method caused the batch to flush, otherwise `false`.
*/
batchQuad: function(gameObject, x0, y0, x1, y1, x2, y2, x3, y3, u0, v0, u1, v1, tintTL, tintTR, tintBL, tintBR, tintEffect, texture) {
var bx = Math.min(x0, x1, x2, x3);
var by = Math.min(y0, y1, y2, y3);
var br = Math.max(x0, x1, x2, x3);
var bb = Math.max(y0, y1, y2, y3);
var bw = br - bx;
var bh = bb - by;
var bounds = this.spriteBounds.setTo(bx, by, bw, bh);
var padding = gameObject ? gameObject.preFX.padding : 0;
var width = bw + padding * 2;
var height = bh + padding * 2;
var maxDimension = Math.abs(Math.max(width, height));
var target = this.manager.getRenderTarget(maxDimension);
var targetBounds = this.targetBounds.setTo(0, 0, target.width, target.height);
CenterOn(targetBounds, Math.round(bounds.centerX), Math.round(bounds.centerY));
this.tempSprite = gameObject;
var gl = this.gl;
var renderer = this.renderer;
renderer.clearStencilMask();
this.setShader(this.drawSpriteShader);
this.set1i("uMainSampler", 0);
this.set2f("uResolution", renderer.width, renderer.height);
this.flipProjectionMatrix(true);
if (gameObject) {
this.onDrawSprite(gameObject, target);
gameObject.preFX.onFX(this);
}
var fsTarget = this.fsTarget;
this.flush();
gl.viewport(0, 0, renderer.width, renderer.height);
gl.bindFramebuffer(gl.FRAMEBUFFER, fsTarget.framebuffer.webGLFramebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, fsTarget.texture.webGLTexture, 0);
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
this.setTexture2D(texture);
this.batchVert(x0, y0, u0, v0, 0, tintEffect, tintTL);
this.batchVert(x1, y1, u0, v1, 0, tintEffect, tintBL);
this.batchVert(x2, y2, u1, v1, 0, tintEffect, tintBR);
this.batchVert(x0, y0, u0, v0, 0, tintEffect, tintTL);
this.batchVert(x2, y2, u1, v1, 0, tintEffect, tintBR);
this.batchVert(x3, y3, u1, v0, 0, tintEffect, tintTR);
this.flush();
this.flipProjectionMatrix(false);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, target.texture.webGLTexture);
gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, targetBounds.x, targetBounds.y, targetBounds.width, targetBounds.height);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.bindTexture(gl.TEXTURE_2D, null);
this.onBatch(gameObject);
this.currentShader = this.copyShader;
this.onDraw(target, this.manager.getSwapRenderTarget(), this.manager.getAltSwapRenderTarget());
return true;
},
/**
* This callback is invoked when a sprite is drawn by this pipeline.
*
* It will fire after the shader has been set, but before the sprite has been drawn,
* so use it to set any additional uniforms you may need.
*
* Note: Manipulating the Sprite during this callback will _not_ change how it is drawn to the Render Target.
*
* @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#onDrawSprite
* @since 3.60.0
*
* @param {Phaser.GameObjects.Sprite} gameObject - The Sprite being drawn.
* @param {Phaser.Renderer.WebGL.RenderTarget} target - The Render Target the Sprite will be drawn to.
*/
onDrawSprite: function() {
},
/**
* This callback is invoked when you call the `copySprite` method.
*
* It will fire after the shader has been set, but before the source target has been copied,
* so use it to set any additional uniforms you may need.
*
* Note: Manipulating the Sprite during this callback will _not_ change the Render Targets.
*
* @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#onCopySprite
* @since 3.60.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target being copied from.
* @param {Phaser.Renderer.WebGL.RenderTarget} target - The target Render Target that will be copied to.
* @param {Phaser.GameObjects.Sprite} gameObject - The Sprite being copied.
*/
onCopySprite: function() {
},
/**
* Copy the `source` Render Target to the `target` Render Target.
*
* No target resizing takes place. If the `source` Render Target is larger than the `target`,
* then only a portion the same size as the `target` dimensions is copied across.
*
* Calling this method will invoke the `onCopySprite` handler and will also call
* the `onFXCopy` callback on the Sprite. Both of these happen prior to the copy, allowing you
* to use them to set shader uniforms and other values.
*
* You can optionally pass in a ColorMatrix. If so, it will use the ColorMatrix shader
* during the copy, allowing you to manipulate the colors to a fine degree.
* See the `ColorMatrix` class for more details.
*
* @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#copySprite
* @since 3.60.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target being copied from.
* @param {Phaser.Renderer.WebGL.RenderTarget} target - The target Render Target that will be copied to.
* @param {boolean} [clear=true] - Clear the target before copying?
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
* @param {boolean} [eraseMode=false] - Erase source from target using ERASE Blend Mode?
* @param {Phaser.Display.ColorMatrix} [colorMatrix] - Optional ColorMatrix to use when copying the Sprite.
* @param {Phaser.Renderer.WebGL.WebGLShader} [shader] - The shader to use to copy the target. Defaults to the `copyShader`.
*/
copySprite: function(source, target, clear, clearAlpha, eraseMode, colorMatrix, shader) {
if (clear === void 0) {
clear = true;
}
if (clearAlpha === void 0) {
clearAlpha = true;
}
if (eraseMode === void 0) {
eraseMode = false;
}
if (shader === void 0) {
shader = this.copyShader;
}
var gl = this.gl;
var sprite = this.tempSprite;
if (colorMatrix) {
shader = this.colorMatrixShader;
}
this.currentShader = shader;
var wasBound = this.setVertexBuffer(this.quadVertexBuffer);
shader.bind(wasBound, false);
var renderer = this.renderer;
this.set1i("uMainSampler", 0);
this.set2f("uResolution", renderer.width, renderer.height);
sprite.preFX.onFXCopy(this);
this.onCopySprite(source, target, sprite);
if (colorMatrix) {
this.set1fv("uColorMatrix", colorMatrix.getData());
this.set1f("uAlpha", colorMatrix.alpha);
}
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, source.texture.webGLTexture);
if (source.height > target.height) {
gl.viewport(0, 0, source.width, source.height);
this.setTargetUVs(source, target);
} else {
var diff = target.height - source.height;
gl.viewport(0, diff, source.width, source.height);
this.resetUVs();
}
gl.bindFramebuffer(gl.FRAMEBUFFER, target.framebuffer.webGLFramebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, target.texture.webGLTexture, 0);
if (clear) {
gl.clearColor(0, 0, 0, Number(!clearAlpha));
gl.clear(gl.COLOR_BUFFER_BIT);
}
if (eraseMode) {
var blendMode = this.renderer.currentBlendMode;
this.renderer.setBlendMode(BlendModes.ERASE);
}
gl.bufferData(gl.ARRAY_BUFFER, this.quadVertexData, gl.STATIC_DRAW);
gl.drawArrays(gl.TRIANGLES, 0, 6);
if (eraseMode) {
this.renderer.setBlendMode(blendMode);
}
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
},
/**
* Draws the `source` Render Target to the `target` Render Target.
*
* This is done using whatever the currently bound shader is. This method does
* not set a shader. All it does is bind the source texture, set the viewport and UVs
* then bind the target framebuffer, clears it and draws the source to it.
*
* At the end a null framebuffer is bound. No other clearing-up takes place, so
* use this method carefully.
*
* @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#copy
* @since 3.60.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} target - The target Render Target.
*/
copy: function(source, target) {
var gl = this.gl;
this.set1i("uMainSampler", 0);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, source.texture.webGLTexture);
gl.viewport(0, 0, source.width, source.height);
this.setUVs(0, 0, 0, 1, 1, 1, 1, 0);
gl.bindFramebuffer(gl.FRAMEBUFFER, target.framebuffer.webGLFramebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, target.texture.webGLTexture, 0);
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.bufferData(gl.ARRAY_BUFFER, this.quadVertexData, gl.STATIC_DRAW);
gl.drawArrays(gl.TRIANGLES, 0, 6);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
},
/**
* Draws the `source1` and `source2` Render Targets to the `target` Render Target
* using a linear blend effect, which is controlled by the `strength` parameter.
*
* @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#blendFrames
* @since 3.60.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source1 - The first source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} source2 - The second source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target.
* @param {number} [strength=1] - The strength of the blend.
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
*/
blendFrames: function(source1, source2, target, strength, clearAlpha) {
this.manager.blendFrames(source1, source2, target, strength, clearAlpha);
},
/**
* Draws the `source1` and `source2` Render Targets to the `target` Render Target
* using an additive blend effect, which is controlled by the `strength` parameter.
*
* @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#blendFramesAdditive
* @since 3.60.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source1 - The first source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} source2 - The second source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target.
* @param {number} [strength=1] - The strength of the blend.
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
*/
blendFramesAdditive: function(source1, source2, target, strength, clearAlpha) {
this.manager.blendFramesAdditive(source1, source2, target, strength, clearAlpha);
},
/**
* This method will copy the given Render Target to the game canvas using the `copyShader`.
*
* This applies the results of the copy shader during the draw.
*
* If you wish to copy the target without any effects see the `copyToGame` method instead.
*
* This method should be the final thing called in your pipeline.
*
* @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#drawToGame
* @since 3.60.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The Render Target to draw to the game.
*/
drawToGame: function(source) {
this.currentShader = null;
this.setShader(this.copyShader);
this.bindAndDraw(source);
},
/**
* This method will copy the given Render Target to the game canvas using the `gameShader`.
*
* Unless you've changed it, the `gameShader` copies the target without modifying it, just
* ensuring it is placed in the correct location on the canvas.
*
* If you wish to draw the target with and apply the fragment shader at the same time,
* see the `drawToGame` method instead.
*
* This method should be the final thing called in your pipeline.
*
* @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#copyToGame
* @since 3.60.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The Render Target to copy to the game.
*/
copyToGame: function(source) {
this.currentShader = null;
this.setShader(this.gameShader);
this.bindAndDraw(source);
},
/**
* This method is called by `drawToGame` and `copyToGame`. It takes the source Render Target
* and copies it back to the game canvas, or the next frame buffer in the stack, and should
* be considered the very last thing this pipeline does.
*
* You don't normally need to call this method, or override it, however it is left public
* should you wish to do so.
*
* Note that it does _not_ set a shader. You should do this yourself if invoking this.
*
* @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#bindAndDraw
* @since 3.60.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The Render Target to draw to the game.
*/
bindAndDraw: function(source) {
var gl = this.gl;
var renderer = this.renderer;
this.set1i("uMainSampler", 0);
if (this.customMainSampler) {
this.setTexture2D(this.customMainSampler);
} else {
this.setTexture2D(source.texture);
}
var matrix = this._tempMatrix1.loadIdentity();
var x = this.targetBounds.x;
var y = this.targetBounds.y;
var xw = x + source.width;
var yh = y + source.height;
var x0 = matrix.getX(x, y);
var x1 = matrix.getX(x, yh);
var x2 = matrix.getX(xw, yh);
var x3 = matrix.getX(xw, y);
var y0 = matrix.getY(x, y);
var y1 = matrix.getY(x, yh);
var y2 = matrix.getY(xw, yh);
var y3 = matrix.getY(xw, y);
var white = 16777215;
this.batchVert(x0, y0, 0, 0, 0, 0, white);
this.batchVert(x1, y1, 0, 1, 0, 0, white);
this.batchVert(x2, y2, 1, 1, 0, 0, white);
this.batchVert(x0, y0, 0, 0, 0, 0, white);
this.batchVert(x2, y2, 1, 1, 0, 0, white);
this.batchVert(x3, y3, 1, 0, 0, 0, white);
renderer.restoreFramebuffer(false, true);
if (!renderer.currentFramebuffer) {
gl.viewport(0, 0, renderer.width, renderer.height);
}
renderer.restoreStencilMask();
this.flush();
this.tempSprite = null;
},
/**
* This method is called every time the `batchSprite` method is called and is passed a
* reference to the current render target.
*
* If you override this method, then it should make sure it calls either the
* `drawToGame` or `copyToGame` methods as the final thing it does. However, you can do as
* much additional processing as you like prior to this.
*
* @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#onDraw
* @since 3.60.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} target - The Render Target to draw to the game.
* @param {Phaser.Renderer.WebGL.RenderTarget} [swapTarget] - The Swap Render Target, useful for double-buffer effects.
* @param {Phaser.Renderer.WebGL.RenderTarget} [altSwapTarget] - The Swap Render Target, useful for double-buffer effects.
*/
onDraw: function(target) {
this.drawToGame(target);
},
/**
* Set the UV values for the 6 vertices that make up the quad used by the copy shader.
*
* Be sure to call `resetUVs` once you have finished manipulating the UV coordinates.
*
* @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#setUVs
* @since 3.60.0
*
* @param {number} uA - The u value of vertex A.
* @param {number} vA - The v value of vertex A.
* @param {number} uB - The u value of vertex B.
* @param {number} vB - The v value of vertex B.
* @param {number} uC - The u value of vertex C.
* @param {number} vC - The v value of vertex C.
* @param {number} uD - The u value of vertex D.
* @param {number} vD - The v value of vertex D.
*/
setUVs: function(uA, vA, uB, vB, uC, vC, uD, vD) {
var vertexViewF32 = this.quadVertexViewF32;
vertexViewF32[2] = uA;
vertexViewF32[3] = vA;
vertexViewF32[9] = uB;
vertexViewF32[10] = vB;
vertexViewF32[16] = uC;
vertexViewF32[17] = vC;
vertexViewF32[23] = uA;
vertexViewF32[24] = vA;
vertexViewF32[30] = uC;
vertexViewF32[31] = vC;
vertexViewF32[37] = uD;
vertexViewF32[38] = vD;
},
/**
* Sets the vertex UV coordinates of the quad used by the copy shaders
* so that they correctly adjust the texture coordinates for a blit frame effect.
*
* Be sure to call `resetUVs` once you have finished manipulating the UV coordinates.
*
* @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#setTargetUVs
* @since 3.60.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} target - The target Render Target.
*/
setTargetUVs: function(source, target) {
var diff = target.height / source.height;
if (diff > 0.5) {
diff = 0.5 - (diff - 0.5);
} else {
diff = 0.5 + (0.5 - diff);
}
this.setUVs(0, diff, 0, 1 + diff, 1, 1 + diff, 1, diff);
},
/**
* Resets the quad vertice UV values to their default settings.
*
* The quad is used by the copy shader in this pipeline.
*
* @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#resetUVs
* @since 3.60.0
*/
resetUVs: function() {
this.setUVs(0, 0, 0, 1, 1, 1, 1, 0);
},
/**
* Destroys all shader instances, removes all object references and nulls all external references.
*
* @method Phaser.Renderer.WebGL.Pipelines.PreFXPipeline#destroy
* @fires Phaser.Renderer.WebGL.Pipelines.Events#DESTROY
* @since 3.60.0
*
* @return {this} This WebGLPipeline instance.
*/
destroy: function() {
this.renderer.deleteBuffer(this.quadVertexBuffer);
this.drawSpriteShader = null;
this.copyShader = null;
this.gameShader = null;
this.colorMatrixShader = null;
this.quadVertexData = null;
this.quadVertexBuffer = null;
this.quadVertexViewF32 = null;
this.fsTarget = null;
this.tempSprite = null;
MultiPipeline.prototype.destroy.call(this);
return this;
}
});
module2.exports = PreFXPipeline;
}
),
/***/
81041: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var GetFastValue = __webpack_require__2(95540);
var MultiPipeline = __webpack_require__2(57516);
var RopePipeline = new Class({
Extends: MultiPipeline,
initialize: function RopePipeline2(config) {
config.topology = 5;
config.batchSize = GetFastValue(config, "batchSize", 256);
MultiPipeline.call(this, config);
}
});
module2.exports = RopePipeline;
}
),
/***/
12385: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var GetFastValue = __webpack_require__2(95540);
var MultiPipeline = __webpack_require__2(57516);
var ShaderSourceFS = __webpack_require__2(45561);
var ShaderSourceVS = __webpack_require__2(60722);
var WebGLPipeline = __webpack_require__2(29100);
var SinglePipeline = new Class({
Extends: MultiPipeline,
initialize: function SinglePipeline2(config) {
config.fragShader = GetFastValue(config, "fragShader", ShaderSourceFS), config.vertShader = GetFastValue(config, "vertShader", ShaderSourceVS), config.forceZero = true;
MultiPipeline.call(this, config);
},
boot: function() {
WebGLPipeline.prototype.boot.call(this);
var renderer = this.renderer;
this.set1i("uMainSampler", 0);
this.set2f("uResolution", renderer.width, renderer.height);
}
});
module2.exports = SinglePipeline;
}
),
/***/
7589: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var AddBlendFS = __webpack_require__2(35407);
var BlendModes = __webpack_require__2(10312);
var Class = __webpack_require__2(83419);
var ColorMatrix = __webpack_require__2(89422);
var ColorMatrixFS = __webpack_require__2(96293);
var CopyFS = __webpack_require__2(36682);
var GetFastValue = __webpack_require__2(95540);
var LinearBlendFS = __webpack_require__2(48247);
var QuadVS = __webpack_require__2(49627);
var WebGLPipeline = __webpack_require__2(29100);
var UtilityPipeline = new Class({
Extends: WebGLPipeline,
initialize: function UtilityPipeline2(config) {
config.renderTarget = GetFastValue(config, "renderTarget", [
{
scale: 1,
autoResize: true
},
{
scale: 1,
autoResize: true
},
{
scale: 0.5,
autoResize: true
},
{
scale: 0.5,
autoResize: true
}
]);
config.vertShader = GetFastValue(config, "vertShader", QuadVS);
config.shaders = GetFastValue(config, "shaders", [
{
name: "Copy",
fragShader: CopyFS
},
{
name: "AddBlend",
fragShader: AddBlendFS
},
{
name: "LinearBlend",
fragShader: LinearBlendFS
},
{
name: "ColorMatrix",
fragShader: ColorMatrixFS
}
]);
config.attributes = GetFastValue(config, "attributes", [
{
name: "inPosition",
size: 2
},
{
name: "inTexCoord",
size: 2
}
]);
config.vertices = [
-1,
-1,
0,
0,
-1,
1,
0,
1,
1,
1,
1,
1,
-1,
-1,
0,
0,
1,
1,
1,
1,
1,
-1,
1,
0
];
config.batchSize = 1;
WebGLPipeline.call(this, config);
this.colorMatrix = new ColorMatrix();
this.copyShader;
this.addShader;
this.linearShader;
this.colorMatrixShader;
this.fullFrame1;
this.fullFrame2;
this.halfFrame1;
this.halfFrame2;
},
boot: function() {
WebGLPipeline.prototype.boot.call(this);
var shaders = this.shaders;
var targets = this.renderTargets;
this.copyShader = shaders[0];
this.addShader = shaders[1];
this.linearShader = shaders[2];
this.colorMatrixShader = shaders[3];
this.fullFrame1 = targets[0];
this.fullFrame2 = targets[1];
this.halfFrame1 = targets[2];
this.halfFrame2 = targets[3];
},
/**
* Copy the `source` Render Target to the `target` Render Target.
*
* You can optionally set the brightness factor of the copy.
*
* The difference between this method and `drawFrame` is that this method
* uses a faster copy shader, where only the brightness can be modified.
* If you need color level manipulation, see `drawFrame` instead.
*
* @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#copyFrame
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target.
* @param {number} [brightness=1] - The brightness value applied to the frame copy.
* @param {boolean} [clear=true] - Clear the target before copying?
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
*/
copyFrame: function(source, target, brightness, clear, clearAlpha) {
if (brightness === void 0) {
brightness = 1;
}
if (clear === void 0) {
clear = true;
}
if (clearAlpha === void 0) {
clearAlpha = true;
}
var gl = this.gl;
this.setShader(this.copyShader);
this.set1i("uMainSampler", 0);
this.set1f("uBrightness", brightness);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, source.texture.webGLTexture);
if (target) {
gl.viewport(0, 0, target.width, target.height);
gl.bindFramebuffer(gl.FRAMEBUFFER, target.framebuffer.webGLFramebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, target.texture.webGLTexture, 0);
} else {
gl.viewport(0, 0, source.width, source.height);
}
if (clear) {
if (clearAlpha) {
gl.clearColor(0, 0, 0, 0);
} else {
gl.clearColor(0, 0, 0, 1);
}
gl.clear(gl.COLOR_BUFFER_BIT);
}
gl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.STATIC_DRAW);
gl.drawArrays(gl.TRIANGLES, 0, 6);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.bindTexture(gl.TEXTURE_2D, null);
},
/**
* Copy the `source` Render Target to the `target` Render Target.
*
* The difference with this copy is that no resizing takes place. If the `source`
* Render Target is larger than the `target` then only a portion the same size as
* the `target` dimensions is copied across.
*
* You can optionally set the brightness factor of the copy.
*
* @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#blitFrame
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} target - The target Render Target.
* @param {number} [brightness=1] - The brightness value applied to the frame copy.
* @param {boolean} [clear=true] - Clear the target before copying?
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
* @param {boolean} [eraseMode=false] - Erase source from target using ERASE Blend Mode?
* @param {boolean} [flipY=false] - Flip the UV on the Y axis before drawing?
*/
blitFrame: function(source, target, brightness, clear, clearAlpha, eraseMode, flipY) {
if (brightness === void 0) {
brightness = 1;
}
if (clear === void 0) {
clear = true;
}
if (clearAlpha === void 0) {
clearAlpha = true;
}
if (eraseMode === void 0) {
eraseMode = false;
}
if (flipY === void 0) {
flipY = false;
}
var gl = this.gl;
this.setShader(this.copyShader);
this.set1i("uMainSampler", 0);
this.set1f("uBrightness", brightness);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, source.texture.webGLTexture);
if (source.height > target.height) {
gl.viewport(0, 0, source.width, source.height);
this.setTargetUVs(source, target);
} else {
var diff = target.height - source.height;
gl.viewport(0, diff, source.width, source.height);
}
gl.bindFramebuffer(gl.FRAMEBUFFER, target.framebuffer.webGLFramebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, target.texture.webGLTexture, 0);
if (clear) {
if (clearAlpha) {
gl.clearColor(0, 0, 0, 0);
} else {
gl.clearColor(0, 0, 0, 1);
}
gl.clear(gl.COLOR_BUFFER_BIT);
}
if (eraseMode) {
var blendMode = this.renderer.currentBlendMode;
this.renderer.setBlendMode(BlendModes.ERASE);
}
if (flipY) {
this.flipY();
}
gl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.STATIC_DRAW);
gl.drawArrays(gl.TRIANGLES, 0, 6);
if (eraseMode) {
this.renderer.setBlendMode(blendMode);
}
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.bindTexture(gl.TEXTURE_2D, null);
this.resetUVs();
},
/**
* Binds the `source` Render Target and then copies a section of it to the `target` Render Target.
*
* This method is extremely fast because it uses `gl.copyTexSubImage2D` and doesn't
* require the use of any shaders. Remember the coordinates are given in standard WebGL format,
* where x and y specify the lower-left corner of the section, not the top-left. Also, the
* copy entirely replaces the contents of the target texture, no 'merging' or 'blending' takes
* place.
*
* @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#copyFrameRect
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} target - The target Render Target.
* @param {number} x - The x coordinate of the lower left corner where to start copying.
* @param {number} y - The y coordinate of the lower left corner where to start copying.
* @param {number} width - The width of the texture.
* @param {number} height - The height of the texture.
* @param {boolean} [clear=true] - Clear the target before copying?
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
*/
copyFrameRect: function(source, target, x, y, width, height, clear, clearAlpha) {
if (clear === void 0) {
clear = true;
}
if (clearAlpha === void 0) {
clearAlpha = true;
}
var gl = this.gl;
gl.bindFramebuffer(gl.FRAMEBUFFER, source.framebuffer.webGLFramebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, source.texture.webGLTexture, 0);
if (clear) {
if (clearAlpha) {
gl.clearColor(0, 0, 0, 0);
} else {
gl.clearColor(0, 0, 0, 1);
}
gl.clear(gl.COLOR_BUFFER_BIT);
}
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, target.texture.webGLTexture);
gl.copyTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, x, y, width, height);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.bindTexture(gl.TEXTURE_2D, null);
},
/**
* Pops the framebuffer from the renderers FBO stack and sets that as the active target,
* then draws the `source` Render Target to it. It then resets the renderer textures.
*
* This should be done when you need to draw the _final_ results of a pipeline to the game
* canvas, or the next framebuffer in line on the FBO stack. You should only call this once
* in the `onDraw` handler and it should be the final thing called. Be careful not to call
* this if you need to actually use the pipeline shader, instead of the copy shader. In
* those cases, use the `bindAndDraw` method.
*
* @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#copyToGame
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The Render Target to draw from.
*/
copyToGame: function(source) {
var gl = this.gl;
this.setShader(this.copyShader);
this.set1i("uMainSampler", 0);
this.set1f("uBrightness", 1);
this.renderer.popFramebuffer();
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, source.texture.webGLTexture);
gl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.STATIC_DRAW);
gl.drawArrays(gl.TRIANGLES, 0, 6);
},
/**
* Copy the `source` Render Target to the `target` Render Target, using the
* given Color Matrix.
*
* The difference between this method and `copyFrame` is that this method
* uses a color matrix shader, where you have full control over the luminance
* values used during the copy. If you don't need this, you can use the faster
* `copyFrame` method instead.
*
* @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#drawFrame
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target.
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
* @param {Phaser.Display.ColorMatrix} [colorMatrix] - The Color Matrix to use when performing the draw.
*/
drawFrame: function(source, target, clearAlpha, colorMatrix) {
if (clearAlpha === void 0) {
clearAlpha = true;
}
if (colorMatrix === void 0) {
colorMatrix = this.colorMatrix;
}
var gl = this.gl;
this.setShader(this.colorMatrixShader);
this.set1i("uMainSampler", 0);
this.set1fv("uColorMatrix", colorMatrix.getData());
this.set1f("uAlpha", colorMatrix.alpha);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, source.texture.webGLTexture);
if (target) {
gl.viewport(0, 0, target.width, target.height);
gl.bindFramebuffer(gl.FRAMEBUFFER, target.framebuffer.webGLFramebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, target.texture.webGLTexture, 0);
} else {
gl.viewport(0, 0, source.width, source.height);
}
if (clearAlpha) {
gl.clearColor(0, 0, 0, 0);
} else {
gl.clearColor(0, 0, 0, 1);
}
gl.clear(gl.COLOR_BUFFER_BIT);
gl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.STATIC_DRAW);
gl.drawArrays(gl.TRIANGLES, 0, 6);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.bindTexture(gl.TEXTURE_2D, null);
},
/**
* Draws the `source1` and `source2` Render Targets to the `target` Render Target
* using a linear blend effect, which is controlled by the `strength` parameter.
*
* @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#blendFrames
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source1 - The first source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} source2 - The second source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target.
* @param {number} [strength=1] - The strength of the blend.
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
* @param {Phaser.Renderer.WebGL.WebGLShader} [blendShader] - The shader to use during the blend copy.
*/
blendFrames: function(source1, source2, target, strength, clearAlpha, blendShader) {
if (strength === void 0) {
strength = 1;
}
if (clearAlpha === void 0) {
clearAlpha = true;
}
if (blendShader === void 0) {
blendShader = this.linearShader;
}
var gl = this.gl;
this.setShader(blendShader);
this.set1i("uMainSampler1", 0);
this.set1i("uMainSampler2", 1);
this.set1f("uStrength", strength);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, source1.texture.webGLTexture);
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, source2.texture.webGLTexture);
if (target) {
gl.bindFramebuffer(gl.FRAMEBUFFER, target.framebuffer.webGLFramebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, target.texture.webGLTexture, 0);
gl.viewport(0, 0, target.width, target.height);
} else {
gl.viewport(0, 0, source1.width, source1.height);
}
if (clearAlpha) {
gl.clearColor(0, 0, 0, 0);
} else {
gl.clearColor(0, 0, 0, 1);
}
gl.clear(gl.COLOR_BUFFER_BIT);
gl.bufferData(gl.ARRAY_BUFFER, this.vertexData, gl.STATIC_DRAW);
gl.drawArrays(gl.TRIANGLES, 0, 6);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.bindTexture(gl.TEXTURE_2D, null);
},
/**
* Draws the `source1` and `source2` Render Targets to the `target` Render Target
* using an additive blend effect, which is controlled by the `strength` parameter.
*
* @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#blendFramesAdditive
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source1 - The first source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} source2 - The second source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} [target] - The target Render Target.
* @param {number} [strength=1] - The strength of the blend.
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
*/
blendFramesAdditive: function(source1, source2, target, strength, clearAlpha) {
this.blendFrames(source1, source2, target, strength, clearAlpha, this.addShader);
},
/**
* Clears the given Render Target.
*
* @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#clearFrame
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} target - The Render Target to clear.
* @param {boolean} [clearAlpha=true] - Clear the alpha channel when running `gl.clear` on the target?
*/
clearFrame: function(target, clearAlpha) {
if (clearAlpha === void 0) {
clearAlpha = true;
}
var gl = this.gl;
gl.viewport(0, 0, target.width, target.height);
gl.bindFramebuffer(gl.FRAMEBUFFER, target.framebuffer.webGLFramebuffer);
if (clearAlpha) {
gl.clearColor(0, 0, 0, 0);
} else {
gl.clearColor(0, 0, 0, 1);
}
gl.clear(gl.COLOR_BUFFER_BIT);
var fbo = this.renderer.currentFramebuffer;
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo.webGLFramebuffer);
},
/**
* Set the UV values for the 6 vertices that make up the quad used by the shaders
* in the Utility Pipeline.
*
* Be sure to call `resetUVs` once you have finished manipulating the UV coordinates.
*
* @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#setUVs
* @since 3.50.0
*
* @param {number} uA - The u value of vertex A.
* @param {number} vA - The v value of vertex A.
* @param {number} uB - The u value of vertex B.
* @param {number} vB - The v value of vertex B.
* @param {number} uC - The u value of vertex C.
* @param {number} vC - The v value of vertex C.
* @param {number} uD - The u value of vertex D.
* @param {number} vD - The v value of vertex D.
*/
setUVs: function(uA, vA, uB, vB, uC, vC, uD, vD) {
var vertexViewF32 = this.vertexViewF32;
vertexViewF32[2] = uA;
vertexViewF32[3] = vA;
vertexViewF32[6] = uB;
vertexViewF32[7] = vB;
vertexViewF32[10] = uC;
vertexViewF32[11] = vC;
vertexViewF32[14] = uA;
vertexViewF32[15] = vA;
vertexViewF32[18] = uC;
vertexViewF32[19] = vC;
vertexViewF32[22] = uD;
vertexViewF32[23] = vD;
},
/**
* Sets the vertex UV coordinates of the quad used by the shaders in the Utility Pipeline
* so that they correctly adjust the texture coordinates for a blit frame effect.
*
* Be sure to call `resetUVs` once you have finished manipulating the UV coordinates.
*
* @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#setTargetUVs
* @since 3.50.0
*
* @param {Phaser.Renderer.WebGL.RenderTarget} source - The source Render Target.
* @param {Phaser.Renderer.WebGL.RenderTarget} target - The target Render Target.
*/
setTargetUVs: function(source, target) {
var diff = target.height / source.height;
if (diff > 0.5) {
diff = 0.5 - (diff - 0.5);
} else {
diff = 0.5 + (0.5 - diff);
}
this.setUVs(0, diff, 0, 1 + diff, 1, 1 + diff, 1, diff);
},
/**
* Horizontally flips the UV coordinates of the quad used by the shaders in this
* Utility Pipeline.
*
* Be sure to call `resetUVs` once you have finished manipulating the UV coordinates.
*
* @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#flipX
* @since 3.50.0
*/
flipX: function() {
this.setUVs(1, 0, 1, 1, 0, 1, 0, 0);
},
/**
* Vertically flips the UV coordinates of the quad used by the shaders in this
* Utility Pipeline.
*
* Be sure to call `resetUVs` once you have finished manipulating the UV coordinates.
*
* @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#flipY
* @since 3.50.0
*/
flipY: function() {
this.setUVs(0, 1, 0, 0, 1, 0, 1, 1);
},
/**
* Resets the quad vertice UV values to their default settings.
*
* The quad is used by all shaders of the Utility Pipeline.
*
* @method Phaser.Renderer.WebGL.Pipelines.UtilityPipeline#resetUVs
* @since 3.50.0
*/
resetUVs: function() {
this.setUVs(0, 0, 0, 1, 1, 1, 1, 0);
}
});
module2.exports = UtilityPipeline;
}
),
/***/
36060: (
/***/
(module2) => {
var PIPELINE_CONST = {
/**
* The Bitmap Mask Pipeline.
*
* @name Phaser.Renderer.WebGL.Pipelines.BITMAPMASK_PIPELINE
* @type {string}
* @const
* @since 3.50.0
*/
BITMAPMASK_PIPELINE: "BitmapMaskPipeline",
/**
* The Light 2D Pipeline.
*
* @name Phaser.Renderer.WebGL.Pipelines.LIGHT_PIPELINE
* @type {string}
* @const
* @since 3.50.0
*/
LIGHT_PIPELINE: "Light2D",
/**
* The Point Light Pipeline.
*
* @name Phaser.Renderer.WebGL.Pipelines.POINTLIGHT_PIPELINE
* @type {string}
* @const
* @since 3.50.0
*/
POINTLIGHT_PIPELINE: "PointLightPipeline",
/**
* The Single Texture Pipeline.
*
* @name Phaser.Renderer.WebGL.Pipelines.SINGLE_PIPELINE
* @type {string}
* @const
* @since 3.50.0
*/
SINGLE_PIPELINE: "SinglePipeline",
/**
* The Multi Texture Pipeline.
*
* @name Phaser.Renderer.WebGL.Pipelines.MULTI_PIPELINE
* @type {string}
* @const
* @since 3.50.0
*/
MULTI_PIPELINE: "MultiPipeline",
/**
* The Rope Pipeline.
*
* @name Phaser.Renderer.WebGL.Pipelines.ROPE_PIPELINE
* @type {string}
* @const
* @since 3.50.0
*/
ROPE_PIPELINE: "RopePipeline",
/**
* The Graphics and Shapes Pipeline.
*
* @name Phaser.Renderer.WebGL.Pipelines.GRAPHICS_PIPELINE
* @type {string}
* @const
* @since 3.50.0
*/
GRAPHICS_PIPELINE: "GraphicsPipeline",
/**
* The Post FX Pipeline.
*
* @name Phaser.Renderer.WebGL.Pipelines.POSTFX_PIPELINE
* @type {string}
* @const
* @since 3.50.0
*/
POSTFX_PIPELINE: "PostFXPipeline",
/**
* The Utility Pipeline.
*
* @name Phaser.Renderer.WebGL.Pipelines.UTILITY_PIPELINE
* @type {string}
* @const
* @since 3.50.0
*/
UTILITY_PIPELINE: "UtilityPipeline",
/**
* The Mobile Texture Pipeline.
*
* @name Phaser.Renderer.WebGL.Pipelines.MOBILE_PIPELINE
* @type {string}
* @const
* @since 3.60.0
*/
MOBILE_PIPELINE: "MobilePipeline",
/**
* The Special FX Pipeline.
*
* @name Phaser.Renderer.WebGL.Pipelines.FX_PIPELINE
* @type {string}
* @const
* @since 3.60.0
*/
FX_PIPELINE: "FxPipeline"
};
module2.exports = PIPELINE_CONST;
}
),
/***/
84817: (
/***/
(module2) => {
module2.exports = "pipelineafterflush";
}
),
/***/
36712: (
/***/
(module2) => {
module2.exports = "pipelinebeforeflush";
}
),
/***/
40285: (
/***/
(module2) => {
module2.exports = "pipelinebind";
}
),
/***/
65918: (
/***/
(module2) => {
module2.exports = "pipelineboot";
}
),
/***/
92852: (
/***/
(module2) => {
module2.exports = "pipelinedestroy";
}
),
/***/
56072: (
/***/
(module2) => {
module2.exports = "pipelinerebind";
}
),
/***/
57566: (
/***/
(module2) => {
module2.exports = "pipelineresize";
}
),
/***/
77085: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
AFTER_FLUSH: __webpack_require__2(84817),
BEFORE_FLUSH: __webpack_require__2(36712),
BIND: __webpack_require__2(40285),
BOOT: __webpack_require__2(65918),
DESTROY: __webpack_require__2(92852),
REBIND: __webpack_require__2(56072),
RESIZE: __webpack_require__2(57566)
};
}
),
/***/
54812: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var BarrelFrag = __webpack_require__2(99155);
var PostFXPipeline = __webpack_require__2(84057);
var BarrelFXPipeline = new Class({
Extends: PostFXPipeline,
initialize: function BarrelFXPipeline2(game) {
PostFXPipeline.call(this, {
game,
fragShader: BarrelFrag
});
this.amount = 1;
},
onPreRender: function(controller, shader) {
controller = this.getController(controller);
this.set1f("amount", controller.amount, shader);
}
});
module2.exports = BarrelFXPipeline;
}
),
/***/
67329: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var BloomFrag = __webpack_require__2(24400);
var PostFXPipeline = __webpack_require__2(84057);
var BloomFXPipeline = new Class({
Extends: PostFXPipeline,
initialize: function BloomFXPipeline2(game) {
PostFXPipeline.call(this, {
game,
fragShader: BloomFrag
});
this.steps = 4;
this.offsetX = 1;
this.offsetY = 1;
this.blurStrength = 1;
this.strength = 1;
this.glcolor = [1, 1, 1];
},
onPreRender: function(controller) {
controller = this.getController(controller);
this.set1f("strength", controller.blurStrength);
this.set3fv("color", controller.glcolor);
},
onDraw: function(target1) {
var controller = this.getController();
var target2 = this.fullFrame1;
var target3 = this.fullFrame2;
this.copyFrame(target1, target3);
var x = 2 / target1.width * controller.offsetX;
var y = 2 / target1.height * controller.offsetY;
for (var i = 0; i < controller.steps; i++) {
this.set2f("offset", x, 0);
this.copySprite(target1, target2);
this.set2f("offset", 0, y);
this.copySprite(target2, target1);
}
this.blendFrames(target3, target1, target2, controller.strength);
this.copyToGame(target2);
}
});
module2.exports = BloomFXPipeline;
}
),
/***/
8861: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var BlurLowFrag = __webpack_require__2(41514);
var BlurMedFrag = __webpack_require__2(51078);
var BlurHighFrag = __webpack_require__2(94328);
var PostFXPipeline = __webpack_require__2(84057);
var BlurFXPipeline = new Class({
Extends: PostFXPipeline,
initialize: function BlurFXPipeline2(game) {
PostFXPipeline.call(this, {
game,
shaders: [
{
name: "Gaussian5",
fragShader: BlurLowFrag
},
{
name: "Gaussian9",
fragShader: BlurMedFrag
},
{
name: "Gaussian13",
fragShader: BlurHighFrag
}
]
});
this.activeShader = this.shaders[0];
this.x = 2;
this.y = 2;
this.steps = 4;
this.strength = 1;
this.glcolor = [1, 1, 1];
},
/**
* Sets the quality of the blur effect to low.
*
* @method Phaser.Renderer.WebGL.Pipelines.FX.BlurFXPipeline#setQualityLow
* @since 3.60.0
*
* @return {this} This FX Pipeline.
*/
setQualityLow: function() {
this.activeShader = this.shaders[0];
return this;
},
/**
* Sets the quality of the blur effect to medium.
*
* @method Phaser.Renderer.WebGL.Pipelines.FX.BlurFXPipeline#setQualityMedium
* @since 3.60.0
*
* @return {this} This FX Pipeline.
*/
setQualityMedium: function() {
this.activeShader = this.shaders[1];
return this;
},
/**
* Sets the quality of the blur effect to high.
*
* @method Phaser.Renderer.WebGL.Pipelines.FX.BlurFXPipeline#setQualityHigh
* @since 3.60.0
*
* @return {this} This FX Pipeline.
*/
setQualityHigh: function() {
this.activeShader = this.shaders[2];
return this;
},
onDraw: function(target1) {
var controller = this.getController();
var gl = this.gl;
var target2 = this.fullFrame1;
var currentFBO = gl.getParameter(gl.FRAMEBUFFER_BINDING);
this.bind(this.shaders[controller.quality]);
gl.activeTexture(gl.TEXTURE0);
gl.viewport(0, 0, target1.width, target1.height);
this.set1i("uMainSampler", 0);
this.set2f("resolution", target1.width, target1.height);
this.set1f("strength", controller.strength);
this.set3fv("color", controller.glcolor);
for (var i = 0; i < controller.steps; i++) {
this.set2f("offset", controller.x, 0);
this.copySprite(target1, target2);
this.set2f("offset", 0, controller.y);
this.copySprite(target2, target1);
}
gl.bindFramebuffer(gl.FRAMEBUFFER, currentFBO);
gl.bindTexture(gl.TEXTURE_2D, null);
this.copyToGame(target1);
}
});
module2.exports = BlurFXPipeline;
}
),
/***/
51051: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var BokehFrag = __webpack_require__2(90610);
var PostFXPipeline = __webpack_require__2(84057);
var BokehFXPipeline = new Class({
Extends: PostFXPipeline,
initialize: function BokehFXPipeline2(game) {
PostFXPipeline.call(this, {
game,
fragShader: BokehFrag
});
this.isTiltShift = false;
this.strength = 1;
this.blurX = 1;
this.blurY = 1;
this.radius = 0.5;
this.amount = 1;
this.contrast = 0.2;
},
onPreRender: function(controller, shader, width, height) {
controller = this.getController(controller);
this.set1f("radius", controller.radius, shader);
this.set1f("amount", controller.amount, shader);
this.set1f("contrast", controller.contrast, shader);
this.set1f("strength", controller.strength, shader);
this.set2f("blur", controller.blurX, controller.blurY, shader);
this.setBoolean("isTiltShift", controller.isTiltShift, shader);
if (width && height) {
this.set2f("resolution", width, height, shader);
}
},
onDraw: function(target) {
this.set2f("resolution", target.width, target.height);
this.bindAndDraw(target);
}
});
module2.exports = BokehFXPipeline;
}
),
/***/
89428: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CircleFrag = __webpack_require__2(91899);
var PostFXPipeline = __webpack_require__2(84057);
var CircleFXPipeline = new Class({
Extends: PostFXPipeline,
initialize: function CircleFXPipeline2(game) {
PostFXPipeline.call(this, {
game,
fragShader: CircleFrag
});
this.scale = 1;
this.feather = 5e-3;
this.thickness = 8;
this.glcolor = [1, 0.2, 0.7];
this.glcolor2 = [1, 0, 0, 0.4];
},
onPreRender: function(controller, shader, width, height) {
controller = this.getController(controller);
this.set1f("scale", controller.scale, shader);
this.set1f("feather", controller.feather, shader);
this.set1f("thickness", controller.thickness, shader);
this.set3fv("color", controller.glcolor, shader);
this.set4fv("backgroundColor", controller.glcolor2, shader);
if (width && height) {
this.set2f("resolution", width, height, shader);
}
},
onDraw: function(target) {
this.set2f("resolution", target.width, target.height);
this.bindAndDraw(target);
}
});
module2.exports = CircleFXPipeline;
}
),
/***/
88904: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var PostFXPipeline = __webpack_require__2(84057);
var ColorMatrixFXPipeline = new Class({
Extends: PostFXPipeline,
initialize: function ColorMatrixFXPipeline2(game) {
PostFXPipeline.call(this, {
game
});
},
onDraw: function(source) {
var target = this.fullFrame1;
if (this.controller) {
this.manager.drawFrame(source, target, true, this.controller);
} else {
this.drawFrame(source, target);
}
this.copyToGame(target);
}
});
module2.exports = ColorMatrixFXPipeline;
}
),
/***/
63563: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var DisplacementFrag = __webpack_require__2(47838);
var PostFXPipeline = __webpack_require__2(84057);
var DisplacementFXPipeline = new Class({
Extends: PostFXPipeline,
initialize: function DisplacementFXPipeline2(game) {
PostFXPipeline.call(this, {
game,
fragShader: DisplacementFrag
});
this.x = 5e-3;
this.y = 5e-3;
this.glTexture;
},
onBoot: function() {
this.setTexture("__WHITE");
},
setTexture: function(texture) {
var phaserTexture = this.game.textures.getFrame(texture);
if (phaserTexture) {
this.glTexture = phaserTexture.glTexture;
}
},
onDraw: function(source) {
var controller = this.getController();
var target = this.fullFrame1;
this.bind();
this.set1i("uMainSampler", 0);
this.set1i("uDisplacementSampler", 1);
this.set2f("amount", controller.x, controller.y);
this.bindTexture(controller.glTexture, 1);
this.copySprite(source, target);
this.copyToGame(target);
}
});
module2.exports = DisplacementFXPipeline;
}
),
/***/
94045: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var GetFastValue = __webpack_require__2(95540);
var GlowFrag = __webpack_require__2(98656);
var PostFXPipeline = __webpack_require__2(84057);
var Utils = __webpack_require__2(70554);
var GlowFXPipeline = new Class({
Extends: PostFXPipeline,
initialize: function GlowFXPipeline2(game, config) {
var quality = GetFastValue(config, "quality", 0.1);
var distance = GetFastValue(config, "distance", 10);
PostFXPipeline.call(this, {
game,
fragShader: Utils.setGlowQuality(GlowFrag, game, quality, distance)
});
this.outerStrength = 4;
this.innerStrength = 0;
this.knockout = false;
this.glcolor = [1, 1, 1, 1];
},
onPreRender: function(controller, shader, width, height) {
controller = this.getController(controller);
this.set1f("outerStrength", controller.outerStrength, shader);
this.set1f("innerStrength", controller.innerStrength, shader);
this.set4fv("glowColor", controller.glcolor, shader);
this.setBoolean("knockout", controller.knockout, shader);
if (width && height) {
this.set2f("resolution", width, height, shader);
}
},
onDraw: function(target) {
this.set2f("resolution", target.width, target.height);
this.bindAndDraw(target);
}
});
module2.exports = GlowFXPipeline;
}
),
/***/
74088: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var GradientFrag = __webpack_require__2(70463);
var PostFXPipeline = __webpack_require__2(84057);
var GradientFXPipeline = new Class({
Extends: PostFXPipeline,
initialize: function GradientFXPipeline2(game) {
PostFXPipeline.call(this, {
game,
fragShader: GradientFrag
});
this.alpha = 0.2;
this.size = 0;
this.fromX = 0;
this.fromY = 0;
this.toX = 0;
this.toY = 1;
this.glcolor1 = [255, 0, 0];
this.glcolor2 = [0, 255, 0];
},
onPreRender: function(controller, shader) {
controller = this.getController(controller);
this.set1f("alpha", controller.alpha, shader);
this.set1i("size", controller.size, shader);
this.set3fv("color1", controller.glcolor1, shader);
this.set3fv("color2", controller.glcolor2, shader);
this.set2f("positionFrom", controller.fromX, controller.fromY, shader);
this.set2f("positionTo", controller.toX, controller.toY, shader);
}
});
module2.exports = GradientFXPipeline;
}
),
/***/
99636: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var PixelateFrag = __webpack_require__2(50831);
var PostFXPipeline = __webpack_require__2(84057);
var PixelateFXPipeline = new Class({
Extends: PostFXPipeline,
initialize: function PixelateFXPipeline2(game) {
PostFXPipeline.call(this, {
game,
fragShader: PixelateFrag
});
this.amount = 1;
},
onPreRender: function(controller, shader, width, height) {
controller = this.getController(controller);
this.set1f("amount", controller.amount, shader);
if (width && height) {
this.set2f("resolution", width, height, shader);
}
},
onDraw: function(target) {
this.set2f("resolution", target.width, target.height);
this.bindAndDraw(target);
}
});
module2.exports = PixelateFXPipeline;
}
),
/***/
34700: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var ShadowFrag = __webpack_require__2(92595);
var PostFXPipeline = __webpack_require__2(84057);
var ShadowFXPipeline = new Class({
Extends: PostFXPipeline,
initialize: function ShadowFXPipeline2(game) {
PostFXPipeline.call(this, {
game,
fragShader: ShadowFrag
});
this.x = 0;
this.y = 0;
this.decay = 0.1;
this.power = 1;
this.glcolor = [0, 0, 0, 1];
this.samples = 6;
this.intensity = 1;
},
onPreRender: function(controller, shader) {
controller = this.getController(controller);
var samples = controller.samples;
this.set1i("samples", samples, shader);
this.set1f("intensity", controller.intensity, shader);
this.set1f("decay", controller.decay, shader);
this.set1f("power", controller.power / samples, shader);
this.set2f("lightPosition", controller.x, controller.y, shader);
this.set4fv("color", controller.glcolor, shader);
}
});
module2.exports = ShadowFXPipeline;
}
),
/***/
91157: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var ShineFrag = __webpack_require__2(72464);
var PostFXPipeline = __webpack_require__2(84057);
var ShineFXPipeline = new Class({
Extends: PostFXPipeline,
initialize: function ShineFXPipeline2(game) {
PostFXPipeline.call(this, {
game,
fragShader: ShineFrag
});
this.speed = 0.5;
this.lineWidth = 0.5;
this.gradient = 3;
this.reveal = false;
},
onPreRender: function(controller, shader, width, height) {
controller = this.getController(controller);
this.setTime("time", shader);
this.set1f("speed", controller.speed, shader);
this.set1f("lineWidth", controller.lineWidth, shader);
this.set1f("gradient", controller.gradient, shader);
this.setBoolean("reveal", controller.reveal, shader);
if (width && height) {
this.set2f("resolution", width, height, shader);
}
},
onDraw: function(target) {
this.set2f("resolution", target.width, target.height);
this.bindAndDraw(target);
}
});
module2.exports = ShineFXPipeline;
}
),
/***/
27797: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var VignetteFrag = __webpack_require__2(39249);
var PostFXPipeline = __webpack_require__2(84057);
var VignetteFXPipeline = new Class({
Extends: PostFXPipeline,
initialize: function VignetteFXPipeline2(game) {
PostFXPipeline.call(this, {
game,
fragShader: VignetteFrag
});
this.x = 0.5;
this.y = 0.5;
this.radius = 0.5;
this.strength = 0.5;
},
onPreRender: function(controller, shader) {
controller = this.getController(controller);
this.set1f("radius", controller.radius, shader);
this.set1f("strength", controller.strength, shader);
this.set2f("position", controller.x, controller.y, shader);
}
});
module2.exports = VignetteFXPipeline;
}
),
/***/
67603: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var WipeFrag = __webpack_require__2(2878);
var PostFXPipeline = __webpack_require__2(84057);
var WipeFXPipeline = new Class({
Extends: PostFXPipeline,
initialize: function WipeFXPipeline2(game) {
PostFXPipeline.call(this, {
game,
fragShader: WipeFrag
});
this.progress = 0;
this.wipeWidth = 0.1;
this.direction = 0;
this.axis = 0;
this.reveal = false;
},
onPreRender: function(controller, shader) {
controller = this.getController(controller);
var progress = controller.progress;
var wipeWidth = controller.wipeWidth;
var direction = controller.direction;
var axis = controller.axis;
this.set4f("config", progress, wipeWidth, direction, axis, shader);
this.setBoolean("reveal", controller.reveal, shader);
}
});
module2.exports = WipeFXPipeline;
}
),
/***/
58918: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var FX = {
Barrel: __webpack_require__2(54812),
Bloom: __webpack_require__2(67329),
Blur: __webpack_require__2(8861),
Bokeh: __webpack_require__2(51051),
Circle: __webpack_require__2(89428),
ColorMatrix: __webpack_require__2(88904),
Displacement: __webpack_require__2(63563),
Glow: __webpack_require__2(94045),
Gradient: __webpack_require__2(74088),
Pixelate: __webpack_require__2(99636),
Shadow: __webpack_require__2(34700),
Shine: __webpack_require__2(91157),
Vignette: __webpack_require__2(27797),
Wipe: __webpack_require__2(67603)
};
module2.exports = FX;
}
),
/***/
96615: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(36060);
var Extend = __webpack_require__2(79291);
var Pipelines = {
FX: __webpack_require__2(58918),
BitmapMaskPipeline: __webpack_require__2(31302),
Events: __webpack_require__2(77085),
FXPipeline: __webpack_require__2(92651),
LightPipeline: __webpack_require__2(96569),
MobilePipeline: __webpack_require__2(56527),
MultiPipeline: __webpack_require__2(57516),
PointLightPipeline: __webpack_require__2(43439),
PostFXPipeline: __webpack_require__2(84057),
PreFXPipeline: __webpack_require__2(43558),
RopePipeline: __webpack_require__2(81041),
SinglePipeline: __webpack_require__2(12385),
UtilityPipeline: __webpack_require__2(7589)
};
Pipelines = Extend(false, Pipelines, CONST);
module2.exports = Pipelines;
}
),
/***/
35407: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME PHASER_ADD_BLEND_FS",
"precision mediump float;",
"uniform sampler2D uMainSampler1;",
"uniform sampler2D uMainSampler2;",
"uniform float uStrength;",
"varying vec2 outTexCoord;",
"void main ()",
"{",
" vec4 frame1 = texture2D(uMainSampler1, outTexCoord);",
" vec4 frame2 = texture2D(uMainSampler2, outTexCoord);",
" gl_FragColor = frame1 + frame2 * uStrength;",
"}"
].join("\n");
}
),
/***/
78908: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME PHASER_BITMAP_MASK_FS",
"precision mediump float;",
"uniform vec2 uResolution;",
"uniform sampler2D uMainSampler;",
"uniform sampler2D uMaskSampler;",
"uniform bool uInvertMaskAlpha;",
"void main ()",
"{",
" vec2 uv = gl_FragCoord.xy / uResolution;",
" vec4 mainColor = texture2D(uMainSampler, uv);",
" vec4 maskColor = texture2D(uMaskSampler, uv);",
" if (!uInvertMaskAlpha)",
" {",
" mainColor *= maskColor.a;",
" }",
" else",
" {",
" mainColor *= (1.0 - maskColor.a);",
" }",
" gl_FragColor = mainColor;",
"}"
].join("\n");
}
),
/***/
85191: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME PHASER_BITMAP_MASK_VS",
"precision mediump float;",
"attribute vec2 inPosition;",
"void main ()",
"{",
" gl_Position = vec4(inPosition, 0.0, 1.0);",
"}"
].join("\n");
}
),
/***/
96293: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME PHASER_COLORMATRIX_FS",
"precision mediump float;",
"uniform sampler2D uMainSampler;",
"uniform float uColorMatrix[20];",
"uniform float uAlpha;",
"varying vec2 outTexCoord;",
"void main ()",
"{",
" vec4 c = texture2D(uMainSampler, outTexCoord);",
" if (uAlpha == 0.0)",
" {",
" gl_FragColor = c;",
" return;",
" }",
" if (c.a > 0.0)",
" {",
" c.rgb /= c.a;",
" }",
" vec4 result;",
" result.r = (uColorMatrix[0] * c.r) + (uColorMatrix[1] * c.g) + (uColorMatrix[2] * c.b) + (uColorMatrix[3] * c.a) + uColorMatrix[4];",
" result.g = (uColorMatrix[5] * c.r) + (uColorMatrix[6] * c.g) + (uColorMatrix[7] * c.b) + (uColorMatrix[8] * c.a) + uColorMatrix[9];",
" result.b = (uColorMatrix[10] * c.r) + (uColorMatrix[11] * c.g) + (uColorMatrix[12] * c.b) + (uColorMatrix[13] * c.a) + uColorMatrix[14];",
" result.a = (uColorMatrix[15] * c.r) + (uColorMatrix[16] * c.g) + (uColorMatrix[17] * c.b) + (uColorMatrix[18] * c.a) + uColorMatrix[19];",
" vec3 rgb = mix(c.rgb, result.rgb, uAlpha);",
" rgb *= result.a;",
" gl_FragColor = vec4(rgb, result.a);",
"}"
].join("\n");
}
),
/***/
36682: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME PHASER_COPY_FS",
"precision mediump float;",
"uniform sampler2D uMainSampler;",
"uniform float uBrightness;",
"varying vec2 outTexCoord;",
"void main ()",
"{",
" gl_FragColor = texture2D(uMainSampler, outTexCoord) * uBrightness;",
"}"
].join("\n");
}
),
/***/
99155: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME BARREL_FS",
"precision mediump float;",
"uniform sampler2D uMainSampler;",
"uniform float amount;",
"varying vec2 outTexCoord;",
"vec2 Distort(vec2 p)",
"{",
" float theta = atan(p.y, p.x);",
" float radius = length(p);",
" radius = pow(radius, amount);",
" p.x = radius * cos(theta);",
" p.y = radius * sin(theta);",
" return 0.5 * (p + 1.0);",
"}",
"void main()",
"{",
" vec2 xy = 2.0 * outTexCoord - 1.0;",
" vec2 texCoord = outTexCoord;",
" if (length(xy) < 1.0)",
" {",
" texCoord = Distort(xy);",
" }",
" gl_FragColor = texture2D(uMainSampler, texCoord);",
"}"
].join("\n");
}
),
/***/
24400: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME BLOOM_FS",
"precision mediump float;",
"uniform sampler2D uMainSampler;",
"uniform vec2 offset;",
"uniform float strength;",
"uniform vec3 color;",
"varying vec2 outTexCoord;",
"void main ()",
"{",
" vec4 sum = texture2D(uMainSampler, outTexCoord) * 0.204164 * strength;",
" sum = sum + texture2D(uMainSampler, outTexCoord + offset * 1.407333) * 0.304005;",
" sum = sum + texture2D(uMainSampler, outTexCoord - offset * 1.407333) * 0.304005;",
" sum = sum + texture2D(uMainSampler, outTexCoord + offset * 3.294215) * 0.093913;",
" gl_FragColor = (sum + texture2D(uMainSampler, outTexCoord - offset * 3.294215) * 0.093913) * vec4(color, 1);",
"}"
].join("\n");
}
),
/***/
94328: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME BLUR_HIGH_FS",
"precision mediump float;",
"uniform sampler2D uMainSampler;",
"uniform vec2 resolution;",
"uniform vec2 offset;",
"uniform float strength;",
"uniform vec3 color;",
"varying vec2 outTexCoord;",
"void main ()",
"{",
" vec2 uv = outTexCoord;",
" vec4 col = vec4(0.0);",
" vec2 off1 = vec2(1.411764705882353) * offset * strength;",
" vec2 off2 = vec2(3.2941176470588234) * offset * strength;",
" vec2 off3 = vec2(5.176470588235294) * offset * strength;",
" col += texture2D(uMainSampler, uv) * 0.1964825501511404;",
" col += texture2D(uMainSampler, uv + (off1 / resolution)) * 0.2969069646728344;",
" col += texture2D(uMainSampler, uv - (off1 / resolution)) * 0.2969069646728344;",
" col += texture2D(uMainSampler, uv + (off2 / resolution)) * 0.09447039785044732;",
" col += texture2D(uMainSampler, uv - (off2 / resolution)) * 0.09447039785044732;",
" col += texture2D(uMainSampler, uv + (off3 / resolution)) * 0.010381362401148057;",
" col += texture2D(uMainSampler, uv - (off3 / resolution)) * 0.010381362401148057;",
" gl_FragColor = col * vec4(color, 1.0);",
"}"
].join("\n");
}
),
/***/
41514: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME BLUR_LOW_FS",
"precision mediump float;",
"uniform sampler2D uMainSampler;",
"uniform vec2 resolution;",
"uniform vec2 offset;",
"uniform float strength;",
"uniform vec3 color;",
"varying vec2 outTexCoord;",
"void main ()",
"{",
" vec2 uv = outTexCoord;",
" vec4 col = vec4(0.0);",
" vec2 offset = vec2(1.333) * offset * strength;",
" col += texture2D(uMainSampler, uv) * 0.29411764705882354;",
" col += texture2D(uMainSampler, uv + (offset / resolution)) * 0.35294117647058826;",
" col += texture2D(uMainSampler, uv - (offset / resolution)) * 0.35294117647058826;",
" gl_FragColor = col * vec4(color, 1.0);",
"}"
].join("\n");
}
),
/***/
51078: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME BLUR_MED_FS",
"precision mediump float;",
"uniform sampler2D uMainSampler;",
"uniform vec2 resolution;",
"uniform vec2 offset;",
"uniform float strength;",
"uniform vec3 color;",
"varying vec2 outTexCoord;",
"void main ()",
"{",
" vec2 uv = outTexCoord;",
" vec4 col = vec4(0.0);",
" vec2 off1 = vec2(1.3846153846) * offset * strength;",
" vec2 off2 = vec2(3.2307692308) * offset * strength;",
" col += texture2D(uMainSampler, uv) * 0.2270270270;",
" col += texture2D(uMainSampler, uv + (off1 / resolution)) * 0.3162162162;",
" col += texture2D(uMainSampler, uv - (off1 / resolution)) * 0.3162162162;",
" col += texture2D(uMainSampler, uv + (off2 / resolution)) * 0.0702702703;",
" col += texture2D(uMainSampler, uv - (off2 / resolution)) * 0.0702702703;",
" gl_FragColor = col * vec4(color, 1.0);",
"}"
].join("\n");
}
),
/***/
90610: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME BOKEH_FS",
"precision mediump float;",
"#define ITERATIONS 100.0",
"#define ONEOVER_ITR 1.0 / ITERATIONS",
"#define PI 3.141596",
"#define GOLDEN_ANGLE 2.39996323",
"uniform sampler2D uMainSampler;",
"uniform vec2 resolution;",
"uniform float radius;",
"uniform float amount;",
"uniform float contrast;",
"uniform bool isTiltShift;",
"uniform float strength;",
"uniform vec2 blur;",
"varying vec2 outTexCoord;",
"vec2 Sample (in float theta, inout float r)",
"{",
" r += 1.0 / r;",
" return (r - 1.0) * vec2(cos(theta), sin(theta)) * 0.06;",
"}",
"vec3 Bokeh (sampler2D tex, vec2 uv, float radius)",
"{",
" vec3 acc = vec3(0.0);",
" vec3 div = vec3(0.0);",
" vec2 pixel = vec2(resolution.y / resolution.x, 1.0) * radius * .025;",
" float r = 1.0;",
" for (float j = 0.0; j < GOLDEN_ANGLE * ITERATIONS; j += GOLDEN_ANGLE)",
" {",
" vec3 col = texture2D(tex, uv + pixel * Sample(j, r)).xyz;",
" col = contrast > 0.0 ? col * col * (1.0 + contrast) : col;",
" vec3 bokeh = vec3(0.5) + pow(col, vec3(10.0)) * amount;",
" acc += col * bokeh;",
" div += bokeh;",
" }",
" return acc / div;",
"}",
"void main ()",
"{",
" float shift = 1.0;",
" if (isTiltShift)",
" {",
" vec2 uv = vec2(gl_FragCoord.xy / resolution + vec2(-0.5, -0.5)) * 2.0;",
" float centerStrength = 1.0;",
" shift = length(uv * blur * strength) * centerStrength;",
" }",
" gl_FragColor = vec4(Bokeh(uMainSampler, outTexCoord * vec2(1.0, 1.0), radius * shift), 0.0);",
"}"
].join("\n");
}
),
/***/
91899: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME CIRCLE_FS",
"precision mediump float;",
"uniform sampler2D uMainSampler;",
"uniform vec2 resolution;",
"uniform vec3 color;",
"uniform vec4 backgroundColor;",
"uniform float thickness;",
"uniform float scale;",
"uniform float feather;",
"varying vec2 outTexCoord;",
"void main ()",
"{",
" vec4 texture = texture2D(uMainSampler, outTexCoord);",
" vec2 position = (gl_FragCoord.xy / resolution.xy) * 2.0 - 1.0;",
" float aspectRatio = resolution.x / resolution.y;",
" position.x *= aspectRatio;",
" float grad = length(position);",
" float outer = aspectRatio;",
" float inner = outer - (thickness * 2.0 / resolution.y);",
" if (aspectRatio >= 1.0)",
" {",
" float f = 2.0 + (resolution.y / resolution.x);",
" outer = 1.0;",
" inner = 1.0 - (thickness * f / resolution.x);",
" }",
" outer *= scale;",
" inner *= scale;",
" float circle = smoothstep(outer, outer - 0.01, grad);",
" float ring = circle - smoothstep(inner, inner - feather, grad);",
" texture = mix(backgroundColor * backgroundColor.a, texture, texture.a);",
" texture = (texture * (circle - ring));",
" gl_FragColor = vec4(texture.rgb + (ring * color), texture.a);",
"}"
].join("\n");
}
),
/***/
47838: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME DISPLACEMENT_FS",
"precision mediump float;",
"uniform sampler2D uMainSampler;",
"uniform sampler2D uDisplacementSampler;",
"uniform vec2 amount;",
"varying vec2 outTexCoord;",
"void main ()",
"{",
" vec2 disp = (-vec2(0.5, 0.5) + texture2D(uDisplacementSampler, outTexCoord).rr) * amount;",
" gl_FragColor = texture2D(uMainSampler, outTexCoord + disp).rgba;",
"}"
].join("\n");
}
),
/***/
98656: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME GLOW_FS",
"precision mediump float;",
"uniform sampler2D uMainSampler;",
"varying vec2 outTexCoord;",
"uniform float outerStrength;",
"uniform float innerStrength;",
"uniform vec2 resolution;",
"uniform vec4 glowColor;",
"uniform bool knockout;",
"const float PI = 3.14159265358979323846264;",
"const float DIST = __DIST__;",
"const float SIZE = min(__SIZE__, PI * 2.0);",
"const float STEP = ceil(PI * 2.0 / SIZE);",
"const float MAX_ALPHA = STEP * DIST * (DIST + 1.0) / 2.0;",
"void main ()",
"{",
" vec2 px = vec2(1.0 / resolution.x, 1.0 / resolution.y);",
" float totalAlpha = 0.0;",
" vec2 direction;",
" vec2 displaced;",
" vec4 color;",
" for (float angle = 0.0; angle < PI * 2.0; angle += SIZE)",
" {",
" direction = vec2(cos(angle), sin(angle)) * px;",
" for (float curDistance = 0.0; curDistance < DIST; curDistance++)",
" {",
" displaced = outTexCoord + direction * (curDistance + 1.0);",
" color = texture2D(uMainSampler, displaced);",
" totalAlpha += (DIST - curDistance) * color.a;",
" }",
" }",
" color = texture2D(uMainSampler, outTexCoord);",
" float alphaRatio = (totalAlpha / MAX_ALPHA);",
" float innerGlowAlpha = (1.0 - alphaRatio) * innerStrength * color.a;",
" float innerGlowStrength = min(1.0, innerGlowAlpha);",
" vec4 innerColor = mix(color, glowColor, innerGlowStrength);",
" float outerGlowAlpha = alphaRatio * outerStrength * (1.0 - color.a);",
" float outerGlowStrength = min(1.0 - innerColor.a, outerGlowAlpha);",
" vec4 outerGlowColor = outerGlowStrength * glowColor.rgba;",
" if (knockout)",
" {",
" float resultAlpha = outerGlowAlpha + innerGlowAlpha;",
" gl_FragColor = vec4(glowColor.rgb * resultAlpha, resultAlpha);",
" }",
" else",
" {",
" gl_FragColor = innerColor + outerGlowColor;",
" }",
"}"
].join("\n");
}
),
/***/
70463: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME GRADIENT_FS",
"#define SRGB_TO_LINEAR(c) pow((c), vec3(2.2))",
"#define LINEAR_TO_SRGB(c) pow((c), vec3(1.0 / 2.2))",
"#define SRGB(r, g, b) SRGB_TO_LINEAR(vec3(float(r), float(g), float(b)) / 255.0)",
"precision mediump float;",
"uniform sampler2D uMainSampler;",
"uniform vec2 positionFrom;",
"uniform vec2 positionTo;",
"uniform vec3 color1;",
"uniform vec3 color2;",
"uniform float alpha;",
"uniform int size;",
"varying vec2 outTexCoord;",
"float gradientNoise(in vec2 uv)",
"{",
" const vec3 magic = vec3(0.06711056, 0.00583715, 52.9829189);",
" return fract(magic.z * fract(dot(uv, magic.xy)));",
"}",
"float stepped (in float s, in float scale, in int steps)",
"{",
" return steps > 0 ? floor( s / ((1.0 * scale) / float(steps))) * 1.0 / float(steps - 1) : s;",
"}",
"void main ()",
"{",
" vec2 a = positionFrom;",
" vec2 b = positionTo;",
" vec2 ba = b - a;",
" float d = dot(outTexCoord - a, ba) / dot(ba, ba);",
" float t = size > 0 ? stepped(d, 1.0, size) : d;",
" t = smoothstep(0.0, 1.0, clamp(t, 0.0, 1.0));",
" vec3 color = mix(SRGB(color1.r, color1.g, color1.b), SRGB(color2.r, color2.g, color2.b), t);",
" color = LINEAR_TO_SRGB(color);",
" color += (1.0 / 255.0) * gradientNoise(outTexCoord) - (0.5 / 255.0);",
" vec4 texture = texture2D(uMainSampler, outTexCoord);",
" gl_FragColor = vec4(mix(color.rgb, texture.rgb, alpha), 1.0) * texture.a;",
"}"
].join("\n");
}
),
/***/
50831: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME PIXELATE_FS",
"precision mediump float;",
"uniform sampler2D uMainSampler;",
"uniform vec2 resolution;",
"uniform float amount;",
"varying vec2 outTexCoord;",
"void main ()",
"{",
" float pixelSize = floor(2.0 + amount);",
" vec2 center = pixelSize * floor(outTexCoord * resolution / pixelSize) + pixelSize * vec2(0.5, 0.5);",
" vec2 corner1 = center + pixelSize * vec2(-0.5, -0.5);",
" vec2 corner2 = center + pixelSize * vec2(+0.5, -0.5);",
" vec2 corner3 = center + pixelSize * vec2(+0.5, +0.5);",
" vec2 corner4 = center + pixelSize * vec2(-0.5, +0.5);",
" vec4 pixel = 0.4 * texture2D(uMainSampler, center / resolution);",
" pixel += 0.15 * texture2D(uMainSampler, corner1 / resolution);",
" pixel += 0.15 * texture2D(uMainSampler, corner2 / resolution);",
" pixel += 0.15 * texture2D(uMainSampler, corner3 / resolution);",
" pixel += 0.15 * texture2D(uMainSampler, corner4 / resolution);",
" gl_FragColor = pixel;",
"}"
].join("\n");
}
),
/***/
92595: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME SHADOW_FS",
"precision mediump float;",
"uniform sampler2D uMainSampler;",
"varying vec2 outTexCoord;",
"uniform vec2 lightPosition;",
"uniform vec4 color;",
"uniform float decay;",
"uniform float power;",
"uniform float intensity;",
"uniform int samples;",
"const int MAX = 12;",
"void main ()",
"{",
" vec4 texture = texture2D(uMainSampler, outTexCoord);",
" vec2 pc = (lightPosition - outTexCoord) * intensity;",
" float shadow = 0.0;",
" float limit = max(float(MAX), float(samples));",
" for (int i = 0; i < MAX; ++i)",
" {",
" if (i >= samples)",
" {",
" break;",
" }",
" shadow += texture2D(uMainSampler, outTexCoord + float(i) * decay / limit * pc).a * power;",
" }",
" float mask = 1.0 - texture.a;",
" gl_FragColor = mix(texture, color, shadow * mask);",
"}"
].join("\n");
}
),
/***/
72464: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME SHINE_FS",
"precision mediump float;",
"uniform sampler2D uMainSampler;",
"uniform vec2 resolution;",
"uniform bool reveal;",
"uniform float speed;",
"uniform float time;",
"uniform float lineWidth;",
"uniform float gradient;",
"varying vec2 outTexCoord;",
"void main ()",
"{",
" vec2 uv = gl_FragCoord.xy / resolution.xy;",
" vec4 tex = texture2D(uMainSampler, outTexCoord);",
" vec4 col1 = vec4(0.3, 0.0, 0.0, 1.0);",
" vec4 col2 = vec4(0.85, 0.85, 0.85, 1.0);",
" uv.x = uv.x - mod(time * speed, 2.0) + 0.5;",
" float y = uv.x * gradient;",
" float s = smoothstep(y - lineWidth, y, uv.y) - smoothstep(y, y + lineWidth, uv.y);",
" gl_FragColor = (((s * col1) + (s * col2)) * tex);",
" if (!reveal)",
" {",
" gl_FragColor += tex;",
" }",
"}"
].join("\n");
}
),
/***/
39249: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME VIGNETTE_FS",
"precision mediump float;",
"uniform sampler2D uMainSampler;",
"uniform float radius;",
"uniform float strength;",
"uniform vec2 position;",
"varying vec2 outTexCoord;",
"void main ()",
"{",
" vec4 col = vec4(1.0);",
" float d = length(outTexCoord - position);",
" if (d <= radius)",
" {",
" float g = d / radius;",
" g = sin(g * 3.14 * strength);",
" col = vec4(g * g * g);",
" }",
" vec4 texture = texture2D(uMainSampler, outTexCoord);",
" gl_FragColor = texture * (1.0 - col);",
"}"
].join("\n");
}
),
/***/
2878: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME WIPE_FS",
"precision mediump float;",
"uniform sampler2D uMainSampler;",
"uniform vec4 config;",
"uniform bool reveal;",
"varying vec2 outTexCoord;",
"void main ()",
"{",
" vec2 uv = outTexCoord;",
" vec4 color0;",
" vec4 color1;",
" if (reveal)",
" {",
" color0 = vec4(0);",
" color1 = texture2D(uMainSampler, uv);",
" }",
" else",
" {",
" color0 = texture2D(uMainSampler, uv);",
" color1 = vec4(0);",
" }",
" float distance = config.x;",
" float width = config.y;",
" float direction = config.z;",
" float axis = uv.x;",
" if (config.w == 1.0)",
" {",
" axis = uv.y;",
" }",
" float adjust = mix(width, -width, distance);",
" float value = smoothstep(distance - width, distance + width, abs(direction - axis) + adjust);",
" gl_FragColor = mix(color1, color0, value);",
"}"
].join("\n");
}
),
/***/
31063: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME PHASER_LIGHT_FS",
"precision mediump float;",
"struct Light",
"{",
" vec2 position;",
" vec3 color;",
" float intensity;",
" float radius;",
"};",
"const int kMaxLights = %LIGHT_COUNT%;",
"uniform vec4 uCamera; /* x, y, rotation, zoom */",
"uniform vec2 uResolution;",
"uniform sampler2D uMainSampler;",
"uniform sampler2D uNormSampler;",
"uniform vec3 uAmbientLightColor;",
"uniform Light uLights[kMaxLights];",
"uniform mat3 uInverseRotationMatrix;",
"uniform int uLightCount;",
"varying vec2 outTexCoord;",
"varying float outTexId;",
"varying float outTintEffect;",
"varying vec4 outTint;",
"void main ()",
"{",
" vec3 finalColor = vec3(0.0, 0.0, 0.0);",
" vec4 texel = vec4(outTint.bgr * outTint.a, outTint.a);",
" vec4 texture = texture2D(uMainSampler, outTexCoord);",
" vec4 color = texture * texel;",
" if (outTintEffect == 1.0)",
" {",
" color.rgb = mix(texture.rgb, outTint.bgr * outTint.a, texture.a);",
" }",
" else if (outTintEffect == 2.0)",
" {",
" color = texel;",
" }",
" vec3 normalMap = texture2D(uNormSampler, outTexCoord).rgb;",
" vec3 normal = normalize(uInverseRotationMatrix * vec3(normalMap * 2.0 - 1.0));",
" vec2 res = vec2(min(uResolution.x, uResolution.y)) * uCamera.w;",
" for (int index = 0; index < kMaxLights; ++index)",
" {",
" if (index < uLightCount)",
" {",
" Light light = uLights[index];",
" vec3 lightDir = vec3((light.position.xy / res) - (gl_FragCoord.xy / res), 0.1);",
" vec3 lightNormal = normalize(lightDir);",
" float distToSurf = length(lightDir) * uCamera.w;",
" float diffuseFactor = max(dot(normal, lightNormal), 0.0);",
" float radius = (light.radius / res.x * uCamera.w) * uCamera.w;",
" float attenuation = clamp(1.0 - distToSurf * distToSurf / (radius * radius), 0.0, 1.0);",
" vec3 diffuse = light.color * diffuseFactor;",
" finalColor += (attenuation * diffuse) * light.intensity;",
" }",
" }",
" vec4 colorOutput = vec4(uAmbientLightColor + finalColor, 1.0);",
" gl_FragColor = color * vec4(colorOutput.rgb * colorOutput.a, colorOutput.a);",
"}"
].join("\n");
}
),
/***/
48247: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME PHASER_LINEAR_BLEND_FS",
"precision mediump float;",
"uniform sampler2D uMainSampler1;",
"uniform sampler2D uMainSampler2;",
"uniform float uStrength;",
"varying vec2 outTexCoord;",
"void main ()",
"{",
" vec4 frame1 = texture2D(uMainSampler1, outTexCoord);",
" vec4 frame2 = texture2D(uMainSampler2, outTexCoord);",
" gl_FragColor = mix(frame1, frame2 * uStrength, 0.5);",
"}"
].join("\n");
}
),
/***/
41214: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME PHASER_MESH_FS",
"precision mediump float;",
"uniform vec3 uLightPosition;",
"uniform vec3 uLightAmbient;",
"uniform vec3 uLightDiffuse;",
"uniform vec3 uLightSpecular;",
"uniform vec3 uFogColor;",
"uniform float uFogNear;",
"uniform float uFogFar;",
"uniform vec3 uMaterialAmbient;",
"uniform vec3 uMaterialDiffuse;",
"uniform vec3 uMaterialSpecular;",
"uniform float uMaterialShine;",
"uniform vec3 uCameraPosition;",
"uniform sampler2D uTexture;",
"varying vec2 vTextureCoord;",
"varying vec3 vNormal;",
"varying vec3 vPosition;",
"void main (void)",
"{",
" vec4 color = texture2D(uTexture, vTextureCoord);",
" vec3 ambient = uLightAmbient * uMaterialAmbient;",
" vec3 norm = normalize(vNormal);",
" vec3 lightDir = normalize(uLightPosition - vPosition);",
" float diff = max(dot(norm, lightDir), 0.0);",
" vec3 diffuse = uLightDiffuse * (diff * uMaterialDiffuse);",
" vec3 viewDir = normalize(uCameraPosition - vPosition);",
" vec3 reflectDir = reflect(-lightDir, norm);",
" float spec = pow(max(dot(viewDir, reflectDir), 0.0), uMaterialShine);",
" vec3 specular = uLightSpecular * (spec * uMaterialSpecular);",
" vec3 result = (ambient + diffuse + specular) * color.rgb;",
" float depth = gl_FragCoord.z / gl_FragCoord.w;",
" float fogFactor = smoothstep(uFogNear, uFogFar, depth);",
" gl_FragColor.rgb = mix(result.rgb, uFogColor, fogFactor);",
" gl_FragColor.a = color.a;",
"}"
].join("\n");
}
),
/***/
39653: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME PHASER_MESH_VS",
"precision mediump float;",
"attribute vec3 aVertexPosition;",
"attribute vec3 aVertexNormal;",
"attribute vec2 aTextureCoord;",
"uniform mat4 uViewProjectionMatrix;",
"uniform mat4 uModelMatrix;",
"uniform mat4 uNormalMatrix;",
"varying vec2 vTextureCoord;",
"varying vec3 vNormal;",
"varying vec3 vPosition;",
"void main ()",
"{",
" vTextureCoord = aTextureCoord;",
" vPosition = vec3(uModelMatrix * vec4(aVertexPosition, 1.0));",
" vNormal = vec3(uNormalMatrix * vec4(aVertexNormal, 1.0));",
" gl_Position = uViewProjectionMatrix * uModelMatrix * vec4(aVertexPosition, 1.0);",
"}"
].join("\n");
}
),
/***/
62143: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME PHASER_MOBILE_FS",
"#ifdef GL_FRAGMENT_PRECISION_HIGH",
"precision highp float;",
"#else",
"precision mediump float;",
"#endif",
"uniform sampler2D uMainSampler;",
"varying vec2 outTexCoord;",
"varying float outTintEffect;",
"varying vec4 outTint;",
"void main ()",
"{",
" vec4 texel = vec4(outTint.bgr * outTint.a, outTint.a);",
" vec4 texture = texture2D(uMainSampler, outTexCoord);",
" vec4 color = texture * texel;",
" if (outTintEffect == 1.0)",
" {",
" color.rgb = mix(texture.rgb, outTint.bgr * outTint.a, texture.a);",
" }",
" else if (outTintEffect == 2.0)",
" {",
" color = texel;",
" }",
" gl_FragColor = color;",
"}"
].join("\n");
}
),
/***/
47940: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME PHASER_MOBILE_VS",
"precision mediump float;",
"uniform mat4 uProjectionMatrix;",
"uniform vec2 uResolution;",
"attribute vec2 inPosition;",
"attribute vec2 inTexCoord;",
"attribute float inTexId;",
"attribute float inTintEffect;",
"attribute vec4 inTint;",
"varying vec2 outTexCoord;",
"varying float outTintEffect;",
"varying vec4 outTint;",
"void main ()",
"{",
" gl_Position = uProjectionMatrix * vec4(inPosition, 1.0, 1.0);",
" outTexCoord = inTexCoord;",
" outTint = inTint;",
" outTintEffect = inTintEffect;",
"}"
].join("\n");
}
),
/***/
98840: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME PHASER_MULTI_FS",
"#ifdef GL_FRAGMENT_PRECISION_HIGH",
"precision highp float;",
"#else",
"precision mediump float;",
"#endif",
"uniform sampler2D uMainSampler[%count%];",
"varying vec2 outTexCoord;",
"varying float outTexId;",
"varying float outTintEffect;",
"varying vec4 outTint;",
"void main ()",
"{",
" vec4 texture;",
" %forloop%",
" vec4 texel = vec4(outTint.bgr * outTint.a, outTint.a);",
" vec4 color = texture * texel;",
" if (outTintEffect == 1.0)",
" {",
" color.rgb = mix(texture.rgb, outTint.bgr * outTint.a, texture.a);",
" }",
" else if (outTintEffect == 2.0)",
" {",
" color = texel;",
" }",
" gl_FragColor = color;",
"}"
].join("\n");
}
),
/***/
44667: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME PHASER_MULTI_VS",
"precision mediump float;",
"uniform mat4 uProjectionMatrix;",
"uniform vec2 uResolution;",
"attribute vec2 inPosition;",
"attribute vec2 inTexCoord;",
"attribute float inTexId;",
"attribute float inTintEffect;",
"attribute vec4 inTint;",
"varying vec2 outTexCoord;",
"varying float outTexId;",
"varying float outTintEffect;",
"varying vec4 outTint;",
"void main ()",
"{",
" gl_Position = uProjectionMatrix * vec4(inPosition, 1.0, 1.0);",
" outTexCoord = inTexCoord;",
" outTexId = inTexId;",
" outTint = inTint;",
" outTintEffect = inTintEffect;",
"}"
].join("\n");
}
),
/***/
4127: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME PHASER_POINTLIGHT_FS",
"precision mediump float;",
"uniform vec2 uResolution;",
"uniform float uCameraZoom;",
"varying vec4 lightPosition;",
"varying vec4 lightColor;",
"varying float lightRadius;",
"varying float lightAttenuation;",
"void main ()",
"{",
" vec2 center = (lightPosition.xy + 1.0) * (uResolution.xy * 0.5);",
" float distToSurf = length(center - gl_FragCoord.xy);",
" float radius = 1.0 - distToSurf / (lightRadius * uCameraZoom);",
" float intensity = smoothstep(0.0, 1.0, radius * lightAttenuation);",
" vec4 color = vec4(intensity, intensity, intensity, 0.0) * lightColor;",
" gl_FragColor = vec4(color.rgb * lightColor.a, color.a);",
"}"
].join("\n");
}
),
/***/
89924: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME PHASER_POINTLIGHT_VS",
"precision mediump float;",
"uniform mat4 uProjectionMatrix;",
"attribute vec2 inPosition;",
"attribute vec2 inLightPosition;",
"attribute vec4 inLightColor;",
"attribute float inLightRadius;",
"attribute float inLightAttenuation;",
"varying vec4 lightPosition;",
"varying vec4 lightColor;",
"varying float lightRadius;",
"varying float lightAttenuation;",
"void main ()",
"{",
" lightColor = inLightColor;",
" lightRadius = inLightRadius;",
" lightAttenuation = inLightAttenuation;",
" lightPosition = uProjectionMatrix * vec4(inLightPosition, 1.0, 1.0);",
" gl_Position = uProjectionMatrix * vec4(inPosition, 1.0, 1.0);",
"}"
].join("\n");
}
),
/***/
27681: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME PHASER_POSTFX_FS",
"precision mediump float;",
"uniform sampler2D uMainSampler;",
"varying vec2 outTexCoord;",
"void main ()",
"{",
" gl_FragColor = texture2D(uMainSampler, outTexCoord);",
"}"
].join("\n");
}
),
/***/
49627: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME PHASER_QUAD_VS",
"precision mediump float;",
"attribute vec2 inPosition;",
"attribute vec2 inTexCoord;",
"varying vec2 outFragCoord;",
"varying vec2 outTexCoord;",
"void main ()",
"{",
" outFragCoord = inPosition.xy * 0.5 + 0.5;",
" outTexCoord = inTexCoord;",
" gl_Position = vec4(inPosition, 0, 1);",
"}"
].join("\n");
}
),
/***/
45561: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME PHASER_SINGLE_FS",
"#ifdef GL_FRAGMENT_PRECISION_HIGH",
"precision highp float;",
"#else",
"precision mediump float;",
"#endif",
"uniform sampler2D uMainSampler;",
"varying vec2 outTexCoord;",
"varying float outTintEffect;",
"varying vec4 outTint;",
"void main ()",
"{",
" vec4 texture = texture2D(uMainSampler, outTexCoord);",
" vec4 texel = vec4(outTint.bgr * outTint.a, outTint.a);",
" vec4 color = texture * texel;",
" if (outTintEffect == 1.0)",
" {",
" color.rgb = mix(texture.rgb, outTint.bgr * outTint.a, texture.a);",
" }",
" else if (outTintEffect == 2.0)",
" {",
" color = texel;",
" }",
" gl_FragColor = color;",
"}"
].join("\n");
}
),
/***/
60722: (
/***/
(module2) => {
module2.exports = [
"#define SHADER_NAME PHASER_SINGLE_VS",
"precision mediump float;",
"uniform mat4 uProjectionMatrix;",
"uniform vec2 uResolution;",
"attribute vec2 inPosition;",
"attribute vec2 inTexCoord;",
"attribute float inTexId;",
"attribute float inTintEffect;",
"attribute vec4 inTint;",
"varying vec2 outTexCoord;",
"varying float outTintEffect;",
"varying vec4 outTint;",
"void main ()",
"{",
" gl_Position = uProjectionMatrix * vec4(inPosition, 1.0, 1.0);",
" outTexCoord = inTexCoord;",
" outTint = inTint;",
" outTintEffect = inTintEffect;",
"}"
].join("\n");
}
),
/***/
89350: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
AddBlendFrag: __webpack_require__2(35407),
BitmapMaskFrag: __webpack_require__2(78908),
BitmapMaskVert: __webpack_require__2(85191),
ColorMatrixFrag: __webpack_require__2(96293),
CopyFrag: __webpack_require__2(36682),
FXBarrelFrag: __webpack_require__2(99155),
FXBloomFrag: __webpack_require__2(24400),
FXBlurHighFrag: __webpack_require__2(94328),
FXBlurLowFrag: __webpack_require__2(41514),
FXBlurMedFrag: __webpack_require__2(51078),
FXBokehFrag: __webpack_require__2(90610),
FXCircleFrag: __webpack_require__2(91899),
FXDisplacementFrag: __webpack_require__2(47838),
FXGlowFrag: __webpack_require__2(98656),
FXGradientFrag: __webpack_require__2(70463),
FXPixelateFrag: __webpack_require__2(50831),
FXShadowFrag: __webpack_require__2(92595),
FXShineFrag: __webpack_require__2(72464),
FXVignetteFrag: __webpack_require__2(39249),
FXWipeFrag: __webpack_require__2(2878),
LightFrag: __webpack_require__2(31063),
LinearBlendFrag: __webpack_require__2(48247),
MeshFrag: __webpack_require__2(41214),
MeshVert: __webpack_require__2(39653),
MobileFrag: __webpack_require__2(62143),
MobileVert: __webpack_require__2(47940),
MultiFrag: __webpack_require__2(98840),
MultiVert: __webpack_require__2(44667),
PointLightFrag: __webpack_require__2(4127),
PointLightVert: __webpack_require__2(89924),
PostFXFrag: __webpack_require__2(27681),
QuadVert: __webpack_require__2(49627),
SingleFrag: __webpack_require__2(45561),
SingleVert: __webpack_require__2(60722)
};
}
),
/***/
93567: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var WebGLAttribLocationWrapper = new Class({
initialize: function WebGLAttribLocationWrapper2(gl, program, name) {
this.webGLAttribLocation = -1;
this.gl = gl;
this.program = program;
this.name = name;
this.createResource();
},
/**
* Creates the WebGLAttribLocation.
*
* @method Phaser.Renderer.WebGL.Wrappers.WebGLAttribLocationWrapper#createResource
* @since 3.80.0
*/
createResource: function() {
if (this.program.webGLProgram === null) {
this.webGLAttribLocation = -1;
return;
}
var gl = this.gl;
if (gl.isContextLost()) {
return;
}
this.webGLAttribLocation = gl.getAttribLocation(this.program.webGLProgram, this.name);
},
/**
* Destroys this WebGLAttribLocationWrapper.
*
* @method Phaser.Renderer.WebGL.Wrappers.WebGLAttribLocationWrapper#destroy
* @since 3.80.0
*/
destroy: function() {
this.gl = null;
this.program = null;
this.name = null;
this.webGLAttribLocation = -1;
}
});
module2.exports = WebGLAttribLocationWrapper;
}
),
/***/
26128: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var WebGLBufferWrapper = new Class({
initialize: function WebGLBufferWrapper2(gl, initialDataOrSize, bufferType, bufferUsage) {
this.webGLBuffer = null;
this.gl = gl;
this.initialDataOrSize = initialDataOrSize;
this.bufferType = bufferType;
this.bufferUsage = bufferUsage;
this.createResource();
},
/**
* Creates a WebGLBuffer for this WebGLBufferWrapper.
*
* This is called automatically by the constructor. It may also be
* called again if the WebGLBuffer needs re-creating.
*
* @method Phaser.Renderer.WebGL.Wrappers.WebGLBufferWrapper#createResource
* @since 3.80.0
*/
createResource: function() {
if (this.initialDataOrSize === null) {
return;
}
var gl = this.gl;
if (gl.isContextLost()) {
return;
}
var bufferType = this.bufferType;
var webGLBuffer = gl.createBuffer();
this.webGLBuffer = webGLBuffer;
gl.bindBuffer(bufferType, this.webGLBuffer);
gl.bufferData(bufferType, this.initialDataOrSize, this.bufferUsage);
gl.bindBuffer(bufferType, null);
},
/**
* Remove this WebGLBufferWrapper from the GL context.
*
* @method Phaser.Renderer.WebGL.Wrappers.WebGLBufferWrapper#destroy
* @since 3.80.0
*/
destroy: function() {
var gl = this.gl;
if (!gl.isContextLost()) {
gl.deleteBuffer(this.webGLBuffer);
}
this.webGLBuffer = null;
this.initialDataOrSize = null;
this.gl = null;
}
});
module2.exports = WebGLBufferWrapper;
}
),
/***/
84387: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var errors = {
36054: "Incomplete Attachment",
36055: "Missing Attachment",
36057: "Incomplete Dimensions",
36061: "Framebuffer Unsupported"
};
var WebGLFramebufferWrapper = new Class({
initialize: function WebGLFramebufferWrapper2(gl, width, height, renderTexture, addDepthStencilBuffer) {
this.webGLFramebuffer = null;
this.gl = gl;
this.width = width;
this.height = height;
this.renderTexture = renderTexture;
this.addDepthStencilBuffer = !!addDepthStencilBuffer;
this.createResource();
},
/**
* Creates a WebGLFramebuffer from the given parameters.
*
* This is called automatically by the constructor. It may also be
* called again if the WebGLFramebuffer needs re-creating.
*
* @method Phaser.Renderer.WebGL.Wrappers.WebGLFramebufferWrapper#createResource
* @since 3.80.0
*/
createResource: function() {
var gl = this.gl;
if (gl.isContextLost()) {
return;
}
var renderTexture = this.renderTexture;
var complete = 0;
var framebuffer = gl.createFramebuffer();
this.webGLFramebuffer = framebuffer;
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
renderTexture.isRenderTexture = true;
renderTexture.isAlphaPremultiplied = false;
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, renderTexture.webGLTexture, 0);
complete = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
if (complete !== gl.FRAMEBUFFER_COMPLETE) {
throw new Error("Framebuffer status: " + (errors[complete] || complete));
}
if (this.addDepthStencilBuffer) {
var depthStencilBuffer = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, depthStencilBuffer);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, this.width, this.height);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, depthStencilBuffer);
}
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
},
/**
* Destroys this WebGLFramebufferWrapper.
*
* @method Phaser.Renderer.WebGL.Wrappers.WebGLFramebufferWrapper#destroy
* @since 3.80.0
*/
destroy: function() {
if (this.webGLFramebuffer === null) {
return;
}
var gl = this.gl;
if (!gl.isContextLost()) {
gl.bindFramebuffer(gl.FRAMEBUFFER, this.webGLFramebuffer);
var colorAttachment = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
if (colorAttachment !== null) {
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0);
gl.deleteTexture(colorAttachment);
}
var depthStencilAttachment = gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME);
if (depthStencilAttachment !== null) {
gl.deleteRenderbuffer(depthStencilAttachment);
}
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.deleteFramebuffer(this.webGLFramebuffer);
}
this.renderTexture = null;
this.webGLFramebuffer = null;
this.gl = null;
}
});
module2.exports = WebGLFramebufferWrapper;
}
),
/***/
1482: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var WebGLProgramWrapper = new Class({
initialize: function WebGLProgramWrapper2(gl, vertexSource, fragmentSource) {
this.webGLProgram = null;
this.gl = gl;
this.vertexSource = vertexSource;
this.fragmentSource = fragmentSource;
this.createResource();
},
/**
* Creates a WebGLProgram from the given vertex and fragment shaders.
*
* This is called automatically by the constructor. It may also be
* called again if the WebGLProgram needs re-creating.
*
* @method Phaser.Renderer.WebGL.Wrappers.WebGLProgramWrapper#createResource
* @throws {Error} If the shaders failed to compile or link.
* @since 3.80.0
*/
createResource: function() {
var gl = this.gl;
if (gl.isContextLost()) {
return;
}
var program = gl.createProgram();
var vs = gl.createShader(gl.VERTEX_SHADER);
var fs = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vs, this.vertexSource);
gl.shaderSource(fs, this.fragmentSource);
gl.compileShader(vs);
gl.compileShader(fs);
var failed = "Shader failed:\n";
if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) {
throw new Error("Vertex " + failed + gl.getShaderInfoLog(vs));
}
if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) {
throw new Error("Fragment " + failed + gl.getShaderInfoLog(fs));
}
gl.attachShader(program, vs);
gl.attachShader(program, fs);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
throw new Error("Link " + failed + gl.getProgramInfoLog(program));
}
gl.useProgram(program);
this.webGLProgram = program;
},
/**
* Remove this WebGLProgram from the GL context.
*
* @method Phaser.Renderer.WebGL.Wrappers.WebGLProgramWrapper#destroy
* @since 3.80.0
*/
destroy: function() {
if (!this.webGLProgram) {
return;
}
if (!this.gl.isContextLost()) {
this.gl.deleteProgram(this.webGLProgram);
}
this.webGLProgram = null;
this.gl = null;
}
});
module2.exports = WebGLProgramWrapper;
}
),
/***/
82751: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var IsSizePowerOfTwo = __webpack_require__2(50030);
var WebGLTextureWrapper = new Class({
initialize: function WebGLTextureWrapper2(gl, mipLevel, minFilter, magFilter, wrapT, wrapS, format, pixels, width, height, pma, forceSize, flipY) {
this.webGLTexture = null;
this.isRenderTexture = false;
this.gl = gl;
this.mipLevel = mipLevel;
this.minFilter = minFilter;
this.magFilter = magFilter;
this.wrapT = wrapT;
this.wrapS = wrapS;
this.format = format;
this.pixels = pixels;
this.width = width;
this.height = height;
this.pma = pma === void 0 || pma === null ? true : pma;
this.forceSize = !!forceSize;
this.flipY = !!flipY;
this.__SPECTOR_Metadata = {};
this.createResource();
},
/**
* Creates a WebGLTexture from the given parameters.
*
* This is called automatically by the constructor. It may also be
* called again if the WebGLTexture needs re-creating.
*
* @method Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper#createResource
* @since 3.80.0
*/
createResource: function() {
var gl = this.gl;
if (gl.isContextLost()) {
return;
}
if (this.pixels instanceof WebGLTextureWrapper) {
this.webGLTexture = this.pixels.webGLTexture;
return;
}
var texture = gl.createTexture();
texture.__SPECTOR_Metadata = this.__SPECTOR_Metadata;
this.webGLTexture = texture;
this._processTexture();
},
/**
* Updates the WebGLTexture from an updated source.
*
* This should only be used when the source is a Canvas or Video element.
*
* @method Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper#update
* @since 3.80.0
*
* @param {?object} source - The source to update the WebGLTexture with.
* @param {number} width - The new width of the WebGLTexture.
* @param {number} height - The new height of the WebGLTexture.
* @param {boolean} flipY - Should the WebGLTexture set `UNPACK_MULTIPLY_FLIP_Y`?
* @param {number} wrapS - The new wrapping mode for the WebGLTexture.
* @param {number} wrapT - The new wrapping mode for the WebGLTexture.
* @param {number} minFilter - The new minification filter for the WebGLTexture.
* @param {number} magFilter - The new magnification filter for the WebGLTexture.
* @param {number} format - The new format for the WebGLTexture.
*/
update: function(source, width, height, flipY, wrapS, wrapT, minFilter, magFilter, format) {
if (width === 0 || height === 0) {
return;
}
this.pixels = source;
this.width = width;
this.height = height;
this.flipY = flipY;
this.wrapS = wrapS;
this.wrapT = wrapT;
this.minFilter = minFilter;
this.magFilter = magFilter;
this.format = format;
var gl = this.gl;
if (gl.isContextLost()) {
return;
}
this._processTexture();
},
/**
* Set all parameters of this WebGLTexture per the stored values.
*
* @function Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper#_processTexture
* @protected
* @since 3.85.0
* @ignore
*/
_processTexture: function() {
var gl = this.gl;
gl.activeTexture(gl.TEXTURE0);
var currentTexture = gl.getParameter(gl.TEXTURE_BINDING_2D);
gl.bindTexture(gl.TEXTURE_2D, this.webGLTexture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, this.minFilter);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, this.magFilter);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, this.wrapS);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, this.wrapT);
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.pma);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, this.flipY);
var pixels = this.pixels;
var mipLevel = this.mipLevel;
var width = this.width;
var height = this.height;
var format = this.format;
var generateMipmap = false;
if (pixels === null || pixels === void 0) {
gl.texImage2D(gl.TEXTURE_2D, mipLevel, format, width, height, 0, format, gl.UNSIGNED_BYTE, null);
generateMipmap = IsSizePowerOfTwo(width, height);
} else if (pixels.compressed) {
width = pixels.width;
height = pixels.height;
generateMipmap = pixels.generateMipmap;
for (var i = 0; i < pixels.mipmaps.length; i++) {
gl.compressedTexImage2D(gl.TEXTURE_2D, i, pixels.internalFormat, pixels.mipmaps[i].width, pixels.mipmaps[i].height, 0, pixels.mipmaps[i].data);
}
} else if (pixels instanceof Uint8Array) {
gl.texImage2D(gl.TEXTURE_2D, mipLevel, format, width, height, 0, format, gl.UNSIGNED_BYTE, pixels);
generateMipmap = IsSizePowerOfTwo(width, height);
} else {
if (!this.forceSize) {
width = pixels.width;
height = pixels.height;
}
gl.texImage2D(gl.TEXTURE_2D, mipLevel, format, format, gl.UNSIGNED_BYTE, pixels);
generateMipmap = IsSizePowerOfTwo(width, height);
}
if (generateMipmap) {
gl.generateMipmap(gl.TEXTURE_2D);
}
if (currentTexture) {
gl.bindTexture(gl.TEXTURE_2D, currentTexture);
} else {
gl.bindTexture(gl.TEXTURE_2D, null);
}
},
/**
* The `__SPECTOR_Metadata` property of the `WebGLTexture`,
* used to add extra data to the debug SpectorJS integration.
*
* @name Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper#spectorMetadata
* @type {object}
* @since 3.80.0
*/
spectorMetadata: {
get: function() {
return this.__SPECTOR_Metadata;
},
set: function(value) {
this.__SPECTOR_Metadata = value;
if (!this.gl.isContextLost()) {
this.webGLTexture.__SPECTOR_Metadata = value;
}
}
},
/**
* Deletes the WebGLTexture from the GPU, if it has not been already.
*
* @method Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper#destroy
* @since 3.80.0
*/
destroy: function() {
if (this.webGLTexture === null) {
return;
}
if (!this.gl.isContextLost()) {
if (!(this.pixels instanceof WebGLTextureWrapper)) {
this.gl.deleteTexture(this.webGLTexture);
}
}
this.pixels = null;
this.webGLTexture = null;
this.gl = null;
}
});
module2.exports = WebGLTextureWrapper;
}
),
/***/
57183: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var WebGLUniformLocationWrapper = new Class({
initialize: function WebGLUniformLocationWrapper2(gl, program, name) {
this.webGLUniformLocation = null;
this.gl = gl;
this.program = program;
this.name = name;
this.createResource();
},
/**
* Creates the WebGLUniformLocation.
*
* @method Phaser.Renderer.WebGL.Wrappers.WebGLUniformLocationWrapper#createResource
* @since 3.80.0
*/
createResource: function() {
if (this.program.webGLProgram === null) {
this.webGLUniformLocation = null;
return;
}
var gl = this.gl;
if (gl.isContextLost()) {
return;
}
this.webGLUniformLocation = gl.getUniformLocation(this.program.webGLProgram, this.name);
},
/**
* Destroys this WebGLUniformLocationWrapper.
*
* @method Phaser.Renderer.WebGL.Wrappers.WebGLUniformLocationWrapper#destroy
* @since 3.80.0
*/
destroy: function() {
this.gl = null;
this.program = null;
this.name = null;
this.webGLUniformLocation = null;
}
});
module2.exports = WebGLUniformLocationWrapper;
}
),
/***/
9503: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Wrappers = {
WebGLAttribLocationWrapper: __webpack_require__2(93567),
WebGLBufferWrapper: __webpack_require__2(26128),
WebGLProgramWrapper: __webpack_require__2(1482),
WebGLTextureWrapper: __webpack_require__2(82751),
WebGLFramebufferWrapper: __webpack_require__2(84387),
WebGLUniformLocationWrapper: __webpack_require__2(57183)
};
module2.exports = Wrappers;
}
),
/***/
76531: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(13560);
var Class = __webpack_require__2(83419);
var EventEmitter = __webpack_require__2(50792);
var Events = __webpack_require__2(97480);
var GameEvents = __webpack_require__2(8443);
var GetInnerHeight = __webpack_require__2(57811);
var GetTarget = __webpack_require__2(74403);
var GetScreenOrientation = __webpack_require__2(45818);
var NOOP = __webpack_require__2(29747);
var Rectangle = __webpack_require__2(87841);
var Size = __webpack_require__2(86555);
var SnapFloor = __webpack_require__2(56583);
var Vector2 = __webpack_require__2(26099);
var Camera = __webpack_require__2(38058);
var ScaleManager = new Class({
Extends: EventEmitter,
initialize: function ScaleManager2(game) {
EventEmitter.call(this);
this.game = game;
this.canvas;
this.canvasBounds = new Rectangle();
this.parent = null;
this.parentIsWindow = false;
this.parentSize = new Size();
this.gameSize = new Size();
this.baseSize = new Size();
this.displaySize = new Size();
this.scaleMode = CONST.SCALE_MODE.NONE;
this.zoom = 1;
this._resetZoom = false;
this.displayScale = new Vector2(1, 1);
this.autoRound = false;
this.autoCenter = CONST.CENTER.NO_CENTER;
this.orientation = CONST.ORIENTATION.LANDSCAPE;
this.fullscreen;
this.fullscreenTarget = null;
this._createdFullscreenTarget = false;
this.dirty = false;
this.resizeInterval = 500;
this._lastCheck = 0;
this._checkOrientation = false;
this.domlisteners = {
orientationChange: NOOP,
windowResize: NOOP,
fullScreenChange: NOOP,
fullScreenError: NOOP
};
},
/**
* Called _before_ the canvas object is created and added to the DOM.
*
* @method Phaser.Scale.ScaleManager#preBoot
* @protected
* @listens Phaser.Core.Events#BOOT
* @since 3.16.0
*/
preBoot: function() {
this.parseConfig(this.game.config);
this.game.events.once(GameEvents.BOOT, this.boot, this);
},
/**
* The Boot handler is called by Phaser.Game when it first starts up.
* The renderer is available by now and the canvas has been added to the DOM.
*
* @method Phaser.Scale.ScaleManager#boot
* @protected
* @fires Phaser.Scale.Events#RESIZE
* @since 3.16.0
*/
boot: function() {
var game = this.game;
this.canvas = game.canvas;
this.fullscreen = game.device.fullscreen;
var scaleMode = this.scaleMode;
if (scaleMode !== CONST.SCALE_MODE.RESIZE && scaleMode !== CONST.SCALE_MODE.EXPAND) {
this.displaySize.setAspectMode(scaleMode);
}
if (scaleMode === CONST.SCALE_MODE.NONE) {
this.resize(this.width, this.height);
} else {
this.getParentBounds();
if (this.parentSize.width > 0 && this.parentSize.height > 0) {
this.displaySize.setParent(this.parentSize);
}
this.refresh();
}
game.events.on(GameEvents.PRE_STEP, this.step, this);
game.events.once(GameEvents.READY, this.refresh, this);
game.events.once(GameEvents.DESTROY, this.destroy, this);
this.startListeners();
},
/**
* Parses the game configuration to set-up the scale defaults.
*
* @method Phaser.Scale.ScaleManager#parseConfig
* @protected
* @since 3.16.0
*
* @param {Phaser.Types.Core.GameConfig} config - The Game configuration object.
*/
parseConfig: function(config) {
this.getParent(config);
this.getParentBounds();
var width = config.width;
var height = config.height;
var scaleMode = config.scaleMode;
var zoom = config.zoom;
var autoRound = config.autoRound;
if (typeof width === "string") {
if (width.substr(-1) !== "%") {
width = parseInt(width, 10);
} else {
var parentWidth = this.parentSize.width;
if (parentWidth === 0) {
parentWidth = window.innerWidth;
}
var parentScaleX = parseInt(width, 10) / 100;
width = Math.floor(parentWidth * parentScaleX);
}
}
if (typeof height === "string") {
if (height.substr(-1) !== "%") {
height = parseInt(height, 10);
} else {
var parentHeight = this.parentSize.height;
if (parentHeight === 0) {
parentHeight = window.innerHeight;
}
var parentScaleY = parseInt(height, 10) / 100;
height = Math.floor(parentHeight * parentScaleY);
}
}
this.scaleMode = scaleMode;
this.autoRound = autoRound;
this.autoCenter = config.autoCenter;
this.resizeInterval = config.resizeInterval;
if (autoRound) {
width = Math.floor(width);
height = Math.floor(height);
}
this.gameSize.setSize(width, height);
if (zoom === CONST.ZOOM.MAX_ZOOM) {
zoom = this.getMaxZoom();
}
this.zoom = zoom;
if (zoom !== 1) {
this._resetZoom = true;
}
this.baseSize.setSize(width, height);
if (autoRound) {
this.baseSize.width = Math.floor(this.baseSize.width);
this.baseSize.height = Math.floor(this.baseSize.height);
}
if (config.minWidth > 0) {
this.displaySize.setMin(config.minWidth * zoom, config.minHeight * zoom);
}
if (config.maxWidth > 0) {
this.displaySize.setMax(config.maxWidth * zoom, config.maxHeight * zoom);
}
this.displaySize.setSize(width, height);
if (config.snapWidth > 0 || config.snapHeight > 0) {
this.displaySize.setSnap(config.snapWidth, config.snapHeight);
}
this.orientation = GetScreenOrientation(width, height);
},
/**
* Determines the parent element of the game canvas, if any, based on the game configuration.
*
* @method Phaser.Scale.ScaleManager#getParent
* @since 3.16.0
*
* @param {Phaser.Types.Core.GameConfig} config - The Game configuration object.
*/
getParent: function(config) {
var parent = config.parent;
if (parent === null) {
return;
}
this.parent = GetTarget(parent);
this.parentIsWindow = this.parent === document.body;
if (config.expandParent && config.scaleMode !== CONST.SCALE_MODE.NONE) {
var DOMRect = this.parent.getBoundingClientRect();
if (this.parentIsWindow || DOMRect.height === 0) {
document.documentElement.style.height = "100%";
document.body.style.height = "100%";
DOMRect = this.parent.getBoundingClientRect();
if (!this.parentIsWindow && DOMRect.height === 0) {
this.parent.style.overflow = "hidden";
this.parent.style.width = "100%";
this.parent.style.height = "100%";
}
}
}
if (config.fullscreenTarget && !this.fullscreenTarget) {
this.fullscreenTarget = GetTarget(config.fullscreenTarget);
}
},
/**
* Calculates the size of the parent bounds and updates the `parentSize`
* properties, only if the canvas has a dom parent.
*
* @method Phaser.Scale.ScaleManager#getParentBounds
* @since 3.16.0
*
* @return {boolean} `true` if the parent bounds have changed size or position, otherwise `false`.
*/
getParentBounds: function() {
if (!this.parent) {
return false;
}
var parentSize = this.parentSize;
var DOMRect = this.parent.getBoundingClientRect();
if (this.parentIsWindow && this.game.device.os.iOS) {
DOMRect.height = GetInnerHeight(true);
}
var newWidth = DOMRect.width;
var newHeight = DOMRect.height;
if (parentSize.width !== newWidth || parentSize.height !== newHeight) {
parentSize.setSize(newWidth, newHeight);
return true;
} else if (this.canvas) {
var canvasBounds = this.canvasBounds;
var canvasRect = this.canvas.getBoundingClientRect();
if (canvasRect.x !== canvasBounds.x || canvasRect.y !== canvasBounds.y) {
return true;
}
}
return false;
},
/**
* Attempts to lock the orientation of the web browser using the Screen Orientation API.
*
* This API is only available on modern mobile browsers.
* See https://developer.mozilla.org/en-US/docs/Web/API/Screen/lockOrientation for details.
*
* @method Phaser.Scale.ScaleManager#lockOrientation
* @since 3.16.0
*
* @param {string} orientation - The orientation you'd like to lock the browser in. Should be an API string such as 'landscape', 'landscape-primary', 'portrait', etc.
*
* @return {boolean} `true` if the orientation was successfully locked, otherwise `false`.
*/
lockOrientation: function(orientation) {
var lock = screen.lockOrientation || screen.mozLockOrientation || screen.msLockOrientation;
if (lock) {
return lock.call(screen, orientation);
}
return false;
},
/**
* This method will set the size of the Parent Size component, which is used in scaling
* and centering calculations. You only need to call this method if you have explicitly
* disabled the use of a parent in your game config, but still wish to take advantage of
* other Scale Manager features.
*
* @method Phaser.Scale.ScaleManager#setParentSize
* @fires Phaser.Scale.Events#RESIZE
* @since 3.16.0
*
* @param {number} width - The new width of the parent.
* @param {number} height - The new height of the parent.
*
* @return {this} The Scale Manager instance.
*/
setParentSize: function(width, height) {
this.parentSize.setSize(width, height);
return this.refresh();
},
/**
* This method will set a new size for your game.
*
* It should only be used if you're looking to change the base size of your game and are using
* one of the Scale Manager scaling modes, i.e. `FIT`. If you're using `NONE` and wish to
* change the game and canvas size directly, then please use the `resize` method instead.
*
* @method Phaser.Scale.ScaleManager#setGameSize
* @fires Phaser.Scale.Events#RESIZE
* @since 3.16.0
*
* @param {number} width - The new width of the game.
* @param {number} height - The new height of the game.
*
* @return {this} The Scale Manager instance.
*/
setGameSize: function(width, height) {
var autoRound = this.autoRound;
if (autoRound) {
width = Math.floor(width);
height = Math.floor(height);
}
var previousWidth = this.width;
var previousHeight = this.height;
this.gameSize.resize(width, height);
this.baseSize.resize(width, height);
if (autoRound) {
this.baseSize.width = Math.floor(this.baseSize.width);
this.baseSize.height = Math.floor(this.baseSize.height);
}
this.displaySize.setAspectRatio(width / height);
this.canvas.width = this.baseSize.width;
this.canvas.height = this.baseSize.height;
return this.refresh(previousWidth, previousHeight);
},
/**
* Call this to modify the size of the Phaser canvas element directly.
* You should only use this if you are using the `NONE` scale mode,
* it will update all internal components completely.
*
* If all you want to do is change the size of the parent, see the `setParentSize` method.
*
* If all you want is to change the base size of the game, but still have the Scale Manager
* manage all the scaling (i.e. you're **not** using `NONE`), then see the `setGameSize` method.
*
* This method will set the `gameSize`, `baseSize` and `displaySize` components to the given
* dimensions. It will then resize the canvas width and height to the values given, by
* directly setting the properties. Finally, if you have set the Scale Manager zoom value
* to anything other than 1 (the default), it will set the canvas CSS width and height to
* be the given size multiplied by the zoom factor (the canvas pixel size remains untouched).
*
* If you have enabled `autoCenter`, it is then passed to the `updateCenter` method and
* the margins are set, allowing the canvas to be centered based on its parent element
* alone. Finally, the `displayScale` is adjusted and the RESIZE event dispatched.
*
* @method Phaser.Scale.ScaleManager#resize
* @fires Phaser.Scale.Events#RESIZE
* @since 3.16.0
*
* @param {number} width - The new width of the game.
* @param {number} height - The new height of the game.
*
* @return {this} The Scale Manager instance.
*/
resize: function(width, height) {
var zoom = this.zoom;
var autoRound = this.autoRound;
if (autoRound) {
width = Math.floor(width);
height = Math.floor(height);
}
var previousWidth = this.width;
var previousHeight = this.height;
this.gameSize.resize(width, height);
this.baseSize.resize(width, height);
if (autoRound) {
this.baseSize.width = Math.floor(this.baseSize.width);
this.baseSize.height = Math.floor(this.baseSize.height);
}
this.displaySize.setSize(width * zoom, height * zoom);
this.canvas.width = this.baseSize.width;
this.canvas.height = this.baseSize.height;
var style = this.canvas.style;
var styleWidth = width * zoom;
var styleHeight = height * zoom;
if (autoRound) {
styleWidth = Math.floor(styleWidth);
styleHeight = Math.floor(styleHeight);
}
if (styleWidth !== width || styleHeight !== height) {
style.width = styleWidth + "px";
style.height = styleHeight + "px";
}
return this.refresh(previousWidth, previousHeight);
},
/**
* Sets the zoom value of the Scale Manager.
*
* @method Phaser.Scale.ScaleManager#setZoom
* @fires Phaser.Scale.Events#RESIZE
* @since 3.16.0
*
* @param {number} value - The new zoom value of the game.
*
* @return {this} The Scale Manager instance.
*/
setZoom: function(value) {
this.zoom = value;
this._resetZoom = true;
return this.refresh();
},
/**
* Sets the zoom to be the maximum possible based on the _current_ parent size.
*
* @method Phaser.Scale.ScaleManager#setMaxZoom
* @fires Phaser.Scale.Events#RESIZE
* @since 3.16.0
*
* @return {this} The Scale Manager instance.
*/
setMaxZoom: function() {
this.zoom = this.getMaxZoom();
this._resetZoom = true;
return this.refresh();
},
/**
* By setting a Snap value, when the browser size is modified, its dimensions will automatically
* be snapped to the nearest grid slice, using floor. For example, if you have snap value of 16,
* and the width changes to 68, then it will snap down to 64 (the closest multiple of 16 when floored)
*
* This mode is best used with the `FIT` scale mode.
*
* Call this method with no arguments to reset the snap values.
*
* Calling this method automatically invokes `ScaleManager.refresh` which emits a `RESIZE` event.
*
* @method Phaser.Scale.ScaleManager#setSnap
* @fires Phaser.Scale.Events#RESIZE
* @since 3.80.0
*
* @param {number} [snapWidth=0] - The amount to snap the width to. If you don't want to snap the width, pass a value of zero.
* @param {number} [snapHeight=snapWidth] - The amount to snap the height to. If not provided it will use the `snapWidth` value. If you don't want to snap the height, pass a value of zero.
*
* @return {this} The Scale Manager instance.
*/
setSnap: function(snapWidth, snapHeight) {
if (snapWidth === void 0) {
snapWidth = 0;
}
if (snapHeight === void 0) {
snapHeight = snapWidth;
}
this.displaySize.setSnap(snapWidth, snapHeight);
return this.refresh();
},
/**
* Refreshes the internal scale values, bounds sizes and orientation checks.
*
* Once finished, dispatches the resize event.
*
* This is called automatically by the Scale Manager when the browser window size changes,
* as long as it is using a Scale Mode other than 'NONE'.
*
* @method Phaser.Scale.ScaleManager#refresh
* @fires Phaser.Scale.Events#RESIZE
* @since 3.16.0
*
* @param {number} [previousWidth] - The previous width of the game. Only set if the gameSize has changed.
* @param {number} [previousHeight] - The previous height of the game. Only set if the gameSize has changed.
*
* @return {this} The Scale Manager instance.
*/
refresh: function(previousWidth, previousHeight) {
if (previousWidth === void 0) {
previousWidth = this.width;
}
if (previousHeight === void 0) {
previousHeight = this.height;
}
this.updateScale();
this.updateBounds();
this.updateOrientation();
this.displayScale.set(this.baseSize.width / this.canvasBounds.width, this.baseSize.height / this.canvasBounds.height);
var domContainer = this.game.domContainer;
if (domContainer) {
this.baseSize.setCSS(domContainer);
var canvasStyle = this.canvas.style;
var domStyle = domContainer.style;
domStyle.transform = "scale(" + this.displaySize.width / this.baseSize.width + "," + this.displaySize.height / this.baseSize.height + ")";
domStyle.marginLeft = canvasStyle.marginLeft;
domStyle.marginTop = canvasStyle.marginTop;
}
this.emit(Events.RESIZE, this.gameSize, this.baseSize, this.displaySize, previousWidth, previousHeight);
return this;
},
/**
* Internal method that checks the current screen orientation, only if the internal check flag is set.
*
* If the orientation has changed it updates the orientation property and then dispatches the orientation change event.
*
* @method Phaser.Scale.ScaleManager#updateOrientation
* @fires Phaser.Scale.Events#ORIENTATION_CHANGE
* @since 3.16.0
*/
updateOrientation: function() {
if (this._checkOrientation) {
this._checkOrientation = false;
var newOrientation = GetScreenOrientation(this.width, this.height);
if (newOrientation !== this.orientation) {
this.orientation = newOrientation;
this.emit(Events.ORIENTATION_CHANGE, newOrientation);
}
}
},
/**
* Internal method that manages updating the size components based on the scale mode.
*
* @method Phaser.Scale.ScaleManager#updateScale
* @since 3.16.0
*/
updateScale: function() {
var style = this.canvas.style;
var width = this.gameSize.width;
var height = this.gameSize.height;
var styleWidth;
var styleHeight;
var zoom = this.zoom;
var autoRound = this.autoRound;
if (this.scaleMode === CONST.SCALE_MODE.NONE) {
this.displaySize.setSize(width * zoom, height * zoom);
styleWidth = this.displaySize.width;
styleHeight = this.displaySize.height;
if (autoRound) {
styleWidth = Math.floor(styleWidth);
styleHeight = Math.floor(styleHeight);
}
if (this._resetZoom) {
style.width = styleWidth + "px";
style.height = styleHeight + "px";
this._resetZoom = false;
}
} else if (this.scaleMode === CONST.SCALE_MODE.RESIZE) {
this.displaySize.setSize(this.parentSize.width, this.parentSize.height);
this.gameSize.setSize(this.displaySize.width, this.displaySize.height);
this.baseSize.setSize(this.displaySize.width, this.displaySize.height);
styleWidth = this.displaySize.width;
styleHeight = this.displaySize.height;
if (autoRound) {
styleWidth = Math.floor(styleWidth);
styleHeight = Math.floor(styleHeight);
}
this.canvas.width = styleWidth;
this.canvas.height = styleHeight;
} else if (this.scaleMode === CONST.SCALE_MODE.EXPAND) {
var baseWidth = this.game.config.width;
var baseHeight = this.game.config.height;
this.displaySize.setSize(this.parentSize.width, this.parentSize.height);
styleWidth = this.displaySize.width;
styleHeight = this.displaySize.height;
if (autoRound) {
styleWidth = Math.floor(styleWidth);
styleHeight = Math.floor(styleHeight);
}
style.width = styleWidth + "px";
style.height = styleHeight + "px";
var scaleX = this.parentSize.width / baseWidth;
var scaleY = this.parentSize.height / baseHeight;
if (scaleX < scaleY && scaleX !== 0) {
this.baseSize.setSize(baseWidth, this.parentSize.height / scaleX);
} else if (scaleY !== 0) {
this.baseSize.setSize(this.displaySize.width / scaleY, baseHeight);
}
this.gameSize.setSize(this.baseSize.width, this.baseSize.height);
styleWidth = this.baseSize.width;
styleHeight = this.baseSize.height;
if (autoRound) {
styleWidth = Math.floor(styleWidth);
styleHeight = Math.floor(styleHeight);
}
this.canvas.width = styleWidth;
this.canvas.height = styleHeight;
} else {
this.displaySize.setSize(this.parentSize.width, this.parentSize.height);
styleWidth = this.displaySize.width;
styleHeight = this.displaySize.height;
if (autoRound) {
styleWidth = Math.floor(styleWidth);
styleHeight = Math.floor(styleHeight);
}
style.width = styleWidth + "px";
style.height = styleHeight + "px";
}
this.getParentBounds();
this.updateCenter();
},
/**
* Calculates and returns the largest possible zoom factor, based on the current
* parent and game sizes. If the parent has no dimensions (i.e. an unstyled div),
* or is smaller than the un-zoomed game, then this will return a value of 1 (no zoom)
*
* @method Phaser.Scale.ScaleManager#getMaxZoom
* @since 3.16.0
*
* @return {number} The maximum possible zoom factor. At a minimum this value is always at least 1.
*/
getMaxZoom: function() {
var zoomH = SnapFloor(this.parentSize.width, this.gameSize.width, 0, true);
var zoomV = SnapFloor(this.parentSize.height, this.gameSize.height, 0, true);
return Math.max(Math.min(zoomH, zoomV), 1);
},
/**
* Calculates and updates the canvas CSS style in order to center it within the
* bounds of its parent. If you have explicitly set parent to be `null` in your
* game config then this method will likely give incorrect results unless you have called the
* `setParentSize` method first.
*
* It works by modifying the canvas CSS `marginLeft` and `marginTop` properties.
*
* If they have already been set by your own style sheet, or code, this will overwrite them.
*
* To prevent the Scale Manager from centering the canvas, either do not set the
* `autoCenter` property in your game config, or make sure it is set to `NO_CENTER`.
*
* @method Phaser.Scale.ScaleManager#updateCenter
* @since 3.16.0
*/
updateCenter: function() {
var autoCenter = this.autoCenter;
if (autoCenter === CONST.CENTER.NO_CENTER) {
return;
}
var canvas = this.canvas;
var style = canvas.style;
var bounds = canvas.getBoundingClientRect();
var width = bounds.width;
var height = bounds.height;
var offsetX = Math.floor((this.parentSize.width - width) / 2);
var offsetY = Math.floor((this.parentSize.height - height) / 2);
if (autoCenter === CONST.CENTER.CENTER_HORIZONTALLY) {
offsetY = 0;
} else if (autoCenter === CONST.CENTER.CENTER_VERTICALLY) {
offsetX = 0;
}
style.marginLeft = offsetX + "px";
style.marginTop = offsetY + "px";
},
/**
* Updates the `canvasBounds` rectangle to match the bounding client rectangle of the
* canvas element being used to track input events.
*
* @method Phaser.Scale.ScaleManager#updateBounds
* @since 3.16.0
*/
updateBounds: function() {
var bounds = this.canvasBounds;
var clientRect = this.canvas.getBoundingClientRect();
bounds.x = clientRect.left + (window.pageXOffset || 0) - (document.documentElement.clientLeft || 0);
bounds.y = clientRect.top + (window.pageYOffset || 0) - (document.documentElement.clientTop || 0);
bounds.width = clientRect.width;
bounds.height = clientRect.height;
},
/**
* Transforms the pageX value into the scaled coordinate space of the Scale Manager.
*
* @method Phaser.Scale.ScaleManager#transformX
* @since 3.16.0
*
* @param {number} pageX - The DOM pageX value.
*
* @return {number} The translated value.
*/
transformX: function(pageX) {
return (pageX - this.canvasBounds.left) * this.displayScale.x;
},
/**
* Transforms the pageY value into the scaled coordinate space of the Scale Manager.
*
* @method Phaser.Scale.ScaleManager#transformY
* @since 3.16.0
*
* @param {number} pageY - The DOM pageY value.
*
* @return {number} The translated value.
*/
transformY: function(pageY) {
return (pageY - this.canvasBounds.top) * this.displayScale.y;
},
/**
* Sends a request to the browser to ask it to go in to full screen mode, using the {@link https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API Fullscreen API}.
*
* If the browser does not support this, a `FULLSCREEN_UNSUPPORTED` event will be emitted.
*
* This method _must_ be called from a `pointerup` user-input gesture (**not** `pointerdown`). You cannot launch
* games fullscreen without this, as most browsers block it. Games within an iframe will also be blocked
* from fullscreen unless the iframe has the `allowfullscreen` attribute.
*
* On touch devices, such as Android and iOS Safari, you should always use `pointerup` and NOT `pointerdown`,
* otherwise the request will fail unless the document in which your game is embedded has already received
* some form of touch input, which you cannot guarantee. Activating fullscreen via `pointerup` circumvents
* this issue.
*
* Performing an action that navigates to another page, or opens another tab, will automatically cancel
* fullscreen mode, as will the user pressing the ESC key. To cancel fullscreen mode directly from your game,
* i.e. by clicking an icon, call the `stopFullscreen` method.
*
* A browser can only send one DOM element into fullscreen. You can control which element this is by
* setting the `fullscreenTarget` property in your game config, or changing the property in the Scale Manager.
* Note that the game canvas _must_ be a child of the target. If you do not give a target, Phaser will
* automatically create a blank `<div>` element and move the canvas into it, before going fullscreen.
* When it leaves fullscreen, the div will be removed.
*
* @method Phaser.Scale.ScaleManager#startFullscreen
* @fires Phaser.Scale.Events#ENTER_FULLSCREEN
* @fires Phaser.Scale.Events#FULLSCREEN_FAILED
* @fires Phaser.Scale.Events#FULLSCREEN_UNSUPPORTED
* @fires Phaser.Scale.Events#RESIZE
* @since 3.16.0
*
* @param {object} [fullscreenOptions] - The FullscreenOptions dictionary is used to provide configuration options when entering full screen.
*/
startFullscreen: function(fullscreenOptions) {
if (fullscreenOptions === void 0) {
fullscreenOptions = { navigationUI: "hide" };
}
var fullscreen = this.fullscreen;
if (!fullscreen.available) {
this.emit(Events.FULLSCREEN_UNSUPPORTED);
return;
}
if (!fullscreen.active) {
var fsTarget = this.getFullscreenTarget();
if (fullscreen.keyboard) {
fsTarget[fullscreen.request](Element.ALLOW_KEYBOARD_INPUT);
} else {
fsTarget[fullscreen.request](fullscreenOptions);
}
}
},
/**
* The browser has successfully entered fullscreen mode.
*
* @method Phaser.Scale.ScaleManager#fullscreenSuccessHandler
* @private
* @fires Phaser.Scale.Events#ENTER_FULLSCREEN
* @fires Phaser.Scale.Events#RESIZE
* @since 3.17.0
*/
fullscreenSuccessHandler: function() {
this.getParentBounds();
this.refresh();
this.emit(Events.ENTER_FULLSCREEN);
},
/**
* The browser failed to enter fullscreen mode.
*
* @method Phaser.Scale.ScaleManager#fullscreenErrorHandler
* @private
* @fires Phaser.Scale.Events#FULLSCREEN_FAILED
* @fires Phaser.Scale.Events#RESIZE
* @since 3.17.0
*
* @param {any} error - The DOM error event.
*/
fullscreenErrorHandler: function(error) {
this.removeFullscreenTarget();
this.emit(Events.FULLSCREEN_FAILED, error);
},
/**
* An internal method that gets the target element that is used when entering fullscreen mode.
*
* @method Phaser.Scale.ScaleManager#getFullscreenTarget
* @since 3.16.0
*
* @return {object} The fullscreen target element.
*/
getFullscreenTarget: function() {
if (!this.fullscreenTarget) {
var fsTarget = document.createElement("div");
fsTarget.style.margin = "0";
fsTarget.style.padding = "0";
fsTarget.style.width = "100%";
fsTarget.style.height = "100%";
this.fullscreenTarget = fsTarget;
this._createdFullscreenTarget = true;
}
if (this._createdFullscreenTarget) {
var canvasParent = this.canvas.parentNode;
canvasParent.insertBefore(this.fullscreenTarget, this.canvas);
this.fullscreenTarget.appendChild(this.canvas);
}
return this.fullscreenTarget;
},
/**
* Removes the fullscreen target that was added to the DOM.
*
* @method Phaser.Scale.ScaleManager#removeFullscreenTarget
* @since 3.17.0
*/
removeFullscreenTarget: function() {
if (this._createdFullscreenTarget) {
var fsTarget = this.fullscreenTarget;
if (fsTarget && fsTarget.parentNode) {
var parent = fsTarget.parentNode;
parent.insertBefore(this.canvas, fsTarget);
parent.removeChild(fsTarget);
}
}
},
/**
* Calling this method will cancel fullscreen mode, if the browser has entered it.
*
* @method Phaser.Scale.ScaleManager#stopFullscreen
* @fires Phaser.Scale.Events#FULLSCREEN_UNSUPPORTED
* @since 3.16.0
*/
stopFullscreen: function() {
var fullscreen = this.fullscreen;
if (!fullscreen.available) {
this.emit(Events.FULLSCREEN_UNSUPPORTED);
return false;
}
if (fullscreen.active) {
document[fullscreen.cancel]();
}
this.removeFullscreenTarget();
},
/**
* The browser has successfully left fullscreen mode.
*
* @method Phaser.Scale.ScaleManager#leaveFullScreenSuccessHandler
* @fires Phaser.Scale.Events#LEAVE_FULLSCREEN
* @since 3.85.0
*/
leaveFullScreenSuccessHandler: function() {
this.getParentBounds();
this.emit(Events.LEAVE_FULLSCREEN);
this.refresh();
},
/**
* Toggles the fullscreen mode. If already in fullscreen, calling this will cancel it.
* If not in fullscreen, this will request the browser to enter fullscreen mode.
*
* If the browser does not support this, a `FULLSCREEN_UNSUPPORTED` event will be emitted.
*
* This method _must_ be called from a user-input gesture, such as `pointerdown`. You cannot launch
* games fullscreen without this, as most browsers block it. Games within an iframe will also be blocked
* from fullscreen unless the iframe has the `allowfullscreen` attribute.
*
* @method Phaser.Scale.ScaleManager#toggleFullscreen
* @fires Phaser.Scale.Events#ENTER_FULLSCREEN
* @fires Phaser.Scale.Events#LEAVE_FULLSCREEN
* @fires Phaser.Scale.Events#FULLSCREEN_UNSUPPORTED
* @fires Phaser.Scale.Events#RESIZE
* @since 3.16.0
*
* @param {object} [fullscreenOptions] - The FullscreenOptions dictionary is used to provide configuration options when entering full screen.
*/
toggleFullscreen: function(fullscreenOptions) {
if (this.fullscreen.active) {
this.stopFullscreen();
} else {
this.startFullscreen(fullscreenOptions);
}
},
/**
* An internal method that starts the different DOM event listeners running.
*
* @method Phaser.Scale.ScaleManager#startListeners
* @since 3.16.0
*/
startListeners: function() {
var _this = this;
var listeners = this.domlisteners;
listeners.orientationChange = function() {
_this.updateBounds();
_this._checkOrientation = true;
_this.dirty = true;
_this.refresh();
};
listeners.windowResize = function() {
_this.updateBounds();
_this.dirty = true;
};
if (screen.orientation && screen.orientation.addEventListener) {
screen.orientation.addEventListener("change", listeners.orientationChange, false);
} else {
window.addEventListener("orientationchange", listeners.orientationChange, false);
}
window.addEventListener("resize", listeners.windowResize, false);
if (this.fullscreen.available) {
listeners.fullScreenChange = function(event) {
return _this.onFullScreenChange(event);
};
listeners.fullScreenError = function(event) {
return _this.onFullScreenError(event);
};
var vendors = ["webkit", "moz", ""];
vendors.forEach(function(prefix) {
document.addEventListener(prefix + "fullscreenchange", listeners.fullScreenChange, false);
document.addEventListener(prefix + "fullscreenerror", listeners.fullScreenError, false);
});
document.addEventListener("MSFullscreenChange", listeners.fullScreenChange, false);
document.addEventListener("MSFullscreenError", listeners.fullScreenError, false);
}
},
/**
* Triggered when a fullscreenchange event is dispatched by the DOM.
*
* @method Phaser.Scale.ScaleManager#onFullScreenChange
* @protected
* @since 3.16.0
*/
onFullScreenChange: function() {
if (document.fullscreenElement || document.webkitFullscreenElement || document.msFullscreenElement || document.mozFullScreenElement) {
this.fullscreenSuccessHandler();
} else {
this.stopFullscreen();
this.leaveFullScreenSuccessHandler();
}
},
/**
* Triggered when a fullscreenerror event is dispatched by the DOM.
*
* @method Phaser.Scale.ScaleManager#onFullScreenError
* @since 3.16.0
*/
onFullScreenError: function() {
this.removeFullscreenTarget();
},
/**
* Get Rectange of visible area.
*
* @method Phaser.Scale.ScaleManager#getViewPort
* @since 3.60.0
*
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The camera this viewport is respond upon.
* @param {Phaser.Geom.Rectangle} [out] - The Rectangle of visible area.
*
* @return {Phaser.Geom.Rectangle} The Rectangle of visible area.
*/
getViewPort: function(camera, out) {
if (!(camera instanceof Camera)) {
out = camera;
camera = void 0;
}
if (out === void 0) {
out = new Rectangle();
}
var baseSize = this.baseSize;
var parentSize = this.parentSize;
var canvasBounds = this.canvasBounds;
var displayScale = this.displayScale;
var x = canvasBounds.x >= 0 ? 0 : -(canvasBounds.x * displayScale.x);
var y = canvasBounds.y >= 0 ? 0 : -(canvasBounds.y * displayScale.y);
var width;
if (parentSize.width >= canvasBounds.width) {
width = baseSize.width;
} else {
width = baseSize.width - (canvasBounds.width - parentSize.width) * displayScale.x;
}
var height;
if (parentSize.height >= canvasBounds.height) {
height = baseSize.height;
} else {
height = baseSize.height - (canvasBounds.height - parentSize.height) * displayScale.y;
}
out.setTo(x, y, width, height);
if (camera) {
out.width /= camera.zoomX;
out.height /= camera.zoomY;
out.centerX = camera.centerX + camera.scrollX;
out.centerY = camera.centerY + camera.scrollY;
}
return out;
},
/**
* Internal method, called automatically by the game step.
* Monitors the elapsed time and resize interval to see if a parent bounds check needs to take place.
*
* @method Phaser.Scale.ScaleManager#step
* @since 3.16.0
*
* @param {number} time - The time value from the most recent Game step. Typically a high-resolution timer value, or Date.now().
* @param {number} delta - The delta value since the last frame. This is smoothed to avoid delta spikes by the TimeStep class.
*/
step: function(time, delta) {
if (!this.parent) {
return;
}
this._lastCheck += delta;
if (this.dirty || this._lastCheck > this.resizeInterval) {
if (this.getParentBounds()) {
this.refresh();
}
this.dirty = false;
this._lastCheck = 0;
}
},
/**
* Stops all DOM event listeners.
*
* @method Phaser.Scale.ScaleManager#stopListeners
* @since 3.16.0
*/
stopListeners: function() {
var listeners = this.domlisteners;
if (screen.orientation && screen.orientation.addEventListener) {
screen.orientation.removeEventListener("change", listeners.orientationChange, false);
} else {
window.removeEventListener("orientationchange", listeners.orientationChange, false);
}
window.removeEventListener("resize", listeners.windowResize, false);
var vendors = ["webkit", "moz", ""];
vendors.forEach(function(prefix) {
document.removeEventListener(prefix + "fullscreenchange", listeners.fullScreenChange, false);
document.removeEventListener(prefix + "fullscreenerror", listeners.fullScreenError, false);
});
document.removeEventListener("MSFullscreenChange", listeners.fullScreenChange, false);
document.removeEventListener("MSFullscreenError", listeners.fullScreenError, false);
},
/**
* Destroys this Scale Manager, releasing all references to external resources.
* Once destroyed, the Scale Manager cannot be used again.
*
* @method Phaser.Scale.ScaleManager#destroy
* @since 3.16.0
*/
destroy: function() {
this.removeAllListeners();
this.stopListeners();
this.game = null;
this.canvas = null;
this.canvasBounds = null;
this.parent = null;
this.fullscreenTarget = null;
this.parentSize.destroy();
this.gameSize.destroy();
this.baseSize.destroy();
this.displaySize.destroy();
},
/**
* Is the browser currently in fullscreen mode or not?
*
* @name Phaser.Scale.ScaleManager#isFullscreen
* @type {boolean}
* @readonly
* @since 3.16.0
*/
isFullscreen: {
get: function() {
return this.fullscreen.active;
}
},
/**
* The game width.
*
* This is typically the size given in the game configuration.
*
* @name Phaser.Scale.ScaleManager#width
* @type {number}
* @readonly
* @since 3.16.0
*/
width: {
get: function() {
return this.gameSize.width;
}
},
/**
* The game height.
*
* This is typically the size given in the game configuration.
*
* @name Phaser.Scale.ScaleManager#height
* @type {number}
* @readonly
* @since 3.16.0
*/
height: {
get: function() {
return this.gameSize.height;
}
},
/**
* Is the device in a portrait orientation as reported by the Orientation API?
* This value is usually only available on mobile devices.
*
* @name Phaser.Scale.ScaleManager#isPortrait
* @type {boolean}
* @readonly
* @since 3.16.0
*/
isPortrait: {
get: function() {
return this.orientation === CONST.ORIENTATION.PORTRAIT;
}
},
/**
* Is the device in a landscape orientation as reported by the Orientation API?
* This value is usually only available on mobile devices.
*
* @name Phaser.Scale.ScaleManager#isLandscape
* @type {boolean}
* @readonly
* @since 3.16.0
*/
isLandscape: {
get: function() {
return this.orientation === CONST.ORIENTATION.LANDSCAPE;
}
},
/**
* Are the game dimensions portrait? (i.e. taller than they are wide)
*
* This is different to the device itself being in a portrait orientation.
*
* @name Phaser.Scale.ScaleManager#isGamePortrait
* @type {boolean}
* @readonly
* @since 3.16.0
*/
isGamePortrait: {
get: function() {
return this.height > this.width;
}
},
/**
* Are the game dimensions landscape? (i.e. wider than they are tall)
*
* This is different to the device itself being in a landscape orientation.
*
* @name Phaser.Scale.ScaleManager#isGameLandscape
* @type {boolean}
* @readonly
* @since 3.16.0
*/
isGameLandscape: {
get: function() {
return this.width > this.height;
}
}
});
module2.exports = ScaleManager;
}
),
/***/
64743: (
/***/
(module2) => {
module2.exports = {
/**
* The game canvas is not centered within the parent by Phaser.
* You can still center it yourself via CSS.
*
* @name Phaser.Scale.Center.NO_CENTER
* @type {number}
* @const
* @since 3.16.0
*/
NO_CENTER: 0,
/**
* The game canvas is centered both horizontally and vertically within the parent.
* To do this, the parent has to have a bounds that can be calculated and not be empty.
*
* Centering is achieved by setting the margin left and top properties of the
* game canvas, and does not factor in any other CSS styles you may have applied.
*
* @name Phaser.Scale.Center.CENTER_BOTH
* @type {number}
* @const
* @since 3.16.0
*/
CENTER_BOTH: 1,
/**
* The game canvas is centered horizontally within the parent.
* To do this, the parent has to have a bounds that can be calculated and not be empty.
*
* Centering is achieved by setting the margin left and top properties of the
* game canvas, and does not factor in any other CSS styles you may have applied.
*
* @name Phaser.Scale.Center.CENTER_HORIZONTALLY
* @type {number}
* @const
* @since 3.16.0
*/
CENTER_HORIZONTALLY: 2,
/**
* The game canvas is centered both vertically within the parent.
* To do this, the parent has to have a bounds that can be calculated and not be empty.
*
* Centering is achieved by setting the margin left and top properties of the
* game canvas, and does not factor in any other CSS styles you may have applied.
*
* @name Phaser.Scale.Center.CENTER_VERTICALLY
* @type {number}
* @const
* @since 3.16.0
*/
CENTER_VERTICALLY: 3
};
}
),
/***/
39218: (
/***/
(module2) => {
module2.exports = {
/**
* The primary landscape orientation.
*
* @name Phaser.Scale.Orientation.LANDSCAPE
* @type {string}
* @const
* @since 3.16.0
*/
LANDSCAPE: "landscape-primary",
/**
* The secondary landscape orientation.
*
* @name Phaser.Scale.Orientation.LANDSCAPE_SECONDARY
* @type {string}
* @const
* @since 3.85.0
*/
LANDSCAPE_SECONDARY: "landscape-secondary",
/**
* The primary portrait orientation.
*
* @name Phaser.Scale.Orientation.PORTRAIT
* @type {string}
* @const
* @since 3.16.0
*/
PORTRAIT: "portrait-primary",
/**
* The secondary portrait orientation.
*
* @name Phaser.Scale.Orientation.PORTRAIT_SECONDARY
* @type {string}
* @const
* @since 3.16.0
*/
PORTRAIT_SECONDARY: "portrait-secondary"
};
}
),
/***/
81050: (
/***/
(module2) => {
module2.exports = {
/**
* No scaling happens at all. The canvas is set to the size given in the game config and Phaser doesn't change it
* again from that point on. If you change the canvas size, either via CSS, or directly via code, then you need
* to call the Scale Managers `resize` method to give the new dimensions, or input events will stop working.
*
* @name Phaser.Scale.ScaleModes.NONE
* @type {number}
* @const
* @since 3.16.0
*/
NONE: 0,
/**
* The height is automatically adjusted based on the width.
*
* @name Phaser.Scale.ScaleModes.WIDTH_CONTROLS_HEIGHT
* @type {number}
* @const
* @since 3.16.0
*/
WIDTH_CONTROLS_HEIGHT: 1,
/**
* The width is automatically adjusted based on the height.
*
* @name Phaser.Scale.ScaleModes.HEIGHT_CONTROLS_WIDTH
* @type {number}
* @const
* @since 3.16.0
*/
HEIGHT_CONTROLS_WIDTH: 2,
/**
* The width and height are automatically adjusted to fit inside the given target area,
* while keeping the aspect ratio. Depending on the aspect ratio there may be some space
* inside the area which is not covered.
*
* @name Phaser.Scale.ScaleModes.FIT
* @type {number}
* @const
* @since 3.16.0
*/
FIT: 3,
/**
* The width and height are automatically adjusted to make the size cover the entire target
* area while keeping the aspect ratio. This may extend further out than the target size.
*
* @name Phaser.Scale.ScaleModes.ENVELOP
* @type {number}
* @const
* @since 3.16.0
*/
ENVELOP: 4,
/**
* The Canvas is resized to fit all available _parent_ space, regardless of aspect ratio.
*
* @name Phaser.Scale.ScaleModes.RESIZE
* @type {number}
* @const
* @since 3.16.0
*/
RESIZE: 5,
/**
* The Canvas's visible area is resized to fit all available _parent_ space like RESIZE mode,
* and scale canvas size to fit inside the visible area like FIT mode.
*
* @name Phaser.Scale.ScaleModes.EXPAND
* @type {number}
* @const
* @since 3.80.0
*/
EXPAND: 6
};
}
),
/***/
80805: (
/***/
(module2) => {
module2.exports = {
/**
* The game canvas will not be zoomed by Phaser.
*
* @name Phaser.Scale.Zoom.NO_ZOOM
* @type {number}
* @const
* @since 3.16.0
*/
NO_ZOOM: 1,
/**
* The game canvas will be 2x zoomed by Phaser.
*
* @name Phaser.Scale.Zoom.ZOOM_2X
* @type {number}
* @const
* @since 3.16.0
*/
ZOOM_2X: 2,
/**
* The game canvas will be 4x zoomed by Phaser.
*
* @name Phaser.Scale.Zoom.ZOOM_4X
* @type {number}
* @const
* @since 3.16.0
*/
ZOOM_4X: 4,
/**
* Calculate the zoom value based on the maximum multiplied game size that will
* fit into the parent, or browser window if no parent is set.
*
* @name Phaser.Scale.Zoom.MAX_ZOOM
* @type {number}
* @const
* @since 3.16.0
*/
MAX_ZOOM: -1
};
}
),
/***/
13560: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = {
CENTER: __webpack_require__2(64743),
ORIENTATION: __webpack_require__2(39218),
SCALE_MODE: __webpack_require__2(81050),
ZOOM: __webpack_require__2(80805)
};
module2.exports = CONST;
}
),
/***/
56139: (
/***/
(module2) => {
module2.exports = "enterfullscreen";
}
),
/***/
2336: (
/***/
(module2) => {
module2.exports = "fullscreenfailed";
}
),
/***/
47412: (
/***/
(module2) => {
module2.exports = "fullscreenunsupported";
}
),
/***/
51452: (
/***/
(module2) => {
module2.exports = "leavefullscreen";
}
),
/***/
20666: (
/***/
(module2) => {
module2.exports = "orientationchange";
}
),
/***/
47945: (
/***/
(module2) => {
module2.exports = "resize";
}
),
/***/
97480: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
ENTER_FULLSCREEN: __webpack_require__2(56139),
FULLSCREEN_FAILED: __webpack_require__2(2336),
FULLSCREEN_UNSUPPORTED: __webpack_require__2(47412),
LEAVE_FULLSCREEN: __webpack_require__2(51452),
ORIENTATION_CHANGE: __webpack_require__2(20666),
RESIZE: __webpack_require__2(47945)
};
}
),
/***/
93364: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Extend = __webpack_require__2(79291);
var CONST = __webpack_require__2(13560);
var Scale = {
Center: __webpack_require__2(64743),
Events: __webpack_require__2(97480),
Orientation: __webpack_require__2(39218),
ScaleManager: __webpack_require__2(76531),
ScaleModes: __webpack_require__2(81050),
Zoom: __webpack_require__2(80805)
};
Scale = Extend(false, Scale, CONST.CENTER);
Scale = Extend(false, Scale, CONST.ORIENTATION);
Scale = Extend(false, Scale, CONST.SCALE_MODE);
Scale = Extend(false, Scale, CONST.ZOOM);
module2.exports = Scale;
}
),
/***/
27397: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetFastValue = __webpack_require__2(95540);
var UppercaseFirst = __webpack_require__2(35355);
var GetPhysicsPlugins = function(sys) {
var defaultSystem = sys.game.config.defaultPhysicsSystem;
var sceneSystems = GetFastValue(sys.settings, "physics", false);
if (!defaultSystem && !sceneSystems) {
return;
}
var output = [];
if (defaultSystem) {
output.push(UppercaseFirst(defaultSystem + "Physics"));
}
if (sceneSystems) {
for (var key in sceneSystems) {
key = UppercaseFirst(key.concat("Physics"));
if (output.indexOf(key) === -1) {
output.push(key);
}
}
}
return output;
};
module2.exports = GetPhysicsPlugins;
}
),
/***/
52106: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetFastValue = __webpack_require__2(95540);
var GetScenePlugins = function(sys) {
var defaultPlugins = sys.plugins.getDefaultScenePlugins();
var scenePlugins = GetFastValue(sys.settings, "plugins", false);
if (Array.isArray(scenePlugins)) {
return scenePlugins;
} else if (defaultPlugins) {
return defaultPlugins;
} else {
return [];
}
};
module2.exports = GetScenePlugins;
}
),
/***/
87033: (
/***/
(module2) => {
var InjectionMap = {
game: "game",
renderer: "renderer",
anims: "anims",
cache: "cache",
plugins: "plugins",
registry: "registry",
scale: "scale",
sound: "sound",
textures: "textures",
events: "events",
cameras: "cameras",
add: "add",
make: "make",
scenePlugin: "scene",
displayList: "children",
lights: "lights",
data: "data",
input: "input",
load: "load",
time: "time",
tweens: "tweens",
arcadePhysics: "physics",
impactPhysics: "impact",
matterPhysics: "matter"
};
if (false) {
}
if (false) {
}
module2.exports = InjectionMap;
}
),
/***/
97482: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Systems = __webpack_require__2(2368);
var Scene = new Class({
initialize: function Scene2(config) {
this.sys = new Systems(this, config);
this.game;
this.anims;
this.cache;
this.registry;
this.sound;
this.textures;
this.events;
this.cameras;
this.add;
this.make;
this.scene;
this.children;
this.lights;
this.data;
this.input;
this.load;
this.time;
this.tweens;
this.physics;
this.matter;
if (false) {
}
this.scale;
this.plugins;
this.renderer;
},
/**
* This method should be overridden by your own Scenes.
*
* This method is called once per game step while the scene is running.
*
* @method Phaser.Scene#update
* @since 3.0.0
*
* @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout.
* @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
*/
update: function() {
}
});
module2.exports = Scene;
}
),
/***/
60903: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(89993);
var Events = __webpack_require__2(44594);
var GameEvents = __webpack_require__2(8443);
var GetValue = __webpack_require__2(35154);
var LoaderEvents = __webpack_require__2(54899);
var NOOP = __webpack_require__2(29747);
var Scene = __webpack_require__2(97482);
var Systems = __webpack_require__2(2368);
var SceneManager = new Class({
initialize: function SceneManager2(game, sceneConfig) {
this.game = game;
this.keys = {};
this.scenes = [];
this._pending = [];
this._start = [];
this._queue = [];
this._data = {};
this.isProcessing = false;
this.isBooted = false;
this.customViewports = 0;
this.systemScene;
if (sceneConfig) {
if (!Array.isArray(sceneConfig)) {
sceneConfig = [sceneConfig];
}
for (var i = 0; i < sceneConfig.length; i++) {
this._pending.push({
key: "default",
scene: sceneConfig[i],
autoStart: i === 0,
data: {}
});
}
}
game.events.once(GameEvents.READY, this.bootQueue, this);
},
/**
* Internal first-time Scene boot handler.
*
* @method Phaser.Scenes.SceneManager#bootQueue
* @private
* @fires Phaser.Core.Events#SYSTEM_READY
* @since 3.2.0
*/
bootQueue: function() {
if (this.isBooted) {
return;
}
this.systemScene = this.createSceneFromInstance("__SYSTEM", new Scene());
this.game.events.emit(GameEvents.SYSTEM_READY, this.systemScene, this);
var i;
var entry;
var key;
var sceneConfig;
for (i = 0; i < this._pending.length; i++) {
entry = this._pending[i];
key = entry.key;
sceneConfig = entry.scene;
var newScene;
if (sceneConfig instanceof Scene) {
newScene = this.createSceneFromInstance(key, sceneConfig);
} else if (typeof sceneConfig === "object") {
newScene = this.createSceneFromObject(key, sceneConfig);
} else if (typeof sceneConfig === "function") {
newScene = this.createSceneFromFunction(key, sceneConfig);
}
key = newScene.sys.settings.key;
this.keys[key] = newScene;
this.scenes.push(newScene);
if (this._data[key]) {
newScene.sys.settings.data = this._data[key].data;
if (this._data[key].autoStart) {
entry.autoStart = true;
}
}
if (entry.autoStart || newScene.sys.settings.active) {
this._start.push(key);
}
}
this._pending.length = 0;
this._data = {};
this.isBooted = true;
for (i = 0; i < this._start.length; i++) {
entry = this._start[i];
this.start(entry);
}
this._start.length = 0;
},
/**
* Process the Scene operations queue.
*
* @method Phaser.Scenes.SceneManager#processQueue
* @since 3.0.0
*/
processQueue: function() {
var pendingLength = this._pending.length;
var queueLength = this._queue.length;
if (pendingLength === 0 && queueLength === 0) {
return;
}
var i;
var entry;
if (pendingLength) {
for (i = 0; i < pendingLength; i++) {
entry = this._pending[i];
this.add(entry.key, entry.scene, entry.autoStart, entry.data);
}
for (i = 0; i < this._start.length; i++) {
entry = this._start[i];
this.start(entry);
}
this._start.length = 0;
this._pending.length = 0;
}
for (i = 0; i < this._queue.length; i++) {
entry = this._queue[i];
this[entry.op](entry.keyA, entry.keyB, entry.data);
}
this._queue.length = 0;
},
/**
* Adds a new Scene into the SceneManager.
* You must give each Scene a unique key by which you'll identify it.
*
* The `sceneConfig` can be:
*
* * A `Phaser.Scene` object, or an object that extends it.
* * A plain JavaScript object
* * A JavaScript ES6 Class that extends `Phaser.Scene`
* * A JavaScript ES5 prototype based Class
* * A JavaScript function
*
* If a function is given then a new Scene will be created by calling it.
*
* @method Phaser.Scenes.SceneManager#add
* @since 3.0.0
*
* @param {string} key - A unique key used to reference the Scene, i.e. `MainMenu` or `Level1`.
* @param {(Phaser.Types.Scenes.SceneType)} sceneConfig - The config for the Scene
* @param {boolean} [autoStart=false] - If `true` the Scene will be started immediately after being added.
* @param {object} [data] - Optional data object. This will be set as `Scene.settings.data` and passed to `Scene.init`, and `Scene.create`.
*
* @return {?Phaser.Scene} The added Scene, if it was added immediately, otherwise `null`.
*/
add: function(key, sceneConfig, autoStart, data) {
if (autoStart === void 0) {
autoStart = false;
}
if (data === void 0) {
data = {};
}
if (this.isProcessing || !this.isBooted) {
this._pending.push({
key,
scene: sceneConfig,
autoStart,
data
});
if (!this.isBooted) {
this._data[key] = { data };
}
return null;
}
key = this.getKey(key, sceneConfig);
var newScene;
if (sceneConfig instanceof Scene) {
newScene = this.createSceneFromInstance(key, sceneConfig);
} else if (typeof sceneConfig === "object") {
sceneConfig.key = key;
newScene = this.createSceneFromObject(key, sceneConfig);
} else if (typeof sceneConfig === "function") {
newScene = this.createSceneFromFunction(key, sceneConfig);
}
newScene.sys.settings.data = data;
key = newScene.sys.settings.key;
this.keys[key] = newScene;
this.scenes.push(newScene);
if (autoStart || newScene.sys.settings.active) {
if (this._pending.length) {
this._start.push(key);
} else {
this.start(key);
}
}
return newScene;
},
/**
* Removes a Scene from the SceneManager.
*
* The Scene is removed from the local scenes array, it's key is cleared from the keys
* cache and Scene.Systems.destroy is then called on it.
*
* If the SceneManager is processing the Scenes when this method is called it will
* queue the operation for the next update sequence.
*
* @method Phaser.Scenes.SceneManager#remove
* @since 3.2.0
*
* @param {string} key - A unique key used to reference the Scene, i.e. `MainMenu` or `Level1`.
*
* @return {this} This Scene Manager instance.
*/
remove: function(key) {
if (this.isProcessing) {
return this.queueOp("remove", key);
}
var sceneToRemove = this.getScene(key);
if (!sceneToRemove || sceneToRemove.sys.isTransitioning()) {
return this;
}
var index = this.scenes.indexOf(sceneToRemove);
var sceneKey = sceneToRemove.sys.settings.key;
if (index > -1) {
delete this.keys[sceneKey];
this.scenes.splice(index, 1);
if (this._start.indexOf(sceneKey) > -1) {
index = this._start.indexOf(sceneKey);
this._start.splice(index, 1);
}
sceneToRemove.sys.destroy();
}
return this;
},
/**
* Boot the given Scene.
*
* @method Phaser.Scenes.SceneManager#bootScene
* @private
* @fires Phaser.Scenes.Events#TRANSITION_INIT
* @since 3.0.0
*
* @param {Phaser.Scene} scene - The Scene to boot.
*/
bootScene: function(scene) {
var sys = scene.sys;
var settings = sys.settings;
sys.sceneUpdate = NOOP;
if (scene.init) {
scene.init.call(scene, settings.data);
settings.status = CONST.INIT;
if (settings.isTransition) {
sys.events.emit(Events.TRANSITION_INIT, settings.transitionFrom, settings.transitionDuration);
}
}
var loader;
if (sys.load) {
loader = sys.load;
loader.reset();
}
if (loader && scene.preload) {
scene.preload.call(scene);
settings.status = CONST.LOADING;
loader.once(LoaderEvents.COMPLETE, this.loadComplete, this);
loader.start();
} else {
this.create(scene);
}
},
/**
* Handles load completion for a Scene's Loader.
*
* Starts the Scene that the Loader belongs to.
*
* @method Phaser.Scenes.SceneManager#loadComplete
* @private
* @since 3.0.0
*
* @param {Phaser.Loader.LoaderPlugin} loader - The loader that has completed loading.
*/
loadComplete: function(loader) {
this.create(loader.scene);
},
/**
* Handle payload completion for a Scene.
*
* @method Phaser.Scenes.SceneManager#payloadComplete
* @private
* @since 3.0.0
*
* @param {Phaser.Loader.LoaderPlugin} loader - The loader that has completed loading its Scene's payload.
*/
payloadComplete: function(loader) {
this.bootScene(loader.scene);
},
/**
* Updates the Scenes.
*
* @method Phaser.Scenes.SceneManager#update
* @since 3.0.0
*
* @param {number} time - Time elapsed.
* @param {number} delta - Delta time from the last update.
*/
update: function(time, delta) {
this.processQueue();
this.isProcessing = true;
for (var i = this.scenes.length - 1; i >= 0; i--) {
var sys = this.scenes[i].sys;
if (sys.settings.status > CONST.START && sys.settings.status <= CONST.RUNNING) {
sys.step(time, delta);
}
if (sys.scenePlugin && sys.scenePlugin._target) {
sys.scenePlugin.step(time, delta);
}
}
},
/**
* Renders the Scenes.
*
* @method Phaser.Scenes.SceneManager#render
* @since 3.0.0
*
* @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The renderer to use.
*/
render: function(renderer) {
for (var i = 0; i < this.scenes.length; i++) {
var sys = this.scenes[i].sys;
if (sys.settings.visible && sys.settings.status >= CONST.LOADING && sys.settings.status < CONST.SLEEPING) {
sys.render(renderer);
}
}
this.isProcessing = false;
},
/**
* Calls the given Scene's {@link Phaser.Scene#create} method and updates its status.
*
* @method Phaser.Scenes.SceneManager#create
* @private
* @fires Phaser.Scenes.Events#CREATE
* @fires Phaser.Scenes.Events#TRANSITION_INIT
* @since 3.0.0
*
* @param {Phaser.Scene} scene - The Scene to create.
*/
create: function(scene) {
var sys = scene.sys;
var settings = sys.settings;
if (scene.create) {
settings.status = CONST.CREATING;
scene.create.call(scene, settings.data);
if (settings.status === CONST.DESTROYED) {
return;
}
}
if (settings.isTransition) {
sys.events.emit(Events.TRANSITION_START, settings.transitionFrom, settings.transitionDuration);
}
if (scene.update) {
sys.sceneUpdate = scene.update;
}
settings.status = CONST.RUNNING;
sys.events.emit(Events.CREATE, scene);
},
/**
* Creates and initializes a Scene from a function.
*
* @method Phaser.Scenes.SceneManager#createSceneFromFunction
* @private
* @since 3.0.0
*
* @param {string} key - The key of the Scene.
* @param {function} scene - The function to create the Scene from.
*
* @return {Phaser.Scene} The created Scene.
*/
createSceneFromFunction: function(key, scene) {
var newScene = new scene();
if (newScene instanceof Scene) {
var configKey = newScene.sys.settings.key;
if (configKey !== "") {
key = configKey;
}
if (this.keys.hasOwnProperty(key)) {
throw new Error("Cannot add Scene with duplicate key: " + key);
}
return this.createSceneFromInstance(key, newScene);
} else {
newScene.sys = new Systems(newScene);
newScene.sys.settings.key = key;
newScene.sys.init(this.game);
return newScene;
}
},
/**
* Creates and initializes a Scene instance.
*
* @method Phaser.Scenes.SceneManager#createSceneFromInstance
* @private
* @since 3.0.0
*
* @param {string} key - The key of the Scene.
* @param {Phaser.Scene} newScene - The Scene instance.
*
* @return {Phaser.Scene} The created Scene.
*/
createSceneFromInstance: function(key, newScene) {
var configKey = newScene.sys.settings.key;
if (configKey === "") {
newScene.sys.settings.key = key;
}
newScene.sys.init(this.game);
return newScene;
},
/**
* Creates and initializes a Scene from an Object definition.
*
* @method Phaser.Scenes.SceneManager#createSceneFromObject
* @private
* @since 3.0.0
*
* @param {string} key - The key of the Scene.
* @param {(string|Phaser.Types.Scenes.SettingsConfig|Phaser.Types.Scenes.CreateSceneFromObjectConfig)} sceneConfig - The Scene config.
*
* @return {Phaser.Scene} The created Scene.
*/
createSceneFromObject: function(key, sceneConfig) {
var newScene = new Scene(sceneConfig);
var configKey = newScene.sys.settings.key;
if (configKey !== "") {
key = configKey;
} else {
newScene.sys.settings.key = key;
}
newScene.sys.init(this.game);
var defaults = ["init", "preload", "create", "update", "render"];
for (var i = 0; i < defaults.length; i++) {
var sceneCallback = GetValue(sceneConfig, defaults[i], null);
if (sceneCallback) {
newScene[defaults[i]] = sceneCallback;
}
}
if (sceneConfig.hasOwnProperty("extend")) {
for (var propertyKey in sceneConfig.extend) {
if (!sceneConfig.extend.hasOwnProperty(propertyKey)) {
continue;
}
var value = sceneConfig.extend[propertyKey];
if (propertyKey === "data" && newScene.hasOwnProperty("data") && typeof value === "object") {
newScene.data.merge(value);
} else if (propertyKey !== "sys") {
newScene[propertyKey] = value;
}
}
}
return newScene;
},
/**
* Retrieves the key of a Scene from a Scene config.
*
* @method Phaser.Scenes.SceneManager#getKey
* @private
* @since 3.0.0
*
* @param {string} key - The key to check in the Scene config.
* @param {(Phaser.Scene|Phaser.Types.Scenes.SettingsConfig|function)} sceneConfig - The Scene config.
*
* @return {string} The Scene key.
*/
getKey: function(key, sceneConfig) {
if (!key) {
key = "default";
}
if (typeof sceneConfig === "function") {
return key;
} else if (sceneConfig instanceof Scene) {
key = sceneConfig.sys.settings.key;
} else if (typeof sceneConfig === "object" && sceneConfig.hasOwnProperty("key")) {
key = sceneConfig.key;
}
if (this.keys.hasOwnProperty(key)) {
throw new Error("Cannot add Scene with duplicate key: " + key);
} else {
return key;
}
},
/**
* Returns an array of all the current Scenes being managed by this Scene Manager.
*
* You can filter the output by the active state of the Scene and choose to have
* the array returned in normal or reversed order.
*
* @method Phaser.Scenes.SceneManager#getScenes
* @since 3.16.0
*
* @generic {Phaser.Scene[]} T - [$return]
*
* @param {boolean} [isActive=true] - Only include Scene's that are currently active?
* @param {boolean} [inReverse=false] - Return the array of Scenes in reverse?
*
* @return {Phaser.Scene[]} An array containing all of the Scenes in the Scene Manager.
*/
getScenes: function(isActive, inReverse) {
if (isActive === void 0) {
isActive = true;
}
if (inReverse === void 0) {
inReverse = false;
}
var out = [];
var scenes = this.scenes;
for (var i = 0; i < scenes.length; i++) {
var scene = scenes[i];
if (scene && (!isActive || isActive && scene.sys.isActive())) {
out.push(scene);
}
}
return inReverse ? out.reverse() : out;
},
/**
* Retrieves a Scene based on the given key.
*
* If an actual Scene is passed to this method, it can be used to check if
* its currently within the Scene Manager, or not.
*
* @method Phaser.Scenes.SceneManager#getScene
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} key - The key of the Scene to retrieve.
*
* @return {?Phaser.Scene} The Scene, or `null` if no matching Scene was found.
*/
getScene: function(key) {
if (typeof key === "string") {
if (this.keys[key]) {
return this.keys[key];
}
} else {
for (var i = 0; i < this.scenes.length; i++) {
if (key === this.scenes[i]) {
return key;
}
}
}
return null;
},
/**
* Determines whether a Scene is running.
*
* @method Phaser.Scenes.SceneManager#isActive
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} key - The Scene to check.
*
* @return {boolean} Whether the Scene is running, or `null` if no matching Scene was found.
*/
isActive: function(key) {
var scene = this.getScene(key);
if (scene) {
return scene.sys.isActive();
}
return null;
},
/**
* Determines whether a Scene is paused.
*
* @method Phaser.Scenes.SceneManager#isPaused
* @since 3.17.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} key - The Scene to check.
*
* @return {boolean} Whether the Scene is paused, or `null` if no matching Scene was found.
*/
isPaused: function(key) {
var scene = this.getScene(key);
if (scene) {
return scene.sys.isPaused();
}
return null;
},
/**
* Determines whether a Scene is visible.
*
* @method Phaser.Scenes.SceneManager#isVisible
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} key - The Scene to check.
*
* @return {boolean} Whether the Scene is visible, or `null` if no matching Scene was found.
*/
isVisible: function(key) {
var scene = this.getScene(key);
if (scene) {
return scene.sys.isVisible();
}
return null;
},
/**
* Determines whether a Scene is sleeping.
*
* @method Phaser.Scenes.SceneManager#isSleeping
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} key - The Scene to check.
*
* @return {boolean} Whether the Scene is sleeping, or `null` if no matching Scene was found.
*/
isSleeping: function(key) {
var scene = this.getScene(key);
if (scene) {
return scene.sys.isSleeping();
}
return null;
},
/**
* Pauses the given Scene.
*
* @method Phaser.Scenes.SceneManager#pause
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} key - The Scene to pause.
* @param {object} [data] - An optional data object that will be passed to the Scene and emitted by its pause event.
*
* @return {this} This Scene Manager instance.
*/
pause: function(key, data) {
var scene = this.getScene(key);
if (scene) {
scene.sys.pause(data);
}
return this;
},
/**
* Resumes the given Scene.
*
* @method Phaser.Scenes.SceneManager#resume
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} key - The Scene to resume.
* @param {object} [data] - An optional data object that will be passed to the Scene and emitted by its resume event.
*
* @return {this} This Scene Manager instance.
*/
resume: function(key, data) {
var scene = this.getScene(key);
if (scene) {
scene.sys.resume(data);
}
return this;
},
/**
* Puts the given Scene to sleep.
*
* @method Phaser.Scenes.SceneManager#sleep
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} key - The Scene to put to sleep.
* @param {object} [data] - An optional data object that will be passed to the Scene and emitted by its sleep event.
*
* @return {this} This Scene Manager instance.
*/
sleep: function(key, data) {
var scene = this.getScene(key);
if (scene && !scene.sys.isTransitioning()) {
scene.sys.sleep(data);
}
return this;
},
/**
* Awakens the given Scene.
*
* @method Phaser.Scenes.SceneManager#wake
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} key - The Scene to wake up.
* @param {object} [data] - An optional data object that will be passed to the Scene and emitted by its wake event.
*
* @return {this} This Scene Manager instance.
*/
wake: function(key, data) {
var scene = this.getScene(key);
if (scene) {
scene.sys.wake(data);
}
return this;
},
/**
* Runs the given Scene.
*
* If the given Scene is paused, it will resume it. If sleeping, it will wake it.
* If not running at all, it will be started.
*
* Use this if you wish to open a modal Scene by calling `pause` on the current
* Scene, then `run` on the modal Scene.
*
* @method Phaser.Scenes.SceneManager#run
* @since 3.10.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} key - The Scene to run.
* @param {object} [data] - A data object that will be passed to the Scene on start, wake, or resume.
*
* @return {this} This Scene Manager instance.
*/
run: function(key, data) {
var scene = this.getScene(key);
if (!scene) {
for (var i = 0; i < this._pending.length; i++) {
if (this._pending[i].key === key) {
this.queueOp("start", key, data);
break;
}
}
return this;
}
if (scene.sys.isSleeping()) {
scene.sys.wake(data);
} else if (scene.sys.isPaused()) {
scene.sys.resume(data);
} else {
this.start(key, data);
}
},
/**
* Starts the given Scene, if it is not starting, loading, or creating.
*
* If the Scene is running, paused, or sleeping, it will be shutdown and then started.
*
* @method Phaser.Scenes.SceneManager#start
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} key - The Scene to start.
* @param {object} [data] - Optional data object to pass to `Scene.Settings` and `Scene.init`, and `Scene.create`.
*
* @return {this} This Scene Manager instance.
*/
start: function(key, data) {
if (!this.isBooted) {
this._data[key] = {
autoStart: true,
data
};
return this;
}
var scene = this.getScene(key);
if (!scene) {
console.warn("Scene key not found: " + key);
return this;
}
var sys = scene.sys;
var status = sys.settings.status;
if (status >= CONST.START && status <= CONST.CREATING) {
return this;
} else if (status >= CONST.RUNNING && status <= CONST.SLEEPING) {
sys.shutdown();
sys.sceneUpdate = NOOP;
sys.start(data);
} else {
sys.sceneUpdate = NOOP;
sys.start(data);
var loader;
if (sys.load) {
loader = sys.load;
}
if (loader && sys.settings.hasOwnProperty("pack")) {
loader.reset();
if (loader.addPack({ payload: sys.settings.pack })) {
sys.settings.status = CONST.LOADING;
loader.once(LoaderEvents.COMPLETE, this.payloadComplete, this);
loader.start();
return this;
}
}
}
this.bootScene(scene);
return this;
},
/**
* Stops the given Scene.
*
* @method Phaser.Scenes.SceneManager#stop
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} key - The Scene to stop.
* @param {object} [data] - Optional data object to pass to Scene.shutdown.
*
* @return {this} This Scene Manager instance.
*/
stop: function(key, data) {
var scene = this.getScene(key);
if (scene && !scene.sys.isTransitioning() && scene.sys.settings.status !== CONST.SHUTDOWN) {
var loader = scene.sys.load;
if (loader) {
loader.off(LoaderEvents.COMPLETE, this.loadComplete, this);
loader.off(LoaderEvents.COMPLETE, this.payloadComplete, this);
}
scene.sys.shutdown(data);
}
return this;
},
/**
* Sleeps one one Scene and starts the other.
*
* @method Phaser.Scenes.SceneManager#switch
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [from,to]
*
* @param {(string|Phaser.Scene)} from - The Scene to sleep.
* @param {(string|Phaser.Scene)} to - The Scene to start.
* @param {object} [data] - Optional data object to pass to `Scene.Settings` and `Scene.init`, and `Scene.create`. It is only passed when the scene starts for the first time.
*
* @return {this} This Scene Manager instance.
*/
switch: function(from, to, data) {
var sceneA = this.getScene(from);
var sceneB = this.getScene(to);
if (sceneA && sceneB && sceneA !== sceneB) {
this.sleep(from);
if (this.isSleeping(to)) {
this.wake(to, data);
} else {
this.start(to, data);
}
}
return this;
},
/**
* Retrieves a Scene by numeric index.
*
* @method Phaser.Scenes.SceneManager#getAt
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {T} - [$return]
*
* @param {number} index - The index of the Scene to retrieve.
*
* @return {(Phaser.Scene|undefined)} The Scene.
*/
getAt: function(index) {
return this.scenes[index];
},
/**
* Retrieves the numeric index of a Scene.
*
* @method Phaser.Scenes.SceneManager#getIndex
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} key - The key of the Scene.
*
* @return {number} The index of the Scene.
*/
getIndex: function(key) {
var scene = this.getScene(key);
return this.scenes.indexOf(scene);
},
/**
* Brings a Scene to the top of the Scenes list.
*
* This means it will render above all other Scenes.
*
* @method Phaser.Scenes.SceneManager#bringToTop
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} key - The Scene to move.
*
* @return {this} This Scene Manager instance.
*/
bringToTop: function(key) {
if (this.isProcessing) {
return this.queueOp("bringToTop", key);
}
var index = this.getIndex(key);
var scenes = this.scenes;
if (index !== -1 && index < scenes.length) {
var scene = this.getScene(key);
scenes.splice(index, 1);
scenes.push(scene);
}
return this;
},
/**
* Sends a Scene to the back of the Scenes list.
*
* This means it will render below all other Scenes.
*
* @method Phaser.Scenes.SceneManager#sendToBack
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} key - The Scene to move.
*
* @return {this} This Scene Manager instance.
*/
sendToBack: function(key) {
if (this.isProcessing) {
return this.queueOp("sendToBack", key);
}
var index = this.getIndex(key);
if (index !== -1 && index > 0) {
var scene = this.getScene(key);
this.scenes.splice(index, 1);
this.scenes.unshift(scene);
}
return this;
},
/**
* Moves a Scene down one position in the Scenes list.
*
* @method Phaser.Scenes.SceneManager#moveDown
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} key - The Scene to move.
*
* @return {this} This Scene Manager instance.
*/
moveDown: function(key) {
if (this.isProcessing) {
return this.queueOp("moveDown", key);
}
var indexA = this.getIndex(key);
if (indexA > 0) {
var indexB = indexA - 1;
var sceneA = this.getScene(key);
var sceneB = this.getAt(indexB);
this.scenes[indexA] = sceneB;
this.scenes[indexB] = sceneA;
}
return this;
},
/**
* Moves a Scene up one position in the Scenes list.
*
* @method Phaser.Scenes.SceneManager#moveUp
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} key - The Scene to move.
*
* @return {this} This Scene Manager instance.
*/
moveUp: function(key) {
if (this.isProcessing) {
return this.queueOp("moveUp", key);
}
var indexA = this.getIndex(key);
if (indexA < this.scenes.length - 1) {
var indexB = indexA + 1;
var sceneA = this.getScene(key);
var sceneB = this.getAt(indexB);
this.scenes[indexA] = sceneB;
this.scenes[indexB] = sceneA;
}
return this;
},
/**
* Moves a Scene so it is immediately above another Scene in the Scenes list.
* If the Scene is already above the other, it isn't moved.
*
* This means it will render over the top of the other Scene.
*
* @method Phaser.Scenes.SceneManager#moveAbove
* @since 3.2.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [keyA,keyB]
*
* @param {(string|Phaser.Scene)} keyA - The Scene that Scene B will be moved above.
* @param {(string|Phaser.Scene)} keyB - The Scene to be moved.
*
* @return {this} This Scene Manager instance.
*/
moveAbove: function(keyA, keyB) {
if (keyA === keyB) {
return this;
}
if (this.isProcessing) {
return this.queueOp("moveAbove", keyA, keyB);
}
var indexA = this.getIndex(keyA);
var indexB = this.getIndex(keyB);
if (indexA !== -1 && indexB !== -1 && indexB < indexA) {
var tempScene = this.getAt(indexB);
this.scenes.splice(indexB, 1);
this.scenes.splice(indexA + (indexB > indexA), 0, tempScene);
}
return this;
},
/**
* Moves a Scene so it is immediately below another Scene in the Scenes list.
* If the Scene is already below the other, it isn't moved.
*
* This means it will render behind the other Scene.
*
* @method Phaser.Scenes.SceneManager#moveBelow
* @since 3.2.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [keyA,keyB]
*
* @param {(string|Phaser.Scene)} keyA - The Scene that Scene B will be moved below.
* @param {(string|Phaser.Scene)} keyB - The Scene to be moved.
*
* @return {this} This Scene Manager instance.
*/
moveBelow: function(keyA, keyB) {
if (keyA === keyB) {
return this;
}
if (this.isProcessing) {
return this.queueOp("moveBelow", keyA, keyB);
}
var indexA = this.getIndex(keyA);
var indexB = this.getIndex(keyB);
if (indexA !== -1 && indexB !== -1 && indexB > indexA) {
var tempScene = this.getAt(indexB);
this.scenes.splice(indexB, 1);
if (indexA === 0) {
this.scenes.unshift(tempScene);
} else {
this.scenes.splice(indexA - (indexB < indexA), 0, tempScene);
}
}
return this;
},
/**
* Queue a Scene operation for the next update.
*
* @method Phaser.Scenes.SceneManager#queueOp
* @private
* @since 3.0.0
*
* @param {string} op - The operation to perform.
* @param {(string|Phaser.Scene)} keyA - Scene A.
* @param {(any|string|Phaser.Scene)} [keyB] - Scene B, or a data object.
* @param {any} [data] - Optional data object to pass.
*
* @return {this} This Scene Manager instance.
*/
queueOp: function(op, keyA, keyB, data) {
this._queue.push({ op, keyA, keyB, data });
return this;
},
/**
* Swaps the positions of two Scenes in the Scenes list.
*
* @method Phaser.Scenes.SceneManager#swapPosition
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [keyA,keyB]
*
* @param {(string|Phaser.Scene)} keyA - The first Scene to swap.
* @param {(string|Phaser.Scene)} keyB - The second Scene to swap.
*
* @return {this} This Scene Manager instance.
*/
swapPosition: function(keyA, keyB) {
if (keyA === keyB) {
return this;
}
if (this.isProcessing) {
return this.queueOp("swapPosition", keyA, keyB);
}
var indexA = this.getIndex(keyA);
var indexB = this.getIndex(keyB);
if (indexA !== indexB && indexA !== -1 && indexB !== -1) {
var tempScene = this.getAt(indexA);
this.scenes[indexA] = this.scenes[indexB];
this.scenes[indexB] = tempScene;
}
return this;
},
/**
* Dumps debug information about each Scene to the developer console.
*
* @method Phaser.Scenes.SceneManager#dump
* @since 3.2.0
*/
dump: function() {
var out = [];
var map = ["pending", "init", "start", "loading", "creating", "running", "paused", "sleeping", "shutdown", "destroyed"];
for (var i = 0; i < this.scenes.length; i++) {
var sys = this.scenes[i].sys;
var key = sys.settings.visible && (sys.settings.status === CONST.RUNNING || sys.settings.status === CONST.PAUSED) ? "[*] " : "[-] ";
key += sys.settings.key + " (" + map[sys.settings.status] + ")";
out.push(key);
}
console.log(out.join("\n"));
},
/**
* Destroy this Scene Manager and all of its systems.
*
* This process cannot be reversed.
*
* This method is called automatically when a Phaser Game instance is destroyed.
*
* @method Phaser.Scenes.SceneManager#destroy
* @since 3.0.0
*/
destroy: function() {
for (var i = 0; i < this.scenes.length; i++) {
var sys = this.scenes[i].sys;
sys.destroy();
}
this.systemScene.sys.destroy();
this.update = NOOP;
this.scenes = [];
this._pending = [];
this._start = [];
this._queue = [];
this.game = null;
this.systemScene = null;
}
});
module2.exports = SceneManager;
}
),
/***/
52209: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Clamp = __webpack_require__2(45319);
var Class = __webpack_require__2(83419);
var Events = __webpack_require__2(44594);
var GetFastValue = __webpack_require__2(95540);
var PluginCache = __webpack_require__2(37277);
var ScenePlugin = new Class({
initialize: function ScenePlugin2(scene) {
this.scene = scene;
this.systems = scene.sys;
this.settings = scene.sys.settings;
this.key = scene.sys.settings.key;
this.manager = scene.sys.game.scene;
this.transitionProgress = 0;
this._elapsed = 0;
this._target = null;
this._duration = 0;
this._onUpdate;
this._onUpdateScope;
this._willSleep = false;
this._willRemove = false;
scene.sys.events.once(Events.BOOT, this.boot, this);
scene.sys.events.on(Events.START, this.pluginStart, this);
},
/**
* This method is called automatically, only once, when the Scene is first created.
* Do not invoke it directly.
*
* @method Phaser.Scenes.ScenePlugin#boot
* @private
* @since 3.0.0
*/
boot: function() {
this.systems.events.once(Events.DESTROY, this.destroy, this);
},
/**
* This method is called automatically by the Scene when it is starting up.
* It is responsible for creating local systems, properties and listening for Scene events.
* Do not invoke it directly.
*
* @method Phaser.Scenes.ScenePlugin#pluginStart
* @private
* @since 3.5.0
*/
pluginStart: function() {
this._target = null;
this.systems.events.once(Events.SHUTDOWN, this.shutdown, this);
},
/**
* Shutdown this Scene and run the given one.
*
* This will happen at the next Scene Manager update, not immediately.
*
* @method Phaser.Scenes.ScenePlugin#start
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} [key] - The Scene to start.
* @param {object} [data] - The Scene data. If no value is given it will not overwrite any previous data that may exist.
*
* @return {this} This Scene Plugin instance.
*/
start: function(key, data) {
if (key === void 0) {
key = this.key;
}
this.manager.queueOp("stop", this.key);
this.manager.queueOp("start", key, data);
return this;
},
/**
* Restarts this Scene.
*
* This will happen at the next Scene Manager update, not immediately.
*
* @method Phaser.Scenes.ScenePlugin#restart
* @since 3.4.0
*
* @param {object} [data] - The Scene data. If no value is given it will not overwrite any previous data that may exist.
*
* @return {this} This Scene Plugin instance.
*/
restart: function(data) {
var key = this.key;
this.manager.queueOp("stop", key);
this.manager.queueOp("start", key, data);
return this;
},
/**
* This will start a transition from the current Scene to the target Scene given.
*
* The target Scene cannot be the same as the current Scene.
*
* The transition will last for the duration specified in milliseconds.
*
* You can have the target Scene moved above or below this one in the display list.
*
* You can specify an update callback. This callback will be invoked _every frame_ for the duration
* of the transition.
*
* This Scene can either be sent to sleep at the end of the transition, or stopped. The default is to stop.
*
* There are also 5 transition related events: This scene will emit the event `transitionout` when
* the transition begins, which is typically the frame after calling this method.
*
* The target Scene will emit the event `transitioninit` when that Scene's `init` method is called.
* It will then emit the event `transitionstart` when its `create` method is called.
* If the Scene was sleeping and has been woken up, it will emit the event `transitionwake` instead of these two,
* as the Scenes `init` and `create` methods are not invoked when a Scene wakes up.
*
* When the duration of the transition has elapsed it will emit the event `transitioncomplete`.
* These events are cleared of all listeners when the Scene shuts down, but not if it is sent to sleep.
*
* It's important to understand that the duration of the transition begins the moment you call this method.
* If the Scene you are transitioning to includes delayed processes, such as waiting for files to load, the
* time still counts down even while that is happening. If the game itself pauses, or something else causes
* this Scenes update loop to stop, then the transition will also pause for that duration. There are
* checks in place to prevent you accidentally stopping a transitioning Scene but if you've got code to
* override this understand that until the target Scene completes it might never be unlocked for input events.
*
* @method Phaser.Scenes.ScenePlugin#transition
* @fires Phaser.Scenes.Events#TRANSITION_OUT
* @since 3.5.0
*
* @param {Phaser.Types.Scenes.SceneTransitionConfig} config - The transition configuration object.
*
* @return {boolean} `true` is the transition was started, otherwise `false`.
*/
transition: function(config) {
if (config === void 0) {
config = {};
}
var key = GetFastValue(config, "target", false);
var target = this.manager.getScene(key);
if (!key || !this.checkValidTransition(target)) {
return false;
}
var duration = GetFastValue(config, "duration", 1e3);
this._elapsed = 0;
this._target = target;
this._duration = duration;
this._willSleep = GetFastValue(config, "sleep", false);
this._willRemove = GetFastValue(config, "remove", false);
var callback = GetFastValue(config, "onUpdate", null);
if (callback) {
this._onUpdate = callback;
this._onUpdateScope = GetFastValue(config, "onUpdateScope", this.scene);
}
var allowInput = GetFastValue(config, "allowInput", false);
this.settings.transitionAllowInput = allowInput;
var targetSettings = target.sys.settings;
targetSettings.isTransition = true;
targetSettings.transitionFrom = this.scene;
targetSettings.transitionDuration = duration;
targetSettings.transitionAllowInput = allowInput;
if (GetFastValue(config, "moveAbove", false)) {
this.manager.moveAbove(this.key, key);
} else if (GetFastValue(config, "moveBelow", false)) {
this.manager.moveBelow(this.key, key);
}
if (target.sys.isSleeping()) {
target.sys.wake(GetFastValue(config, "data"));
} else {
this.manager.start(key, GetFastValue(config, "data"));
}
var onStartCallback = GetFastValue(config, "onStart", null);
var onStartScope = GetFastValue(config, "onStartScope", this.scene);
if (onStartCallback) {
onStartCallback.call(onStartScope, this.scene, target, duration);
}
this.systems.events.emit(Events.TRANSITION_OUT, target, duration);
return true;
},
/**
* Checks to see if this Scene can transition to the target Scene or not.
*
* @method Phaser.Scenes.ScenePlugin#checkValidTransition
* @private
* @since 3.5.0
*
* @param {Phaser.Scene} target - The Scene to test against.
*
* @return {boolean} `true` if this Scene can transition, otherwise `false`.
*/
checkValidTransition: function(target) {
if (!target || target.sys.isActive() || target.sys.isTransitioning() || target === this.scene || this.systems.isTransitioning()) {
return false;
}
return true;
},
/**
* A single game step. This is only called if the parent Scene is transitioning
* out to another Scene.
*
* @method Phaser.Scenes.ScenePlugin#step
* @private
* @since 3.5.0
*
* @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout.
* @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
*/
step: function(time, delta) {
this._elapsed += delta;
this.transitionProgress = Clamp(this._elapsed / this._duration, 0, 1);
if (this._onUpdate) {
this._onUpdate.call(this._onUpdateScope, this.transitionProgress);
}
if (this._elapsed >= this._duration) {
this.transitionComplete();
}
},
/**
* Called by `step` when the transition out of this scene to another is over.
*
* @method Phaser.Scenes.ScenePlugin#transitionComplete
* @private
* @fires Phaser.Scenes.Events#TRANSITION_COMPLETE
* @since 3.5.0
*/
transitionComplete: function() {
var targetSys = this._target.sys;
var targetSettings = this._target.sys.settings;
targetSys.events.emit(Events.TRANSITION_COMPLETE, this.scene);
targetSettings.isTransition = false;
targetSettings.transitionFrom = null;
this._duration = 0;
this._target = null;
this._onUpdate = null;
this._onUpdateScope = null;
if (this._willRemove) {
this.manager.remove(this.key);
} else if (this._willSleep) {
this.systems.sleep();
} else {
this.manager.stop(this.key);
}
},
/**
* Add the Scene into the Scene Manager and start it if 'autoStart' is true or the Scene config 'active' property is set.
*
* @method Phaser.Scenes.ScenePlugin#add
* @since 3.0.0
*
* @param {string} key - A unique key used to reference the Scene, i.e. `MainMenu` or `Level1`.
* @param {(Phaser.Types.Scenes.SceneType)} sceneConfig - The config for the Scene
* @param {boolean} [autoStart=false] - If `true` the Scene will be started immediately after being added.
* @param {object} [data] - Optional data object. This will be set as `Scene.settings.data` and passed to `Scene.init`, and `Scene.create`.
*
* @return {?Phaser.Scene} The added Scene, if it was added immediately, otherwise `null`.
*/
add: function(key, sceneConfig, autoStart, data) {
return this.manager.add(key, sceneConfig, autoStart, data);
},
/**
* Launch the given Scene and run it in parallel with this one.
*
* This will happen at the next Scene Manager update, not immediately.
*
* @method Phaser.Scenes.ScenePlugin#launch
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} key - The Scene to launch.
* @param {object} [data] - The Scene data.
*
* @return {this} This Scene Plugin instance.
*/
launch: function(key, data) {
if (key && key !== this.key) {
this.manager.queueOp("start", key, data);
}
return this;
},
/**
* Runs the given Scene, but does not change the state of this Scene.
*
* This will happen at the next Scene Manager update, not immediately.
*
* If the given Scene is paused, it will resume it. If sleeping, it will wake it.
* If not running at all, it will be started.
*
* Use this if you wish to open a modal Scene by calling `pause` on the current
* Scene, then `run` on the modal Scene.
*
* @method Phaser.Scenes.ScenePlugin#run
* @since 3.10.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} key - The Scene to run.
* @param {object} [data] - A data object that will be passed to the Scene and emitted in its ready, wake, or resume events.
*
* @return {this} This Scene Plugin instance.
*/
run: function(key, data) {
if (key && key !== this.key) {
this.manager.queueOp("run", key, data);
}
return this;
},
/**
* Pause the Scene - this stops the update step from happening but it still renders.
*
* This will happen at the next Scene Manager update, not immediately.
*
* @method Phaser.Scenes.ScenePlugin#pause
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} [key] - The Scene to pause.
* @param {object} [data] - An optional data object that will be passed to the Scene and emitted in its pause event.
*
* @return {this} This Scene Plugin instance.
*/
pause: function(key, data) {
if (key === void 0) {
key = this.key;
}
this.manager.queueOp("pause", key, data);
return this;
},
/**
* Resume the Scene - starts the update loop again.
*
* This will happen at the next Scene Manager update, not immediately.
*
* @method Phaser.Scenes.ScenePlugin#resume
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} [key] - The Scene to resume.
* @param {object} [data] - An optional data object that will be passed to the Scene and emitted in its resume event.
*
* @return {this} This Scene Plugin instance.
*/
resume: function(key, data) {
if (key === void 0) {
key = this.key;
}
this.manager.queueOp("resume", key, data);
return this;
},
/**
* Makes the Scene sleep (no update, no render) but doesn't shutdown.
*
* This will happen at the next Scene Manager update, not immediately.
*
* @method Phaser.Scenes.ScenePlugin#sleep
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} [key] - The Scene to put to sleep.
* @param {object} [data] - An optional data object that will be passed to the Scene and emitted in its sleep event.
*
* @return {this} This Scene Plugin instance.
*/
sleep: function(key, data) {
if (key === void 0) {
key = this.key;
}
this.manager.queueOp("sleep", key, data);
return this;
},
/**
* Makes the Scene wake-up (starts update and render)
*
* This will happen at the next Scene Manager update, not immediately.
*
* @method Phaser.Scenes.ScenePlugin#wake
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} [key] - The Scene to wake up.
* @param {object} [data] - An optional data object that will be passed to the Scene and emitted in its wake event.
*
* @return {this} This Scene Plugin instance.
*/
wake: function(key, data) {
if (key === void 0) {
key = this.key;
}
this.manager.queueOp("wake", key, data);
return this;
},
/**
* Makes this Scene sleep then starts the Scene given.
*
* This will happen at the next Scene Manager update, not immediately.
*
* @method Phaser.Scenes.ScenePlugin#switch
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} key - The Scene to start.
* @param {any} [data] - Optional data object to pass to either the Scene `wake` or `start` method.
*
* @return {this} This Scene Plugin instance.
*/
switch: function(key, data) {
if (key !== this.key) {
this.manager.queueOp("switch", this.key, key, data);
}
return this;
},
/**
* Shutdown the Scene, clearing display list, timers, etc.
*
* This happens at the next Scene Manager update, not immediately.
*
* @method Phaser.Scenes.ScenePlugin#stop
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} [key] - The Scene to stop.
* @param {any} [data] - Optional data object to pass to Scene.Systems.shutdown.
*
* @return {this} This Scene Plugin instance.
*/
stop: function(key, data) {
if (key === void 0) {
key = this.key;
}
this.manager.queueOp("stop", key, data);
return this;
},
/**
* Sets the active state of the given Scene.
*
* @method Phaser.Scenes.ScenePlugin#setActive
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {boolean} value - If `true` the Scene will be resumed. If `false` it will be paused.
* @param {(string|Phaser.Scene)} [key] - The Scene to set the active state of.
* @param {object} [data] - An optional data object that will be passed to the Scene and emitted with its events.
*
* @return {this} This Scene Plugin instance.
*/
setActive: function(value, key, data) {
if (key === void 0) {
key = this.key;
}
var scene = this.manager.getScene(key);
if (scene) {
scene.sys.setActive(value, data);
}
return this;
},
/**
* Sets the visible state of the given Scene.
*
* @method Phaser.Scenes.ScenePlugin#setVisible
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {boolean} value - The visible value.
* @param {(string|Phaser.Scene)} [key] - The Scene to set the visible state for.
*
* @return {this} This Scene Plugin instance.
*/
setVisible: function(value, key) {
if (key === void 0) {
key = this.key;
}
var scene = this.manager.getScene(key);
if (scene) {
scene.sys.setVisible(value);
}
return this;
},
/**
* Checks if the given Scene is sleeping or not?
*
* @method Phaser.Scenes.ScenePlugin#isSleeping
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} [key] - The Scene to check.
*
* @return {boolean} Whether the Scene is sleeping, or `null` if no matching Scene was found.
*/
isSleeping: function(key) {
if (key === void 0) {
key = this.key;
}
return this.manager.isSleeping(key);
},
/**
* Checks if the given Scene is running or not?
*
* @method Phaser.Scenes.ScenePlugin#isActive
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} [key] - The Scene to check.
*
* @return {boolean} Whether the Scene is running, or `null` if no matching Scene was found.
*/
isActive: function(key) {
if (key === void 0) {
key = this.key;
}
return this.manager.isActive(key);
},
/**
* Checks if the given Scene is paused or not?
*
* @method Phaser.Scenes.ScenePlugin#isPaused
* @since 3.17.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} [key] - The Scene to check.
*
* @return {boolean} Whether the Scene is paused, or `null` if no matching Scene was found.
*/
isPaused: function(key) {
if (key === void 0) {
key = this.key;
}
return this.manager.isPaused(key);
},
/**
* Checks if the given Scene is visible or not?
*
* @method Phaser.Scenes.ScenePlugin#isVisible
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} [key] - The Scene to check.
*
* @return {boolean} Whether the Scene is visible, or `null` if no matching Scene was found.
*/
isVisible: function(key) {
if (key === void 0) {
key = this.key;
}
return this.manager.isVisible(key);
},
/**
* Swaps the position of two scenes in the Scenes list.
*
* This controls the order in which they are rendered and updated.
*
* @method Phaser.Scenes.ScenePlugin#swapPosition
* @since 3.2.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [keyA,keyB]
*
* @param {(string|Phaser.Scene)} keyA - The first Scene to swap.
* @param {(string|Phaser.Scene)} [keyB] - The second Scene to swap. If none is given it defaults to this Scene.
*
* @return {this} This Scene Plugin instance.
*/
swapPosition: function(keyA, keyB) {
if (keyB === void 0) {
keyB = this.key;
}
if (keyA !== keyB) {
this.manager.swapPosition(keyA, keyB);
}
return this;
},
/**
* Moves a Scene so it is immediately above another Scene in the Scenes list.
* If the Scene is already above the other, it isn't moved.
*
* This means it will render over the top of the other Scene.
*
* @method Phaser.Scenes.ScenePlugin#moveAbove
* @since 3.2.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [keyA,keyB]
*
* @param {(string|Phaser.Scene)} keyA - The Scene that Scene B will be moved to be above.
* @param {(string|Phaser.Scene)} [keyB] - The Scene to be moved. If none is given it defaults to this Scene.
*
* @return {this} This Scene Plugin instance.
*/
moveAbove: function(keyA, keyB) {
if (keyB === void 0) {
keyB = this.key;
}
if (keyA !== keyB) {
this.manager.moveAbove(keyA, keyB);
}
return this;
},
/**
* Moves a Scene so it is immediately below another Scene in the Scenes list.
* If the Scene is already below the other, it isn't moved.
*
* This means it will render behind the other Scene.
*
* @method Phaser.Scenes.ScenePlugin#moveBelow
* @since 3.2.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [keyA,keyB]
*
* @param {(string|Phaser.Scene)} keyA - The Scene that Scene B will be moved to be below.
* @param {(string|Phaser.Scene)} [keyB] - The Scene to be moved. If none is given it defaults to this Scene.
*
* @return {this} This Scene Plugin instance.
*/
moveBelow: function(keyA, keyB) {
if (keyB === void 0) {
keyB = this.key;
}
if (keyA !== keyB) {
this.manager.moveBelow(keyA, keyB);
}
return this;
},
/**
* Removes a Scene from the SceneManager.
*
* The Scene is removed from the local scenes array, it's key is cleared from the keys
* cache and Scene.Systems.destroy is then called on it.
*
* If the SceneManager is processing the Scenes when this method is called it will
* queue the operation for the next update sequence.
*
* @method Phaser.Scenes.ScenePlugin#remove
* @since 3.2.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} [key] - The Scene to be removed.
*
* @return {this} This Scene Plugin instance.
*/
remove: function(key) {
if (key === void 0) {
key = this.key;
}
this.manager.remove(key);
return this;
},
/**
* Moves a Scene up one position in the Scenes list.
*
* @method Phaser.Scenes.ScenePlugin#moveUp
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} [key] - The Scene to move.
*
* @return {this} This Scene Plugin instance.
*/
moveUp: function(key) {
if (key === void 0) {
key = this.key;
}
this.manager.moveUp(key);
return this;
},
/**
* Moves a Scene down one position in the Scenes list.
*
* @method Phaser.Scenes.ScenePlugin#moveDown
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} [key] - The Scene to move.
*
* @return {this} This Scene Plugin instance.
*/
moveDown: function(key) {
if (key === void 0) {
key = this.key;
}
this.manager.moveDown(key);
return this;
},
/**
* Brings a Scene to the top of the Scenes list.
*
* This means it will render above all other Scenes.
*
* @method Phaser.Scenes.ScenePlugin#bringToTop
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} [key] - The Scene to move.
*
* @return {this} This Scene Plugin instance.
*/
bringToTop: function(key) {
if (key === void 0) {
key = this.key;
}
this.manager.bringToTop(key);
return this;
},
/**
* Sends a Scene to the back of the Scenes list.
*
* This means it will render below all other Scenes.
*
* @method Phaser.Scenes.ScenePlugin#sendToBack
* @since 3.0.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} [key] - The Scene to move.
*
* @return {this} This Scene Plugin instance.
*/
sendToBack: function(key) {
if (key === void 0) {
key = this.key;
}
this.manager.sendToBack(key);
return this;
},
/**
* Retrieves a Scene based on the given key.
*
* If an actual Scene is passed to this method, it can be used to check if
* its currently within the Scene Manager, or not.
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @method Phaser.Scenes.ScenePlugin#get
* @since 3.0.0
*
* @param {(string|Phaser.Scene)} key - The Scene to retrieve.
*
* @return {Phaser.Scene} The Scene.
*/
get: function(key) {
return this.manager.getScene(key);
},
/**
* Return the status of the Scene.
*
* @method Phaser.Scenes.ScenePlugin#getStatus
* @since 3.60.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} key - The Scene to get the status from.
*
* @return {number} The Scene status. This maps to the `Phaser.Scene` constants, such as `Phaser.Scene.LOADING`.
*/
getStatus: function(key) {
var scene = this.manager.getScene(key);
if (scene) {
return scene.sys.getStatus();
}
},
/**
* Retrieves the numeric index of a Scene in the Scenes list.
*
* @method Phaser.Scenes.ScenePlugin#getIndex
* @since 3.7.0
*
* @generic {Phaser.Scene} T
* @genericUse {(T|string)} - [key]
*
* @param {(string|Phaser.Scene)} [key] - The Scene to get the index of.
*
* @return {number} The index of the Scene.
*/
getIndex: function(key) {
if (key === void 0) {
key = this.key;
}
return this.manager.getIndex(key);
},
/**
* The Scene that owns this plugin is shutting down.
*
* We need to kill and reset all internal properties as well as stop listening to Scene events.
*
* @method Phaser.Scenes.ScenePlugin#shutdown
* @private
* @since 3.0.0
*/
shutdown: function() {
var eventEmitter = this.systems.events;
eventEmitter.off(Events.SHUTDOWN, this.shutdown, this);
eventEmitter.off(Events.TRANSITION_OUT);
},
/**
* The Scene that owns this plugin is being destroyed.
*
* We need to shutdown and then kill off all external references.
*
* @method Phaser.Scenes.ScenePlugin#destroy
* @private
* @since 3.0.0
*/
destroy: function() {
this.shutdown();
this.scene.sys.events.off(Events.START, this.start, this);
this.scene = null;
this.systems = null;
this.settings = null;
this.manager = null;
}
});
PluginCache.register("ScenePlugin", ScenePlugin, "scenePlugin");
module2.exports = ScenePlugin;
}
),
/***/
55681: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(89993);
var GetValue = __webpack_require__2(35154);
var Merge = __webpack_require__2(46975);
var InjectionMap = __webpack_require__2(87033);
var Settings = {
/**
* Takes a Scene configuration object and returns a fully formed System Settings object.
*
* @function Phaser.Scenes.Settings.create
* @since 3.0.0
*
* @param {(string|Phaser.Types.Scenes.SettingsConfig)} config - The Scene configuration object used to create this Scene Settings.
*
* @return {Phaser.Types.Scenes.SettingsObject} The Scene Settings object created as a result of the config and default settings.
*/
create: function(config) {
if (typeof config === "string") {
config = { key: config };
} else if (config === void 0) {
config = {};
}
return {
status: CONST.PENDING,
key: GetValue(config, "key", ""),
active: GetValue(config, "active", false),
visible: GetValue(config, "visible", true),
isBooted: false,
isTransition: false,
transitionFrom: null,
transitionDuration: 0,
transitionAllowInput: true,
// Loader payload array
data: {},
pack: GetValue(config, "pack", false),
// Cameras
cameras: GetValue(config, "cameras", null),
// Scene Property Injection Map
map: GetValue(config, "map", Merge(InjectionMap, GetValue(config, "mapAdd", {}))),
// Physics
physics: GetValue(config, "physics", {}),
// Loader
loader: GetValue(config, "loader", {}),
// Plugins
plugins: GetValue(config, "plugins", false),
// Input
input: GetValue(config, "input", {})
};
}
};
module2.exports = Settings;
}
),
/***/
2368: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(89993);
var DefaultPlugins = __webpack_require__2(42363);
var Events = __webpack_require__2(44594);
var GetPhysicsPlugins = __webpack_require__2(27397);
var GetScenePlugins = __webpack_require__2(52106);
var NOOP = __webpack_require__2(29747);
var Settings = __webpack_require__2(55681);
var Systems = new Class({
initialize: function Systems2(scene, config) {
this.scene = scene;
this.game;
this.renderer;
if (false) {
}
this.config = config;
this.settings = Settings.create(config);
this.canvas;
this.context;
this.anims;
this.cache;
this.plugins;
this.registry;
this.scale;
this.sound;
this.textures;
this.add;
this.cameras;
this.displayList;
this.events;
this.make;
this.scenePlugin;
this.updateList;
this.sceneUpdate = NOOP;
},
/**
* This method is called only once by the Scene Manager when the Scene is instantiated.
* It is responsible for setting up all of the Scene plugins and references.
* It should never be called directly.
*
* @method Phaser.Scenes.Systems#init
* @protected
* @fires Phaser.Scenes.Events#BOOT
* @since 3.0.0
*
* @param {Phaser.Game} game - A reference to the Phaser Game instance.
*/
init: function(game) {
this.settings.status = CONST.INIT;
this.sceneUpdate = NOOP;
this.game = game;
this.renderer = game.renderer;
this.canvas = game.canvas;
this.context = game.context;
var pluginManager = game.plugins;
this.plugins = pluginManager;
pluginManager.addToScene(this, DefaultPlugins.Global, [DefaultPlugins.CoreScene, GetScenePlugins(this), GetPhysicsPlugins(this)]);
this.events.emit(Events.BOOT, this);
this.settings.isBooted = true;
},
/**
* A single game step. Called automatically by the Scene Manager as a result of a Request Animation
* Frame or Set Timeout call to the main Game instance.
*
* @method Phaser.Scenes.Systems#step
* @fires Phaser.Scenes.Events#PRE_UPDATE
* @fires Phaser.Scenes.Events#UPDATE
* @fires Phaser.Scenes.Events#POST_UPDATE
* @since 3.0.0
*
* @param {number} time - The time value from the most recent Game step. Typically a high-resolution timer value, or Date.now().
* @param {number} delta - The delta value since the last frame. This is smoothed to avoid delta spikes by the TimeStep class.
*/
step: function(time, delta) {
var events = this.events;
events.emit(Events.PRE_UPDATE, time, delta);
events.emit(Events.UPDATE, time, delta);
this.sceneUpdate.call(this.scene, time, delta);
events.emit(Events.POST_UPDATE, time, delta);
},
/**
* Called automatically by the Scene Manager.
* Instructs the Scene to render itself via its Camera Manager to the renderer given.
*
* @method Phaser.Scenes.Systems#render
* @fires Phaser.Scenes.Events#PRE_RENDER
* @fires Phaser.Scenes.Events#RENDER
* @since 3.0.0
*
* @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The renderer that invoked the render call.
*/
render: function(renderer) {
var displayList = this.displayList;
displayList.depthSort();
this.events.emit(Events.PRE_RENDER, renderer);
this.cameras.render(renderer, displayList);
this.events.emit(Events.RENDER, renderer);
},
/**
* Force a sort of the display list on the next render.
*
* @method Phaser.Scenes.Systems#queueDepthSort
* @since 3.0.0
*/
queueDepthSort: function() {
this.displayList.queueDepthSort();
},
/**
* Immediately sorts the display list if the flag is set.
*
* @method Phaser.Scenes.Systems#depthSort
* @since 3.0.0
*/
depthSort: function() {
this.displayList.depthSort();
},
/**
* Pause this Scene.
*
* A paused Scene still renders, it just doesn't run any of its update handlers or systems.
*
* @method Phaser.Scenes.Systems#pause
* @fires Phaser.Scenes.Events#PAUSE
* @since 3.0.0
*
* @param {object} [data] - A data object that will be passed in the 'pause' event.
*
* @return {Phaser.Scenes.Systems} This Systems object.
*/
pause: function(data) {
var settings = this.settings;
var status = this.getStatus();
if (status !== CONST.CREATING && status !== CONST.RUNNING) {
console.warn("Cannot pause non-running Scene", settings.key);
} else if (this.settings.active) {
settings.status = CONST.PAUSED;
settings.active = false;
this.events.emit(Events.PAUSE, this, data);
}
return this;
},
/**
* Resume this Scene from a paused state.
*
* @method Phaser.Scenes.Systems#resume
* @fires Phaser.Scenes.Events#RESUME
* @since 3.0.0
*
* @param {object} [data] - A data object that will be passed in the 'resume' event.
*
* @return {Phaser.Scenes.Systems} This Systems object.
*/
resume: function(data) {
var events = this.events;
var settings = this.settings;
if (!this.settings.active) {
settings.status = CONST.RUNNING;
settings.active = true;
events.emit(Events.RESUME, this, data);
}
return this;
},
/**
* Send this Scene to sleep.
*
* A sleeping Scene doesn't run its update step or render anything, but it also isn't shut down
* or has any of its systems or children removed, meaning it can be re-activated at any point and
* will carry on from where it left off. It also keeps everything in memory and events and callbacks
* from other Scenes may still invoke changes within it, so be careful what is left active.
*
* @method Phaser.Scenes.Systems#sleep
* @fires Phaser.Scenes.Events#SLEEP
* @since 3.0.0
*
* @param {object} [data] - A data object that will be passed in the 'sleep' event.
*
* @return {Phaser.Scenes.Systems} This Systems object.
*/
sleep: function(data) {
var settings = this.settings;
var status = this.getStatus();
if (status !== CONST.CREATING && status !== CONST.RUNNING) {
console.warn("Cannot sleep non-running Scene", settings.key);
} else {
settings.status = CONST.SLEEPING;
settings.active = false;
settings.visible = false;
this.events.emit(Events.SLEEP, this, data);
}
return this;
},
/**
* Wake-up this Scene if it was previously asleep.
*
* @method Phaser.Scenes.Systems#wake
* @fires Phaser.Scenes.Events#WAKE
* @since 3.0.0
*
* @param {object} [data] - A data object that will be passed in the 'wake' event.
*
* @return {Phaser.Scenes.Systems} This Systems object.
*/
wake: function(data) {
var events = this.events;
var settings = this.settings;
settings.status = CONST.RUNNING;
settings.active = true;
settings.visible = true;
events.emit(Events.WAKE, this, data);
if (settings.isTransition) {
events.emit(Events.TRANSITION_WAKE, settings.transitionFrom, settings.transitionDuration);
}
return this;
},
/**
* Returns any data that was sent to this Scene by another Scene.
*
* The data is also passed to `Scene.init` and in various Scene events, but
* you can access it at any point via this method.
*
* @method Phaser.Scenes.Systems#getData
* @since 3.22.0
*
* @return {any} The Scene Data.
*/
getData: function() {
return this.settings.data;
},
/**
* Returns the current status of this Scene.
*
* @method Phaser.Scenes.Systems#getStatus
* @since 3.60.0
*
* @return {number} The status of this Scene. One of the `Phaser.Scene` constants.
*/
getStatus: function() {
return this.settings.status;
},
/**
* Can this Scene receive Input events?
*
* @method Phaser.Scenes.Systems#canInput
* @since 3.60.0
*
* @return {boolean} `true` if this Scene can receive Input events.
*/
canInput: function() {
var status = this.settings.status;
return status > CONST.PENDING && status <= CONST.RUNNING;
},
/**
* Is this Scene sleeping?
*
* @method Phaser.Scenes.Systems#isSleeping
* @since 3.0.0
*
* @return {boolean} `true` if this Scene is asleep, otherwise `false`.
*/
isSleeping: function() {
return this.settings.status === CONST.SLEEPING;
},
/**
* Is this Scene running?
*
* @method Phaser.Scenes.Systems#isActive
* @since 3.0.0
*
* @return {boolean} `true` if this Scene is running, otherwise `false`.
*/
isActive: function() {
return this.settings.status === CONST.RUNNING;
},
/**
* Is this Scene paused?
*
* @method Phaser.Scenes.Systems#isPaused
* @since 3.13.0
*
* @return {boolean} `true` if this Scene is paused, otherwise `false`.
*/
isPaused: function() {
return this.settings.status === CONST.PAUSED;
},
/**
* Is this Scene currently transitioning out to, or in from another Scene?
*
* @method Phaser.Scenes.Systems#isTransitioning
* @since 3.5.0
*
* @return {boolean} `true` if this Scene is currently transitioning, otherwise `false`.
*/
isTransitioning: function() {
return this.settings.isTransition || this.scenePlugin._target !== null;
},
/**
* Is this Scene currently transitioning out from itself to another Scene?
*
* @method Phaser.Scenes.Systems#isTransitionOut
* @since 3.5.0
*
* @return {boolean} `true` if this Scene is in transition to another Scene, otherwise `false`.
*/
isTransitionOut: function() {
return this.scenePlugin._target !== null && this.scenePlugin._duration > 0;
},
/**
* Is this Scene currently transitioning in from another Scene?
*
* @method Phaser.Scenes.Systems#isTransitionIn
* @since 3.5.0
*
* @return {boolean} `true` if this Scene is transitioning in from another Scene, otherwise `false`.
*/
isTransitionIn: function() {
return this.settings.isTransition;
},
/**
* Is this Scene visible and rendering?
*
* @method Phaser.Scenes.Systems#isVisible
* @since 3.0.0
*
* @return {boolean} `true` if this Scene is visible, otherwise `false`.
*/
isVisible: function() {
return this.settings.visible;
},
/**
* Sets the visible state of this Scene.
* An invisible Scene will not render, but will still process updates.
*
* @method Phaser.Scenes.Systems#setVisible
* @since 3.0.0
*
* @param {boolean} value - `true` to render this Scene, otherwise `false`.
*
* @return {Phaser.Scenes.Systems} This Systems object.
*/
setVisible: function(value) {
this.settings.visible = value;
return this;
},
/**
* Set the active state of this Scene.
*
* An active Scene will run its core update loop.
*
* @method Phaser.Scenes.Systems#setActive
* @since 3.0.0
*
* @param {boolean} value - If `true` the Scene will be resumed, if previously paused. If `false` it will be paused.
* @param {object} [data] - A data object that will be passed in the 'resume' or 'pause' events.
*
* @return {Phaser.Scenes.Systems} This Systems object.
*/
setActive: function(value, data) {
if (value) {
return this.resume(data);
} else {
return this.pause(data);
}
},
/**
* Start this Scene running and rendering.
* Called automatically by the SceneManager.
*
* @method Phaser.Scenes.Systems#start
* @fires Phaser.Scenes.Events#START
* @fires Phaser.Scenes.Events#READY
* @since 3.0.0
*
* @param {object} data - Optional data object that may have been passed to this Scene from another.
*/
start: function(data) {
var events = this.events;
var settings = this.settings;
if (data) {
settings.data = data;
}
settings.status = CONST.START;
settings.active = true;
settings.visible = true;
events.emit(Events.START, this);
events.emit(Events.READY, this, data);
},
/**
* Shutdown this Scene and send a shutdown event to all of its systems.
* A Scene that has been shutdown will not run its update loop or render, but it does
* not destroy any of its plugins or references. It is put into hibernation for later use.
* If you don't ever plan to use this Scene again, then it should be destroyed instead
* to free-up resources.
*
* @method Phaser.Scenes.Systems#shutdown
* @fires Phaser.Scenes.Events#SHUTDOWN
* @since 3.0.0
*
* @param {object} [data] - A data object that will be passed in the 'shutdown' event.
*/
shutdown: function(data) {
var events = this.events;
var settings = this.settings;
events.off(Events.TRANSITION_INIT);
events.off(Events.TRANSITION_START);
events.off(Events.TRANSITION_COMPLETE);
events.off(Events.TRANSITION_OUT);
settings.status = CONST.SHUTDOWN;
settings.active = false;
settings.visible = false;
events.emit(Events.SHUTDOWN, this, data);
},
/**
* Destroy this Scene and send a destroy event all of its systems.
* A destroyed Scene cannot be restarted.
* You should not call this directly, instead use `SceneManager.remove`.
*
* @method Phaser.Scenes.Systems#destroy
* @private
* @fires Phaser.Scenes.Events#DESTROY
* @since 3.0.0
*/
destroy: function() {
var events = this.events;
var settings = this.settings;
settings.status = CONST.DESTROYED;
settings.active = false;
settings.visible = false;
events.emit(Events.DESTROY, this);
events.removeAllListeners();
var props = ["scene", "game", "anims", "cache", "plugins", "registry", "sound", "textures", "add", "camera", "displayList", "events", "make", "scenePlugin", "updateList"];
for (var i = 0; i < props.length; i++) {
this[props[i]] = null;
}
}
});
module2.exports = Systems;
}
),
/***/
89993: (
/***/
(module2) => {
var CONST = {
/**
* Scene state.
*
* @name Phaser.Scenes.PENDING
* @readonly
* @type {number}
* @since 3.0.0
*/
PENDING: 0,
/**
* Scene state.
*
* @name Phaser.Scenes.INIT
* @readonly
* @type {number}
* @since 3.0.0
*/
INIT: 1,
/**
* Scene state.
*
* @name Phaser.Scenes.START
* @readonly
* @type {number}
* @since 3.0.0
*/
START: 2,
/**
* Scene state.
*
* @name Phaser.Scenes.LOADING
* @readonly
* @type {number}
* @since 3.0.0
*/
LOADING: 3,
/**
* Scene state.
*
* @name Phaser.Scenes.CREATING
* @readonly
* @type {number}
* @since 3.0.0
*/
CREATING: 4,
/**
* Scene state.
*
* @name Phaser.Scenes.RUNNING
* @readonly
* @type {number}
* @since 3.0.0
*/
RUNNING: 5,
/**
* Scene state.
*
* @name Phaser.Scenes.PAUSED
* @readonly
* @type {number}
* @since 3.0.0
*/
PAUSED: 6,
/**
* Scene state.
*
* @name Phaser.Scenes.SLEEPING
* @readonly
* @type {number}
* @since 3.0.0
*/
SLEEPING: 7,
/**
* Scene state.
*
* @name Phaser.Scenes.SHUTDOWN
* @readonly
* @type {number}
* @since 3.0.0
*/
SHUTDOWN: 8,
/**
* Scene state.
*
* @name Phaser.Scenes.DESTROYED
* @readonly
* @type {number}
* @since 3.0.0
*/
DESTROYED: 9
};
module2.exports = CONST;
}
),
/***/
69830: (
/***/
(module2) => {
module2.exports = "addedtoscene";
}
),
/***/
7919: (
/***/
(module2) => {
module2.exports = "boot";
}
),
/***/
46763: (
/***/
(module2) => {
module2.exports = "create";
}
),
/***/
11763: (
/***/
(module2) => {
module2.exports = "destroy";
}
),
/***/
71555: (
/***/
(module2) => {
module2.exports = "pause";
}
),
/***/
36735: (
/***/
(module2) => {
module2.exports = "postupdate";
}
),
/***/
3809: (
/***/
(module2) => {
module2.exports = "prerender";
}
),
/***/
90716: (
/***/
(module2) => {
module2.exports = "preupdate";
}
),
/***/
58262: (
/***/
(module2) => {
module2.exports = "ready";
}
),
/***/
91633: (
/***/
(module2) => {
module2.exports = "removedfromscene";
}
),
/***/
10319: (
/***/
(module2) => {
module2.exports = "render";
}
),
/***/
87132: (
/***/
(module2) => {
module2.exports = "resume";
}
),
/***/
81961: (
/***/
(module2) => {
module2.exports = "shutdown";
}
),
/***/
90194: (
/***/
(module2) => {
module2.exports = "sleep";
}
),
/***/
6265: (
/***/
(module2) => {
module2.exports = "start";
}
),
/***/
33178: (
/***/
(module2) => {
module2.exports = "transitioncomplete";
}
),
/***/
43063: (
/***/
(module2) => {
module2.exports = "transitioninit";
}
),
/***/
11259: (
/***/
(module2) => {
module2.exports = "transitionout";
}
),
/***/
61611: (
/***/
(module2) => {
module2.exports = "transitionstart";
}
),
/***/
45209: (
/***/
(module2) => {
module2.exports = "transitionwake";
}
),
/***/
22966: (
/***/
(module2) => {
module2.exports = "update";
}
),
/***/
21747: (
/***/
(module2) => {
module2.exports = "wake";
}
),
/***/
44594: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
ADDED_TO_SCENE: __webpack_require__2(69830),
BOOT: __webpack_require__2(7919),
CREATE: __webpack_require__2(46763),
DESTROY: __webpack_require__2(11763),
PAUSE: __webpack_require__2(71555),
POST_UPDATE: __webpack_require__2(36735),
PRE_RENDER: __webpack_require__2(3809),
PRE_UPDATE: __webpack_require__2(90716),
READY: __webpack_require__2(58262),
REMOVED_FROM_SCENE: __webpack_require__2(91633),
RENDER: __webpack_require__2(10319),
RESUME: __webpack_require__2(87132),
SHUTDOWN: __webpack_require__2(81961),
SLEEP: __webpack_require__2(90194),
START: __webpack_require__2(6265),
TRANSITION_COMPLETE: __webpack_require__2(33178),
TRANSITION_INIT: __webpack_require__2(43063),
TRANSITION_OUT: __webpack_require__2(11259),
TRANSITION_START: __webpack_require__2(61611),
TRANSITION_WAKE: __webpack_require__2(45209),
UPDATE: __webpack_require__2(22966),
WAKE: __webpack_require__2(21747)
};
}
),
/***/
62194: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(89993);
var Extend = __webpack_require__2(79291);
var Scene = {
Events: __webpack_require__2(44594),
GetPhysicsPlugins: __webpack_require__2(27397),
GetScenePlugins: __webpack_require__2(52106),
SceneManager: __webpack_require__2(60903),
ScenePlugin: __webpack_require__2(52209),
Settings: __webpack_require__2(55681),
Systems: __webpack_require__2(2368)
};
Scene = Extend(false, Scene, CONST);
module2.exports = Scene;
}
),
/***/
30341: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var EventEmitter = __webpack_require__2(50792);
var Events = __webpack_require__2(14463);
var Extend = __webpack_require__2(79291);
var NOOP = __webpack_require__2(29747);
var BaseSound = new Class({
Extends: EventEmitter,
initialize: function BaseSound2(manager, key, config) {
EventEmitter.call(this);
this.manager = manager;
this.key = key;
this.isPlaying = false;
this.isPaused = false;
this.totalRate = 1;
this.duration = this.duration || 0;
this.totalDuration = this.totalDuration || 0;
this.config = {
mute: false,
volume: 1,
rate: 1,
detune: 0,
seek: 0,
loop: false,
delay: 0,
pan: 0
};
this.currentConfig = this.config;
this.config = Extend(this.config, config);
this.markers = {};
this.currentMarker = null;
this.pendingRemove = false;
},
/**
* Adds a marker into the current sound. A marker is represented by name, start time, duration, and optionally config object.
* This allows you to bundle multiple sounds together into a single audio file and use markers to jump between them for playback.
*
* @method Phaser.Sound.BaseSound#addMarker
* @since 3.0.0
*
* @param {Phaser.Types.Sound.SoundMarker} marker - Marker object.
*
* @return {boolean} Whether the marker was added successfully.
*/
addMarker: function(marker) {
if (!marker || !marker.name || typeof marker.name !== "string") {
return false;
}
if (this.markers[marker.name]) {
console.error("addMarker " + marker.name + " already exists in Sound");
return false;
}
marker = Extend(true, {
name: "",
start: 0,
duration: this.totalDuration - (marker.start || 0),
config: {
mute: false,
volume: 1,
rate: 1,
detune: 0,
seek: 0,
loop: false,
delay: 0,
pan: 0
}
}, marker);
this.markers[marker.name] = marker;
return true;
},
/**
* Updates previously added marker.
*
* @method Phaser.Sound.BaseSound#updateMarker
* @since 3.0.0
*
* @param {Phaser.Types.Sound.SoundMarker} marker - Marker object with updated values.
*
* @return {boolean} Whether the marker was updated successfully.
*/
updateMarker: function(marker) {
if (!marker || !marker.name || typeof marker.name !== "string") {
return false;
}
if (!this.markers[marker.name]) {
console.warn("Audio Marker: " + marker.name + " missing in Sound: " + this.key);
return false;
}
this.markers[marker.name] = Extend(true, this.markers[marker.name], marker);
return true;
},
/**
* Removes a marker from the sound.
*
* @method Phaser.Sound.BaseSound#removeMarker
* @since 3.0.0
*
* @param {string} markerName - The name of the marker to remove.
*
* @return {?Phaser.Types.Sound.SoundMarker} Removed marker object or 'null' if there was no marker with provided name.
*/
removeMarker: function(markerName) {
var marker = this.markers[markerName];
if (!marker) {
return null;
}
this.markers[markerName] = null;
return marker;
},
/**
* Play this sound, or a marked section of it.
*
* It always plays the sound from the start. If you want to start playback from a specific time
* you can set 'seek' setting of the config object, provided to this call, to that value.
*
* @method Phaser.Sound.BaseSound#play
* @since 3.0.0
*
* @param {(string|Phaser.Types.Sound.SoundConfig)} [markerName=''] - If you want to play a marker then provide the marker name here. Alternatively, this parameter can be a SoundConfig object.
* @param {Phaser.Types.Sound.SoundConfig} [config] - Optional sound config object to be applied to this marker or entire sound if no marker name is provided. It gets memorized for future plays of current section of the sound.
*
* @return {boolean} Whether the sound started playing successfully.
*/
play: function(markerName, config) {
if (markerName === void 0) {
markerName = "";
}
if (typeof markerName === "object") {
config = markerName;
markerName = "";
}
if (typeof markerName !== "string") {
return false;
}
if (!markerName) {
this.currentMarker = null;
this.currentConfig = this.config;
this.duration = this.totalDuration;
} else {
if (!this.markers[markerName]) {
console.warn("Marker: " + markerName + " missing in Sound: " + this.key);
return false;
}
this.currentMarker = this.markers[markerName];
this.currentConfig = this.currentMarker.config;
this.duration = this.currentMarker.duration;
}
this.resetConfig();
this.currentConfig = Extend(this.currentConfig, config);
this.isPlaying = true;
this.isPaused = false;
return true;
},
/**
* Pauses the sound. This only works if the sound is currently playing.
*
* You can inspect the `isPlaying` and `isPaused` properties to check the state.
*
* @method Phaser.Sound.BaseSound#pause
* @since 3.0.0
*
* @return {boolean} Whether the sound was paused successfully.
*/
pause: function() {
if (this.isPaused || !this.isPlaying) {
return false;
}
this.isPlaying = false;
this.isPaused = true;
return true;
},
/**
* Resumes the sound. This only works if the sound is paused and not already playing.
*
* You can inspect the `isPlaying` and `isPaused` properties to check the state.
*
* @method Phaser.Sound.BaseSound#resume
* @since 3.0.0
*
* @return {boolean} Whether the sound was resumed successfully.
*/
resume: function() {
if (!this.isPaused || this.isPlaying) {
return false;
}
this.isPlaying = true;
this.isPaused = false;
return true;
},
/**
* Stop playing this sound.
*
* @method Phaser.Sound.BaseSound#stop
* @since 3.0.0
*
* @return {boolean} Whether the sound was stopped successfully.
*/
stop: function() {
if (!this.isPaused && !this.isPlaying) {
return false;
}
this.isPlaying = false;
this.isPaused = false;
this.resetConfig();
return true;
},
/**
* Method used internally for applying config values to some of the sound properties.
*
* @method Phaser.Sound.BaseSound#applyConfig
* @since 3.0.0
*/
applyConfig: function() {
this.mute = this.currentConfig.mute;
this.volume = this.currentConfig.volume;
this.rate = this.currentConfig.rate;
this.detune = this.currentConfig.detune;
this.loop = this.currentConfig.loop;
this.pan = this.currentConfig.pan;
},
/**
* Method used internally for resetting values of some of the config properties.
*
* @method Phaser.Sound.BaseSound#resetConfig
* @since 3.0.0
*/
resetConfig: function() {
this.currentConfig.seek = 0;
this.currentConfig.delay = 0;
},
/**
* Update method called automatically by sound manager on every game step.
*
* @method Phaser.Sound.BaseSound#update
* @since 3.0.0
*
* @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout.
* @param {number} delta - The delta time elapsed since the last frame.
*/
update: NOOP,
/**
* Method used internally to calculate total playback rate of the sound.
*
* @method Phaser.Sound.BaseSound#calculateRate
* @since 3.0.0
*/
calculateRate: function() {
var cent = 1.0005777895065548;
var totalDetune = this.currentConfig.detune + this.manager.detune;
var detuneRate = Math.pow(cent, totalDetune);
this.totalRate = this.currentConfig.rate * this.manager.rate * detuneRate;
},
/**
* Destroys this sound and all associated events and marks it for removal from the sound manager.
*
* @method Phaser.Sound.BaseSound#destroy
* @fires Phaser.Sound.Events#DESTROY
* @since 3.0.0
*/
destroy: function() {
if (this.pendingRemove) {
return;
}
this.stop();
this.emit(Events.DESTROY, this);
this.removeAllListeners();
this.pendingRemove = true;
this.manager = null;
this.config = null;
this.currentConfig = null;
this.markers = null;
this.currentMarker = null;
}
});
module2.exports = BaseSound;
}
),
/***/
85034: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Clone = __webpack_require__2(41786);
var EventEmitter = __webpack_require__2(50792);
var Events = __webpack_require__2(14463);
var GameEvents = __webpack_require__2(8443);
var GetAll = __webpack_require__2(46710);
var GetFirst = __webpack_require__2(58731);
var NOOP = __webpack_require__2(29747);
var Vector2 = __webpack_require__2(26099);
var BaseSoundManager = new Class({
Extends: EventEmitter,
initialize: function BaseSoundManager2(game) {
EventEmitter.call(this);
this.game = game;
this.jsonCache = game.cache.json;
this.sounds = [];
this.mute = false;
this.volume = 1;
this.pauseOnBlur = true;
this._rate = 1;
this._detune = 0;
this.locked = this.locked || false;
this.unlocked = false;
this.gameLostFocus = false;
this.listenerPosition = new Vector2();
game.events.on(GameEvents.BLUR, this.onGameBlur, this);
game.events.on(GameEvents.FOCUS, this.onGameFocus, this);
game.events.on(GameEvents.PRE_STEP, this.update, this);
game.events.once(GameEvents.DESTROY, this.destroy, this);
},
/**
* Adds a new sound into the sound manager.
*
* @method Phaser.Sound.BaseSoundManager#add
* @override
* @since 3.0.0
*
* @param {string} key - Asset key for the sound.
* @param {Phaser.Types.Sound.SoundConfig} [config] - An optional config object containing default sound settings.
*
* @return {Phaser.Sound.BaseSound} The new sound instance.
*/
add: NOOP,
/**
* Adds a new audio sprite sound into the sound manager.
* Audio Sprites are a combination of audio files and a JSON configuration.
* The JSON follows the format of that created by https://github.com/tonistiigi/audiosprite
*
* @method Phaser.Sound.BaseSoundManager#addAudioSprite
* @since 3.0.0
*
* @param {string} key - Asset key for the sound.
* @param {Phaser.Types.Sound.SoundConfig} [config] - An optional config object containing default sound settings.
*
* @return {(Phaser.Sound.NoAudioSound|Phaser.Sound.HTML5AudioSound|Phaser.Sound.WebAudioSound)} The new audio sprite sound instance.
*/
addAudioSprite: function(key, config) {
if (config === void 0) {
config = {};
}
var sound = this.add(key, config);
sound.spritemap = this.jsonCache.get(key).spritemap;
for (var markerName in sound.spritemap) {
if (!sound.spritemap.hasOwnProperty(markerName)) {
continue;
}
var markerConfig = Clone(config);
var marker = sound.spritemap[markerName];
markerConfig.loop = marker.hasOwnProperty("loop") ? marker.loop : false;
sound.addMarker({
name: markerName,
start: marker.start,
duration: marker.end - marker.start,
config: markerConfig
});
}
return sound;
},
/**
* Gets the first sound in this Sound Manager that matches the given key.
* If none can be found it returns `null`.
*
* @method Phaser.Sound.BaseSoundManager#get
* @since 3.23.0
*
* @generic {Phaser.Sound.BaseSound} T
* @genericUse {T} - [$return]
*
* @param {string} key - Sound asset key.
*
* @return {?Phaser.Sound.BaseSound} - The sound, or null.
*/
get: function(key) {
return GetFirst(this.sounds, "key", key);
},
/**
* Gets all sounds in this Sound Manager.
*
* You can optionally specify a key, in which case only Sound instances that match the given key
* will be returned.
*
* @method Phaser.Sound.BaseSoundManager#getAll
* @since 3.23.0
*
* @generic {Phaser.Sound.BaseSound} T
* @genericUse {T[]} - [$return]
*
* @param {string} [key] - Optional asset key. If given, only Sound instances with this key will be returned.
*
* @return {Phaser.Sound.BaseSound[]} - The sounds, or an empty array.
*/
getAll: function(key) {
if (key) {
return GetAll(this.sounds, "key", key);
} else {
return GetAll(this.sounds);
}
},
/**
* Returns all sounds from this Sound Manager that are currently
* playing. That is, Sound instances that have their `isPlaying`
* property set to `true`.
*
* @method Phaser.Sound.BaseSoundManager#getAllPlaying
* @since 3.60.0
*
* @generic {Phaser.Sound.BaseSound} T
* @genericUse {T[]} - [$return]
*
* @return {Phaser.Sound.BaseSound[]} - All currently playing sounds, or an empty array.
*/
getAllPlaying: function() {
return GetAll(this.sounds, "isPlaying", true);
},
/**
* Adds a new sound to the sound manager and plays it.
*
* The sound will be automatically removed (destroyed) once playback ends.
*
* This lets you play a new sound on the fly without the need to keep a reference to it.
*
* @method Phaser.Sound.BaseSoundManager#play
* @listens Phaser.Sound.Events#COMPLETE
* @since 3.0.0
*
* @param {string} key - Asset key for the sound.
* @param {(Phaser.Types.Sound.SoundConfig|Phaser.Types.Sound.SoundMarker)} [extra] - An optional additional object containing settings to be applied to the sound. It could be either config or marker object.
*
* @return {boolean} Whether the sound started playing successfully.
*/
play: function(key, extra) {
var sound = this.add(key);
sound.once(Events.COMPLETE, sound.destroy, sound);
if (extra) {
if (extra.name) {
sound.addMarker(extra);
return sound.play(extra.name);
} else {
return sound.play(extra);
}
} else {
return sound.play();
}
},
/**
* Adds a new audio sprite sound to the sound manager and plays it.
* The sprite will be automatically removed (destroyed) once playback ends.
* This lets you play a new sound on the fly without the need to keep a reference to it.
*
* @method Phaser.Sound.BaseSoundManager#playAudioSprite
* @listens Phaser.Sound.Events#COMPLETE
* @since 3.0.0
*
* @param {string} key - Asset key for the sound.
* @param {string} spriteName - The name of the sound sprite to play.
* @param {Phaser.Types.Sound.SoundConfig} [config] - An optional config object containing default sound settings.
*
* @return {boolean} Whether the audio sprite sound started playing successfully.
*/
playAudioSprite: function(key, spriteName, config) {
var sound = this.addAudioSprite(key);
sound.once(Events.COMPLETE, sound.destroy, sound);
return sound.play(spriteName, config);
},
/**
* Removes a sound from the sound manager.
* The removed sound is destroyed before removal.
*
* @method Phaser.Sound.BaseSoundManager#remove
* @since 3.0.0
*
* @param {Phaser.Sound.BaseSound} sound - The sound object to remove.
*
* @return {boolean} True if the sound was removed successfully, otherwise false.
*/
remove: function(sound) {
var index = this.sounds.indexOf(sound);
if (index !== -1) {
sound.destroy();
this.sounds.splice(index, 1);
return true;
}
return false;
},
/**
* Removes all sounds from the manager, destroying the sounds.
*
* @method Phaser.Sound.BaseSoundManager#removeAll
* @since 3.23.0
*/
removeAll: function() {
this.sounds.forEach(function(sound) {
sound.destroy();
});
this.sounds.length = 0;
},
/**
* Removes all sounds from the sound manager that have an asset key matching the given value.
* The removed sounds are destroyed before removal.
*
* @method Phaser.Sound.BaseSoundManager#removeByKey
* @since 3.0.0
*
* @param {string} key - The key to match when removing sound objects.
*
* @return {number} The number of matching sound objects that were removed.
*/
removeByKey: function(key) {
var removed = 0;
for (var i = this.sounds.length - 1; i >= 0; i--) {
var sound = this.sounds[i];
if (sound.key === key) {
sound.destroy();
this.sounds.splice(i, 1);
removed++;
}
}
return removed;
},
/**
* Pauses all the sounds in the game.
*
* @method Phaser.Sound.BaseSoundManager#pauseAll
* @fires Phaser.Sound.Events#PAUSE_ALL
* @since 3.0.0
*/
pauseAll: function() {
this.forEachActiveSound(function(sound) {
sound.pause();
});
this.emit(Events.PAUSE_ALL, this);
},
/**
* Resumes all the sounds in the game.
*
* @method Phaser.Sound.BaseSoundManager#resumeAll
* @fires Phaser.Sound.Events#RESUME_ALL
* @since 3.0.0
*/
resumeAll: function() {
this.forEachActiveSound(function(sound) {
sound.resume();
});
this.emit(Events.RESUME_ALL, this);
},
/**
* Sets the X and Y position of the Spatial Audio listener on this Web Audios context.
*
* If you call this method with no parameters it will default to the center-point of
* the game canvas. Depending on the type of game you're making, you may need to call
* this method constantly to reset the listener position as the camera scrolls.
*
* Calling this method does nothing on HTML5Audio.
*
* @method Phaser.Sound.BaseSoundManager#setListenerPosition
* @since 3.60.0
*
* @param {number} [x] - The x position of the Spatial Audio listener.
* @param {number} [y] - The y position of the Spatial Audio listener.
*/
setListenerPosition: NOOP,
/**
* Stops all the sounds in the game.
*
* @method Phaser.Sound.BaseSoundManager#stopAll
* @fires Phaser.Sound.Events#STOP_ALL
* @since 3.0.0
*/
stopAll: function() {
this.forEachActiveSound(function(sound) {
sound.stop();
});
this.emit(Events.STOP_ALL, this);
},
/**
* Stops any sounds matching the given key.
*
* @method Phaser.Sound.BaseSoundManager#stopByKey
* @since 3.23.0
*
* @param {string} key - Sound asset key.
*
* @return {number} - How many sounds were stopped.
*/
stopByKey: function(key) {
var stopped = 0;
this.getAll(key).forEach(function(sound) {
if (sound.stop()) {
stopped++;
}
});
return stopped;
},
/**
* When a key is given, returns true if any sound with that key is playing.
*
* When no key is given, returns true if any sound is playing.
*
* @method Phaser.Sound.BaseSoundManager#isPlaying
* @since 3.85.0
*
* @param {?string} key - Sound asset key.
*
* @return {boolean} - Per the key argument, true if any matching sound is playing, otherwise false.
*/
isPlaying: function(key) {
var sounds = this.sounds;
var i = sounds.length - 1;
var sound;
if (key === void 0) {
for (; i >= 0; i--) {
sound = this.sounds[i];
if (sound.isPlaying) {
return true;
}
}
} else {
for (; i >= 0; i--) {
sound = this.sounds[i];
if (sound.key === key && sound.isPlaying) {
return true;
}
}
}
return false;
},
/**
* Method used internally for unlocking audio playback on devices that
* require user interaction before any sound can be played on a web page.
*
* Read more about how this issue is handled here in [this article](https://medium.com/@pgoloskokovic/unlocking-web-audio-the-smarter-way-8858218c0e09).
*
* @method Phaser.Sound.BaseSoundManager#unlock
* @override
* @protected
* @since 3.0.0
*/
unlock: NOOP,
/**
* Method used internally for pausing sound manager if
* Phaser.Sound.BaseSoundManager#pauseOnBlur is set to true.
*
* @method Phaser.Sound.BaseSoundManager#onBlur
* @override
* @protected
* @since 3.0.0
*/
onBlur: NOOP,
/**
* Method used internally for resuming sound manager if
* Phaser.Sound.BaseSoundManager#pauseOnBlur is set to true.
*
* @method Phaser.Sound.BaseSoundManager#onFocus
* @override
* @protected
* @since 3.0.0
*/
onFocus: NOOP,
/**
* Internal handler for Phaser.Core.Events#BLUR.
*
* @method Phaser.Sound.BaseSoundManager#onGameBlur
* @private
* @since 3.23.0
*/
onGameBlur: function() {
this.gameLostFocus = true;
if (this.pauseOnBlur) {
this.onBlur();
}
},
/**
* Internal handler for Phaser.Core.Events#FOCUS.
*
* @method Phaser.Sound.BaseSoundManager#onGameFocus
* @private
* @since 3.23.0
*/
onGameFocus: function() {
this.gameLostFocus = false;
if (this.pauseOnBlur) {
this.onFocus();
}
},
/**
* Update method called on every game step.
* Removes destroyed sounds and updates every active sound in the game.
*
* @method Phaser.Sound.BaseSoundManager#update
* @protected
* @fires Phaser.Sound.Events#UNLOCKED
* @since 3.0.0
*
* @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout.
* @param {number} delta - The delta time elapsed since the last frame.
*/
update: function(time, delta) {
if (this.unlocked) {
this.unlocked = false;
this.locked = false;
this.emit(Events.UNLOCKED, this);
}
for (var i = this.sounds.length - 1; i >= 0; i--) {
if (this.sounds[i].pendingRemove) {
this.sounds.splice(i, 1);
}
}
this.sounds.forEach(function(sound) {
sound.update(time, delta);
});
},
/**
* Destroys all the sounds in the game and all associated events.
*
* @method Phaser.Sound.BaseSoundManager#destroy
* @since 3.0.0
*/
destroy: function() {
this.game.events.off(GameEvents.BLUR, this.onGameBlur, this);
this.game.events.off(GameEvents.FOCUS, this.onGameFocus, this);
this.game.events.off(GameEvents.PRE_STEP, this.update, this);
this.removeAllListeners();
this.removeAll();
this.sounds.length = 0;
this.sounds = null;
this.listenerPosition = null;
this.game = null;
},
/**
* Method used internally for iterating only over active sounds and skipping sounds that are marked for removal.
*
* @method Phaser.Sound.BaseSoundManager#forEachActiveSound
* @private
* @since 3.0.0
*
* @param {Phaser.Types.Sound.EachActiveSoundCallback} callback - Callback function. (manager: Phaser.Sound.BaseSoundManager, sound: Phaser.Sound.BaseSound, index: number, sounds: Phaser.Manager.BaseSound[]) => void
* @param {*} [scope] - Callback context.
*/
forEachActiveSound: function(callback, scope) {
var _this = this;
this.sounds.forEach(function(sound, index) {
if (sound && !sound.pendingRemove) {
callback.call(scope || _this, sound, index, _this.sounds);
}
});
},
/**
* Sets the global playback rate at which all the sounds will be played.
*
* For example, a value of 1.0 plays the audio at full speed, 0.5 plays the audio at half speed
* and 2.0 doubles the audios playback speed.
*
* @method Phaser.Sound.BaseSoundManager#setRate
* @fires Phaser.Sound.Events#GLOBAL_RATE
* @since 3.3.0
*
* @param {number} value - Global playback rate at which all the sounds will be played.
*
* @return {this} This Sound Manager.
*/
setRate: function(value) {
this.rate = value;
return this;
},
/**
* Global playback rate at which all the sounds will be played.
* Value of 1.0 plays the audio at full speed, 0.5 plays the audio at half speed
* and 2.0 doubles the audio's playback speed.
*
* @name Phaser.Sound.BaseSoundManager#rate
* @type {number}
* @default 1
* @since 3.0.0
*/
rate: {
get: function() {
return this._rate;
},
set: function(value) {
this._rate = value;
this.forEachActiveSound(function(sound) {
sound.calculateRate();
});
this.emit(Events.GLOBAL_RATE, this, value);
}
},
/**
* Sets the global detuning of all sounds in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29).
* The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent).
*
* @method Phaser.Sound.BaseSoundManager#setDetune
* @fires Phaser.Sound.Events#GLOBAL_DETUNE
* @since 3.3.0
*
* @param {number} value - The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent).
*
* @return {this} This Sound Manager.
*/
setDetune: function(value) {
this.detune = value;
return this;
},
/**
* Global detuning of all sounds in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29).
* The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent).
*
* @name Phaser.Sound.BaseSoundManager#detune
* @type {number}
* @default 0
* @since 3.0.0
*/
detune: {
get: function() {
return this._detune;
},
set: function(value) {
this._detune = value;
this.forEachActiveSound(function(sound) {
sound.calculateRate();
});
this.emit(Events.GLOBAL_DETUNE, this, value);
}
}
});
module2.exports = BaseSoundManager;
}
),
/***/
14747: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var HTML5AudioSoundManager = __webpack_require__2(33684);
var NoAudioSoundManager = __webpack_require__2(25960);
var WebAudioSoundManager = __webpack_require__2(57490);
var SoundManagerCreator = {
create: function(game) {
var audioConfig = game.config.audio;
var deviceAudio = game.device.audio;
if (audioConfig.noAudio || !deviceAudio.webAudio && !deviceAudio.audioData) {
return new NoAudioSoundManager(game);
}
if (deviceAudio.webAudio && !audioConfig.disableWebAudio) {
return new WebAudioSoundManager(game);
}
return new HTML5AudioSoundManager(game);
}
};
module2.exports = SoundManagerCreator;
}
),
/***/
19723: (
/***/
(module2) => {
module2.exports = "complete";
}
),
/***/
98882: (
/***/
(module2) => {
module2.exports = "decodedall";
}
),
/***/
57506: (
/***/
(module2) => {
module2.exports = "decoded";
}
),
/***/
73146: (
/***/
(module2) => {
module2.exports = "destroy";
}
),
/***/
11305: (
/***/
(module2) => {
module2.exports = "detune";
}
),
/***/
40577: (
/***/
(module2) => {
module2.exports = "detune";
}
),
/***/
30333: (
/***/
(module2) => {
module2.exports = "mute";
}
),
/***/
20394: (
/***/
(module2) => {
module2.exports = "rate";
}
),
/***/
21802: (
/***/
(module2) => {
module2.exports = "volume";
}
),
/***/
1299: (
/***/
(module2) => {
module2.exports = "looped";
}
),
/***/
99190: (
/***/
(module2) => {
module2.exports = "loop";
}
),
/***/
97125: (
/***/
(module2) => {
module2.exports = "mute";
}
),
/***/
89259: (
/***/
(module2) => {
module2.exports = "pan";
}
),
/***/
79986: (
/***/
(module2) => {
module2.exports = "pauseall";
}
),
/***/
17586: (
/***/
(module2) => {
module2.exports = "pause";
}
),
/***/
19618: (
/***/
(module2) => {
module2.exports = "play";
}
),
/***/
42306: (
/***/
(module2) => {
module2.exports = "rate";
}
),
/***/
10387: (
/***/
(module2) => {
module2.exports = "resumeall";
}
),
/***/
48959: (
/***/
(module2) => {
module2.exports = "resume";
}
),
/***/
9960: (
/***/
(module2) => {
module2.exports = "seek";
}
),
/***/
19180: (
/***/
(module2) => {
module2.exports = "stopall";
}
),
/***/
98328: (
/***/
(module2) => {
module2.exports = "stop";
}
),
/***/
50401: (
/***/
(module2) => {
module2.exports = "unlocked";
}
),
/***/
52498: (
/***/
(module2) => {
module2.exports = "volume";
}
),
/***/
14463: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
COMPLETE: __webpack_require__2(19723),
DECODED: __webpack_require__2(57506),
DECODED_ALL: __webpack_require__2(98882),
DESTROY: __webpack_require__2(73146),
DETUNE: __webpack_require__2(11305),
GLOBAL_DETUNE: __webpack_require__2(40577),
GLOBAL_MUTE: __webpack_require__2(30333),
GLOBAL_RATE: __webpack_require__2(20394),
GLOBAL_VOLUME: __webpack_require__2(21802),
LOOP: __webpack_require__2(99190),
LOOPED: __webpack_require__2(1299),
MUTE: __webpack_require__2(97125),
PAN: __webpack_require__2(89259),
PAUSE_ALL: __webpack_require__2(79986),
PAUSE: __webpack_require__2(17586),
PLAY: __webpack_require__2(19618),
RATE: __webpack_require__2(42306),
RESUME_ALL: __webpack_require__2(10387),
RESUME: __webpack_require__2(48959),
SEEK: __webpack_require__2(9960),
STOP_ALL: __webpack_require__2(19180),
STOP: __webpack_require__2(98328),
UNLOCKED: __webpack_require__2(50401),
VOLUME: __webpack_require__2(52498)
};
}
),
/***/
64895: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BaseSound = __webpack_require__2(30341);
var Class = __webpack_require__2(83419);
var Events = __webpack_require__2(14463);
var Clamp = __webpack_require__2(45319);
var HTML5AudioSound = new Class({
Extends: BaseSound,
initialize: function HTML5AudioSound2(manager, key, config) {
if (config === void 0) {
config = {};
}
this.tags = manager.game.cache.audio.get(key);
if (!this.tags) {
throw new Error('No cached audio asset with key "' + key);
}
this.audio = null;
this.startTime = 0;
this.previousTime = 0;
this.duration = this.tags[0].duration;
this.totalDuration = this.tags[0].duration;
BaseSound.call(this, manager, key, config);
},
/**
* Play this sound, or a marked section of it.
*
* It always plays the sound from the start. If you want to start playback from a specific time
* you can set 'seek' setting of the config object, provided to this call, to that value.
*
* If you want to play the same sound simultaneously, then you need to create another instance
* of it and play that Sound. For HTML5 Audio this also requires creating multiple audio instances
* when loading the audio files.
*
* @method Phaser.Sound.HTML5AudioSound#play
* @fires Phaser.Sound.Events#PLAY
* @since 3.0.0
*
* @param {(string|Phaser.Types.Sound.SoundConfig)} [markerName=''] - If you want to play a marker then provide the marker name here. Alternatively, this parameter can be a SoundConfig object.
* @param {Phaser.Types.Sound.SoundConfig} [config] - Optional sound config object to be applied to this marker or entire sound if no marker name is provided. It gets memorized for future plays of current section of the sound.
*
* @return {boolean} Whether the sound started playing successfully.
*/
play: function(markerName, config) {
if (this.manager.isLocked(this, "play", [markerName, config])) {
return false;
}
if (!BaseSound.prototype.play.call(this, markerName, config)) {
return false;
}
if (!this.pickAndPlayAudioTag()) {
return false;
}
this.emit(Events.PLAY, this);
return true;
},
/**
* Pauses the sound.
*
* @method Phaser.Sound.HTML5AudioSound#pause
* @fires Phaser.Sound.Events#PAUSE
* @since 3.0.0
*
* @return {boolean} Whether the sound was paused successfully.
*/
pause: function() {
if (this.manager.isLocked(this, "pause")) {
return false;
}
if (this.startTime > 0) {
return false;
}
if (!BaseSound.prototype.pause.call(this)) {
return false;
}
this.currentConfig.seek = this.audio.currentTime - (this.currentMarker ? this.currentMarker.start : 0);
this.stopAndReleaseAudioTag();
this.emit(Events.PAUSE, this);
return true;
},
/**
* Resumes the sound.
*
* @method Phaser.Sound.HTML5AudioSound#resume
* @fires Phaser.Sound.Events#RESUME
* @since 3.0.0
*
* @return {boolean} Whether the sound was resumed successfully.
*/
resume: function() {
if (this.manager.isLocked(this, "resume")) {
return false;
}
if (this.startTime > 0) {
return false;
}
if (!BaseSound.prototype.resume.call(this)) {
return false;
}
if (!this.pickAndPlayAudioTag()) {
return false;
}
this.emit(Events.RESUME, this);
return true;
},
/**
* Stop playing this sound.
*
* @method Phaser.Sound.HTML5AudioSound#stop
* @fires Phaser.Sound.Events#STOP
* @since 3.0.0
*
* @return {boolean} Whether the sound was stopped successfully.
*/
stop: function() {
if (this.manager.isLocked(this, "stop")) {
return false;
}
if (!BaseSound.prototype.stop.call(this)) {
return false;
}
this.stopAndReleaseAudioTag();
this.emit(Events.STOP, this);
return true;
},
/**
* This method is used internally to pick and play the next available audio tag.
*
* @method Phaser.Sound.HTML5AudioSound#pickAndPlayAudioTag
* @since 3.0.0
*
* @return {boolean} Whether the sound was assigned an audio tag successfully.
*/
pickAndPlayAudioTag: function() {
if (!this.pickAudioTag()) {
this.reset();
return false;
}
var seek = this.currentConfig.seek;
var delay = this.currentConfig.delay;
var offset = (this.currentMarker ? this.currentMarker.start : 0) + seek;
this.previousTime = offset;
this.audio.currentTime = offset;
this.applyConfig();
if (delay === 0) {
this.startTime = 0;
if (this.audio.paused) {
this.playCatchPromise();
}
} else {
this.startTime = window.performance.now() + delay * 1e3;
if (!this.audio.paused) {
this.audio.pause();
}
}
this.resetConfig();
return true;
},
/**
* This method performs the audio tag pooling logic. It first looks for
* unused audio tag to assign to this sound object. If there are no unused
* audio tags, based on HTML5AudioSoundManager#override property value, it
* looks for sound with most advanced playback and hijacks its audio tag or
* does nothing.
*
* @method Phaser.Sound.HTML5AudioSound#pickAudioTag
* @since 3.0.0
*
* @return {boolean} Whether the sound was assigned an audio tag successfully.
*/
pickAudioTag: function() {
if (this.audio) {
return true;
}
for (var i = 0; i < this.tags.length; i++) {
var audio = this.tags[i];
if (audio.dataset.used === "false") {
audio.dataset.used = "true";
this.audio = audio;
return true;
}
}
if (!this.manager.override) {
return false;
}
var otherSounds = [];
this.manager.forEachActiveSound(function(sound) {
if (sound.key === this.key && sound.audio) {
otherSounds.push(sound);
}
}, this);
otherSounds.sort(function(a1, a2) {
if (a1.loop === a2.loop) {
return a2.seek / a2.duration - a1.seek / a1.duration;
}
return a1.loop ? 1 : -1;
});
var selectedSound = otherSounds[0];
this.audio = selectedSound.audio;
selectedSound.reset();
selectedSound.audio = null;
selectedSound.startTime = 0;
selectedSound.previousTime = 0;
return true;
},
/**
* Method used for playing audio tag and catching possible exceptions
* thrown from rejected Promise returned from play method call.
*
* @method Phaser.Sound.HTML5AudioSound#playCatchPromise
* @since 3.0.0
*/
playCatchPromise: function() {
var playPromise = this.audio.play();
if (playPromise) {
playPromise.catch(function(reason) {
console.warn(reason);
});
}
},
/**
* This method is used internally to stop and release the current audio tag.
*
* @method Phaser.Sound.HTML5AudioSound#stopAndReleaseAudioTag
* @since 3.0.0
*/
stopAndReleaseAudioTag: function() {
this.startTime = 0;
this.previousTime = 0;
if (this.audio) {
this.audio.pause();
this.audio.dataset.used = "false";
this.audio = null;
}
},
/**
* Method used internally to reset sound state, usually when stopping sound
* or when hijacking audio tag from another sound.
*
* @method Phaser.Sound.HTML5AudioSound#reset
* @since 3.0.0
*/
reset: function() {
BaseSound.prototype.stop.call(this);
},
/**
* Method used internally by sound manager for pausing sound if
* Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true.
*
* @method Phaser.Sound.HTML5AudioSound#onBlur
* @since 3.0.0
*/
onBlur: function() {
this.isPlaying = false;
this.isPaused = true;
this.currentConfig.seek = this.audio.currentTime - (this.currentMarker ? this.currentMarker.start : 0);
this.currentConfig.delay = Math.max(0, (this.startTime - window.performance.now()) / 1e3);
this.stopAndReleaseAudioTag();
},
/**
* Method used internally by sound manager for resuming sound if
* Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true.
*
* @method Phaser.Sound.HTML5AudioSound#onFocus
* @since 3.0.0
*/
onFocus: function() {
this.isPlaying = true;
this.isPaused = false;
this.pickAndPlayAudioTag();
},
/**
* Update method called automatically by sound manager on every game step.
*
* @method Phaser.Sound.HTML5AudioSound#update
* @fires Phaser.Sound.Events#COMPLETE
* @fires Phaser.Sound.Events#LOOPED
* @since 3.0.0
*
* @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout.
*/
update: function(time) {
if (!this.isPlaying) {
return;
}
if (this.startTime > 0) {
if (this.startTime < time - this.manager.audioPlayDelay) {
this.audio.currentTime += Math.max(0, time - this.startTime) / 1e3;
this.startTime = 0;
this.previousTime = this.audio.currentTime;
this.playCatchPromise();
}
return;
}
var startTime = this.currentMarker ? this.currentMarker.start : 0;
var endTime = startTime + this.duration;
var currentTime = this.audio.currentTime;
if (this.currentConfig.loop) {
if (currentTime >= endTime - this.manager.loopEndOffset) {
this.audio.currentTime = startTime + Math.max(0, currentTime - endTime);
currentTime = this.audio.currentTime;
} else if (currentTime < startTime) {
this.audio.currentTime += startTime;
currentTime = this.audio.currentTime;
}
if (currentTime < this.previousTime) {
this.emit(Events.LOOPED, this);
}
} else if (currentTime >= endTime) {
this.reset();
this.stopAndReleaseAudioTag();
this.emit(Events.COMPLETE, this);
return;
}
this.previousTime = currentTime;
},
/**
* Calls Phaser.Sound.BaseSound#destroy method
* and cleans up all HTML5 Audio related stuff.
*
* @method Phaser.Sound.HTML5AudioSound#destroy
* @since 3.0.0
*/
destroy: function() {
BaseSound.prototype.destroy.call(this);
this.tags = null;
if (this.audio) {
this.stopAndReleaseAudioTag();
}
},
/**
* This method is used internally to update the mute setting of this sound.
*
* @method Phaser.Sound.HTML5AudioSound#updateMute
* @since 3.0.0
*/
updateMute: function() {
if (this.audio) {
this.audio.muted = this.currentConfig.mute || this.manager.mute;
}
},
/**
* This method is used internally to update the volume of this sound.
*
* @method Phaser.Sound.HTML5AudioSound#updateVolume
* @since 3.0.0
*/
updateVolume: function() {
if (this.audio) {
this.audio.volume = Clamp(this.currentConfig.volume * this.manager.volume, 0, 1);
}
},
/**
* This method is used internally to update the playback rate of this sound.
*
* @method Phaser.Sound.HTML5AudioSound#calculateRate
* @since 3.0.0
*/
calculateRate: function() {
BaseSound.prototype.calculateRate.call(this);
if (this.audio) {
this.audio.playbackRate = this.totalRate;
}
},
/**
* Boolean indicating whether the sound is muted or not.
* Gets or sets the muted state of this sound.
*
* @name Phaser.Sound.HTML5AudioSound#mute
* @type {boolean}
* @default false
* @fires Phaser.Sound.Events#MUTE
* @since 3.0.0
*/
mute: {
get: function() {
return this.currentConfig.mute;
},
set: function(value) {
this.currentConfig.mute = value;
if (this.manager.isLocked(this, "mute", value)) {
return;
}
this.updateMute();
this.emit(Events.MUTE, this, value);
}
},
/**
* Sets the muted state of this Sound.
*
* @method Phaser.Sound.HTML5AudioSound#setMute
* @fires Phaser.Sound.Events#MUTE
* @since 3.4.0
*
* @param {boolean} value - `true` to mute this sound, `false` to unmute it.
*
* @return {this} This Sound instance.
*/
setMute: function(value) {
this.mute = value;
return this;
},
/**
* Gets or sets the volume of this sound, a value between 0 (silence) and 1 (full volume).
*
* @name Phaser.Sound.HTML5AudioSound#volume
* @type {number}
* @default 1
* @fires Phaser.Sound.Events#VOLUME
* @since 3.0.0
*/
volume: {
get: function() {
return this.currentConfig.volume;
},
set: function(value) {
this.currentConfig.volume = value;
if (this.manager.isLocked(this, "volume", value)) {
return;
}
this.updateVolume();
this.emit(Events.VOLUME, this, value);
}
},
/**
* Sets the volume of this Sound.
*
* @method Phaser.Sound.HTML5AudioSound#setVolume
* @fires Phaser.Sound.Events#VOLUME
* @since 3.4.0
*
* @param {number} value - The volume of the sound.
*
* @return {this} This Sound instance.
*/
setVolume: function(value) {
this.volume = value;
return this;
},
/**
* Rate at which this Sound will be played.
* Value of 1.0 plays the audio at full speed, 0.5 plays the audio at half speed
* and 2.0 doubles the audios playback speed.
*
* @name Phaser.Sound.HTML5AudioSound#rate
* @type {number}
* @default 1
* @fires Phaser.Sound.Events#RATE
* @since 3.0.0
*/
rate: {
get: function() {
return this.currentConfig.rate;
},
set: function(value) {
this.currentConfig.rate = value;
if (this.manager.isLocked(this, Events.RATE, value)) {
return;
} else {
this.calculateRate();
this.emit(Events.RATE, this, value);
}
}
},
/**
* Sets the playback rate of this Sound.
*
* For example, a value of 1.0 plays the audio at full speed, 0.5 plays the audio at half speed
* and 2.0 doubles the audios playback speed.
*
* @method Phaser.Sound.HTML5AudioSound#setRate
* @fires Phaser.Sound.Events#RATE
* @since 3.3.0
*
* @param {number} value - The playback rate at of this Sound.
*
* @return {this} This Sound instance.
*/
setRate: function(value) {
this.rate = value;
return this;
},
/**
* The detune value of this Sound, given in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29).
* The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent).
*
* @name Phaser.Sound.HTML5AudioSound#detune
* @type {number}
* @default 0
* @fires Phaser.Sound.Events#DETUNE
* @since 3.0.0
*/
detune: {
get: function() {
return this.currentConfig.detune;
},
set: function(value) {
this.currentConfig.detune = value;
if (this.manager.isLocked(this, Events.DETUNE, value)) {
return;
} else {
this.calculateRate();
this.emit(Events.DETUNE, this, value);
}
}
},
/**
* Sets the detune value of this Sound, given in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29).
* The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent).
*
* @method Phaser.Sound.HTML5AudioSound#setDetune
* @fires Phaser.Sound.Events#DETUNE
* @since 3.3.0
*
* @param {number} value - The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent).
*
* @return {this} This Sound instance.
*/
setDetune: function(value) {
this.detune = value;
return this;
},
/**
* Property representing the position of playback for this sound, in seconds.
* Setting it to a specific value moves current playback to that position.
* The value given is clamped to the range 0 to current marker duration.
* Setting seek of a stopped sound has no effect.
*
* @name Phaser.Sound.HTML5AudioSound#seek
* @type {number}
* @fires Phaser.Sound.Events#SEEK
* @since 3.0.0
*/
seek: {
get: function() {
if (this.isPlaying) {
return this.audio.currentTime - (this.currentMarker ? this.currentMarker.start : 0);
} else if (this.isPaused) {
return this.currentConfig.seek;
} else {
return 0;
}
},
set: function(value) {
if (this.manager.isLocked(this, "seek", value)) {
return;
}
if (this.startTime > 0) {
return;
}
if (this.isPlaying || this.isPaused) {
value = Math.min(Math.max(0, value), this.duration);
if (this.isPlaying) {
this.previousTime = value;
this.audio.currentTime = value;
} else if (this.isPaused) {
this.currentConfig.seek = value;
}
this.emit(Events.SEEK, this, value);
}
}
},
/**
* Seeks to a specific point in this sound.
*
* @method Phaser.Sound.HTML5AudioSound#setSeek
* @fires Phaser.Sound.Events#SEEK
* @since 3.4.0
*
* @param {number} value - The point in the sound to seek to.
*
* @return {this} This Sound instance.
*/
setSeek: function(value) {
this.seek = value;
return this;
},
/**
* Flag indicating whether or not the sound or current sound marker will loop.
*
* @name Phaser.Sound.HTML5AudioSound#loop
* @type {boolean}
* @default false
* @fires Phaser.Sound.Events#LOOP
* @since 3.0.0
*/
loop: {
get: function() {
return this.currentConfig.loop;
},
set: function(value) {
this.currentConfig.loop = value;
if (this.manager.isLocked(this, "loop", value)) {
return;
}
if (this.audio) {
this.audio.loop = value;
}
this.emit(Events.LOOP, this, value);
}
},
/**
* Sets the loop state of this Sound.
*
* @method Phaser.Sound.HTML5AudioSound#setLoop
* @fires Phaser.Sound.Events#LOOP
* @since 3.4.0
*
* @param {boolean} value - `true` to loop this sound, `false` to not loop it.
*
* @return {Phaser.Sound.HTML5AudioSound} This Sound instance.
*/
setLoop: function(value) {
this.loop = value;
return this;
},
/**
* Gets or sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan).
*
* Has no audible effect on HTML5 Audio Sound, but still generates the PAN Event.
*
* @name Phaser.Sound.HTML5AudioSound#pan
* @type {number}
* @default 0
* @fires Phaser.Sound.Events#PAN
* @since 3.50.0
*/
pan: {
get: function() {
return this.currentConfig.pan;
},
set: function(value) {
this.currentConfig.pan = value;
this.emit(Events.PAN, this, value);
}
},
/**
* Sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan).
*
* Has no audible effect on HTML5 Audio Sound, but still generates the PAN Event.
*
* @method Phaser.Sound.HTML5AudioSound#setPan
* @fires Phaser.Sound.Events#PAN
* @since 3.50.0
*
* @param {number} value - The pan of the sound. A value between -1 (full left pan) and 1 (full right pan).
*
* @return {this} This Sound instance.
*/
setPan: function(value) {
this.pan = value;
return this;
}
});
module2.exports = HTML5AudioSound;
}
),
/***/
33684: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BaseSoundManager = __webpack_require__2(85034);
var Class = __webpack_require__2(83419);
var Events = __webpack_require__2(14463);
var HTML5AudioSound = __webpack_require__2(64895);
var HTML5AudioSoundManager = new Class({
Extends: BaseSoundManager,
initialize: function HTML5AudioSoundManager2(game) {
this.override = true;
this.audioPlayDelay = 0.1;
this.loopEndOffset = 0.05;
this.onBlurPausedSounds = [];
this.locked = "ontouchstart" in window;
this.lockedActionsQueue = this.locked ? [] : null;
this._mute = false;
this._volume = 1;
BaseSoundManager.call(this, game);
},
/**
* Adds a new sound into the sound manager.
*
* @method Phaser.Sound.HTML5AudioSoundManager#add
* @since 3.0.0
*
* @param {string} key - Asset key for the sound.
* @param {Phaser.Types.Sound.SoundConfig} [config] - An optional config object containing default sound settings.
*
* @return {Phaser.Sound.HTML5AudioSound} The new sound instance.
*/
add: function(key, config) {
var sound = new HTML5AudioSound(this, key, config);
this.sounds.push(sound);
return sound;
},
/**
* Unlocks HTML5 Audio loading and playback on mobile
* devices on the initial explicit user interaction.
*
* @method Phaser.Sound.HTML5AudioSoundManager#unlock
* @since 3.0.0
*/
unlock: function() {
this.locked = false;
var _this = this;
this.game.cache.audio.entries.each(function(key, tags) {
for (var i = 0; i < tags.length; i++) {
if (tags[i].dataset.locked === "true") {
_this.locked = true;
return false;
}
}
return true;
});
if (!this.locked) {
return;
}
var moved = false;
var detectMove = function() {
moved = true;
};
var unlock = function() {
if (moved) {
moved = false;
return;
}
document.body.removeEventListener("touchmove", detectMove);
document.body.removeEventListener("touchend", unlock);
var lockedTags = [];
_this.game.cache.audio.entries.each(function(key, tags) {
for (var i = 0; i < tags.length; i++) {
var tag = tags[i];
if (tag.dataset.locked === "true") {
lockedTags.push(tag);
}
}
return true;
});
if (lockedTags.length === 0) {
return;
}
var lastTag = lockedTags[lockedTags.length - 1];
lastTag.oncanplaythrough = function() {
lastTag.oncanplaythrough = null;
lockedTags.forEach(function(tag) {
tag.dataset.locked = "false";
});
_this.unlocked = true;
};
lockedTags.forEach(function(tag) {
tag.load();
});
};
this.once(Events.UNLOCKED, function() {
this.forEachActiveSound(function(sound) {
if (sound.currentMarker === null && sound.duration === 0) {
sound.duration = sound.tags[0].duration;
}
sound.totalDuration = sound.tags[0].duration;
});
while (this.lockedActionsQueue.length) {
var lockedAction = this.lockedActionsQueue.shift();
if (lockedAction.sound[lockedAction.prop].apply) {
lockedAction.sound[lockedAction.prop].apply(lockedAction.sound, lockedAction.value || []);
} else {
lockedAction.sound[lockedAction.prop] = lockedAction.value;
}
}
}, this);
document.body.addEventListener("touchmove", detectMove, false);
document.body.addEventListener("touchend", unlock, false);
},
/**
* Method used internally for pausing sound manager if
* Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true.
*
* @method Phaser.Sound.HTML5AudioSoundManager#onBlur
* @protected
* @since 3.0.0
*/
onBlur: function() {
this.forEachActiveSound(function(sound) {
if (sound.isPlaying) {
this.onBlurPausedSounds.push(sound);
sound.onBlur();
}
});
},
/**
* Method used internally for resuming sound manager if
* Phaser.Sound.HTML5AudioSoundManager#pauseOnBlur is set to true.
*
* @method Phaser.Sound.HTML5AudioSoundManager#onFocus
* @protected
* @since 3.0.0
*/
onFocus: function() {
this.onBlurPausedSounds.forEach(function(sound) {
sound.onFocus();
});
this.onBlurPausedSounds.length = 0;
},
/**
* Calls Phaser.Sound.BaseSoundManager#destroy method
* and cleans up all HTML5 Audio related stuff.
*
* @method Phaser.Sound.HTML5AudioSoundManager#destroy
* @since 3.0.0
*/
destroy: function() {
BaseSoundManager.prototype.destroy.call(this);
this.onBlurPausedSounds.length = 0;
this.onBlurPausedSounds = null;
},
/**
* Method used internally by Phaser.Sound.HTML5AudioSound class methods and property setters
* to check if sound manager is locked and then either perform action immediately or queue it
* to be performed once the sound manager gets unlocked.
*
* @method Phaser.Sound.HTML5AudioSoundManager#isLocked
* @protected
* @since 3.0.0
*
* @param {Phaser.Sound.HTML5AudioSound} sound - Sound object on which to perform queued action.
* @param {string} prop - Name of the method to be called or property to be assigned a value to.
* @param {*} [value] - An optional parameter that either holds an array of arguments to be passed to the method call or value to be set to the property.
*
* @return {boolean} Whether the sound manager is locked.
*/
isLocked: function(sound, prop, value) {
if (sound.tags[0].dataset.locked === "true") {
this.lockedActionsQueue.push({
sound,
prop,
value
});
return true;
}
return false;
},
/**
* Sets the muted state of all this Sound Manager.
*
* @method Phaser.Sound.HTML5AudioSoundManager#setMute
* @fires Phaser.Sound.Events#GLOBAL_MUTE
* @since 3.3.0
*
* @param {boolean} value - `true` to mute all sounds, `false` to unmute them.
*
* @return {Phaser.Sound.HTML5AudioSoundManager} This Sound Manager.
*/
setMute: function(value) {
this.mute = value;
return this;
},
/**
* @name Phaser.Sound.HTML5AudioSoundManager#mute
* @type {boolean}
* @fires Phaser.Sound.Events#GLOBAL_MUTE
* @since 3.0.0
*/
mute: {
get: function() {
return this._mute;
},
set: function(value) {
this._mute = value;
this.forEachActiveSound(function(sound) {
sound.updateMute();
});
this.emit(Events.GLOBAL_MUTE, this, value);
}
},
/**
* Sets the volume of this Sound Manager.
*
* @method Phaser.Sound.HTML5AudioSoundManager#setVolume
* @fires Phaser.Sound.Events#GLOBAL_VOLUME
* @since 3.3.0
*
* @param {number} value - The global volume of this Sound Manager.
*
* @return {Phaser.Sound.HTML5AudioSoundManager} This Sound Manager.
*/
setVolume: function(value) {
this.volume = value;
return this;
},
/**
* @name Phaser.Sound.HTML5AudioSoundManager#volume
* @type {number}
* @fires Phaser.Sound.Events#GLOBAL_VOLUME
* @since 3.0.0
*/
volume: {
get: function() {
return this._volume;
},
set: function(value) {
this._volume = value;
this.forEachActiveSound(function(sound) {
sound.updateVolume();
});
this.emit(Events.GLOBAL_VOLUME, this, value);
}
}
});
module2.exports = HTML5AudioSoundManager;
}
),
/***/
23717: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
SoundManagerCreator: __webpack_require__2(14747),
Events: __webpack_require__2(14463),
BaseSound: __webpack_require__2(30341),
BaseSoundManager: __webpack_require__2(85034),
WebAudioSound: __webpack_require__2(71741),
WebAudioSoundManager: __webpack_require__2(57490),
HTML5AudioSound: __webpack_require__2(64895),
HTML5AudioSoundManager: __webpack_require__2(33684),
NoAudioSound: __webpack_require__2(4603),
NoAudioSoundManager: __webpack_require__2(25960)
};
}
),
/***/
4603: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BaseSound = __webpack_require__2(30341);
var Class = __webpack_require__2(83419);
var EventEmitter = __webpack_require__2(50792);
var Extend = __webpack_require__2(79291);
var NOOP = __webpack_require__2(29747);
var returnFalse = function() {
return false;
};
var returnNull = function() {
return null;
};
var returnThis = function() {
return this;
};
var NoAudioSound = new Class({
Extends: EventEmitter,
initialize: function NoAudioSound2(manager, key, config) {
if (config === void 0) {
config = {};
}
EventEmitter.call(this);
this.manager = manager;
this.key = key;
this.isPlaying = false;
this.isPaused = false;
this.totalRate = 1;
this.duration = 0;
this.totalDuration = 0;
this.config = Extend({
mute: false,
volume: 1,
rate: 1,
detune: 0,
seek: 0,
loop: false,
delay: 0,
pan: 0
}, config);
this.currentConfig = this.config;
this.mute = false;
this.volume = 1;
this.rate = 1;
this.detune = 0;
this.seek = 0;
this.loop = false;
this.pan = 0;
this.markers = {};
this.currentMarker = null;
this.pendingRemove = false;
},
/**
* @method Phaser.Sound.NoAudioSound#addMarker
* @since 3.0.0
*
* @param {Phaser.Types.Sound.SoundMarker} marker - Marker object.
*
* @return {boolean} false
*/
addMarker: returnFalse,
/**
* @method Phaser.Sound.NoAudioSound#updateMarker
* @since 3.0.0
*
* @param {Phaser.Types.Sound.SoundMarker} marker - Marker object with updated values.
*
* @return {boolean} false
*/
updateMarker: returnFalse,
/**
* @method Phaser.Sound.NoAudioSound#removeMarker
* @since 3.0.0
*
* @param {string} markerName - The name of the marker to remove.
*
* @return {null} null
*/
removeMarker: returnNull,
/**
* @method Phaser.Sound.NoAudioSound#play
* @since 3.0.0
*
* @param {(string|Phaser.Types.Sound.SoundConfig)} [markerName=''] - If you want to play a marker then provide the marker name here. Alternatively, this parameter can be a SoundConfig object.
* @param {Phaser.Types.Sound.SoundConfig} [config] - Optional sound config object to be applied to this marker or entire sound if no marker name is provided. It gets memorized for future plays of current section of the sound.
*
* @return {boolean} false
*/
play: returnFalse,
/**
* @method Phaser.Sound.NoAudioSound#pause
* @since 3.0.0
*
* @return {boolean} false
*/
pause: returnFalse,
/**
* Resumes the sound.
*
* @method Phaser.Sound.NoAudioSound#resume
* @since 3.0.0
*
* @return {boolean} false
*/
resume: returnFalse,
/**
* Stop playing this sound.
*
* @method Phaser.Sound.NoAudioSound#stop
* @since 3.0.0
*
* @return {boolean} false
*/
stop: returnFalse,
/**
* Sets the muted state of this Sound.
*
* @method Phaser.Sound.NoAudioSound#setMute
* @since 3.4.0
*
* @param {boolean} value - `true` to mute this sound, `false` to unmute it.
*
* @return {this} This Sound instance.
*/
setMute: returnThis,
/**
* Sets the volume of this Sound.
*
* @method Phaser.Sound.NoAudioSound#setVolume
* @since 3.4.0
*
* @param {number} value - The volume of the sound.
*
* @return {this} This Sound instance.
*/
setVolume: returnThis,
/**
* Sets the playback rate of this Sound.
*
* For example, a value of 1.0 plays the audio at full speed, 0.5 plays the audio at half speed
* and 2.0 doubles the audios playback speed.
*
* @method Phaser.Sound.NoAudioSound#setRate
* @since 3.3.0
*
* @param {number} value - The playback rate at of this Sound.
*
* @return {this} This Sound instance.
*/
setRate: returnThis,
/**
* Sets the detune value of this Sound, given in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29).
* The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent).
*
* @method Phaser.Sound.NoAudioSound#setDetune
* @since 3.3.0
*
* @param {number} value - The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent).
*
* @return {this} This Sound instance.
*/
setDetune: returnThis,
/**
* Seeks to a specific point in this sound.
*
* @method Phaser.Sound.NoAudioSound#setSeek
* @since 3.4.0
*
* @param {number} value - The point in the sound to seek to.
*
* @return {this} This Sound instance.
*/
setSeek: returnThis,
/**
* Sets the loop state of this Sound.
*
* @method Phaser.Sound.NoAudioSound#setLoop
* @since 3.4.0
*
* @param {boolean} value - `true` to loop this sound, `false` to not loop it.
*
* @return {this} This Sound instance.
*/
setLoop: returnThis,
/**
* Sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan).
*
* Note: iOS / Safari doesn't support the stereo panner node.
*
* @method Phaser.Sound.NoAudioSound#setPan
* @since 3.50.0
*
* @param {number} value - The pan of the sound. A value between -1 (full left pan) and 1 (full right pan).
*
* @return {this} This Sound instance.
*/
setPan: returnThis,
/**
* Method used internally for applying config values to some of the sound properties.
*
* @method Phaser.Sound.NoAudioSound#applyConfig
* @since 3.0.0
*/
applyConfig: returnNull,
/**
* Method used internally for resetting values of some of the config properties.
*
* @method Phaser.Sound.NoAudioSound#resetConfig
* @since 3.0.0
*/
resetConfig: returnNull,
/**
* Update method called automatically by sound manager on every game step.
*
* @method Phaser.Sound.NoAudioSound#update
* @override
* @since 3.0.0
*
* @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout.
* @param {number} delta - The delta time elapsed since the last frame.
*/
update: NOOP,
/**
* Method used internally to calculate total playback rate of the sound.
*
* @method Phaser.Sound.NoAudioSound#calculateRate
* @since 3.0.0
*/
calculateRate: returnNull,
/**
* Destroys this sound and all associated events and marks it for removal from the sound manager.
*
* @method Phaser.Sound.NoAudioSound#destroy
* @fires Phaser.Sound.Events#DESTROY
* @since 3.0.0
*/
destroy: function() {
BaseSound.prototype.destroy.call(this);
}
});
module2.exports = NoAudioSound;
}
),
/***/
25960: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BaseSoundManager = __webpack_require__2(85034);
var Class = __webpack_require__2(83419);
var EventEmitter = __webpack_require__2(50792);
var NoAudioSound = __webpack_require__2(4603);
var NOOP = __webpack_require__2(29747);
var NoAudioSoundManager = new Class({
Extends: EventEmitter,
initialize: function NoAudioSoundManager2(game) {
EventEmitter.call(this);
this.game = game;
this.sounds = [];
this.mute = false;
this.volume = 1;
this.rate = 1;
this.detune = 0;
this.pauseOnBlur = true;
this.locked = false;
},
/**
* Adds a new sound into the sound manager.
*
* @method Phaser.Sound.NoAudioSoundManager#add
* @since 3.60.0
*
* @param {string} key - Asset key for the sound.
* @param {Phaser.Types.Sound.SoundConfig} [config] - An optional config object containing default sound settings.
*
* @return {Phaser.Sound.NoAudioSound} The new sound instance.
*/
add: function(key, config) {
var sound = new NoAudioSound(this, key, config);
this.sounds.push(sound);
return sound;
},
/**
* Adds a new audio sprite sound into the sound manager.
* Audio Sprites are a combination of audio files and a JSON configuration.
* The JSON follows the format of that created by https://github.com/tonistiigi/audiosprite
*
* @method Phaser.Sound.NoAudioSoundManager#addAudioSprite
* @since 3.60.0
*
* @param {string} key - Asset key for the sound.
* @param {Phaser.Types.Sound.SoundConfig} [config] - An optional config object containing default sound settings.
*
* @return {Phaser.Sound.NoAudioSound} The new audio sprite sound instance.
*/
addAudioSprite: function(key, config) {
var sound = this.add(key, config);
sound.spritemap = {};
return sound;
},
/**
* Gets the first sound in the manager matching the given key, if any.
*
* @method Phaser.Sound.NoAudioSoundManager#get
* @since 3.23.0
*
* @generic {Phaser.Sound.BaseSound} T
* @genericUse {T} - [$return]
*
* @param {string} key - Sound asset key.
*
* @return {?Phaser.Sound.BaseSound} - The sound, or null.
*/
get: function(key) {
return BaseSoundManager.prototype.get.call(this, key);
},
/**
* Gets any sounds in the manager matching the given key.
*
* @method Phaser.Sound.NoAudioSoundManager#getAll
* @since 3.23.0
*
* @generic {Phaser.Sound.BaseSound} T
* @genericUse {T[]} - [$return]
*
* @param {string} key - Sound asset key.
*
* @return {Phaser.Sound.BaseSound[]} - The sounds, or an empty array.
*/
getAll: function(key) {
return BaseSoundManager.prototype.getAll.call(this, key);
},
/**
* This method does nothing but return 'false' for the No Audio Sound Manager, to maintain
* compatibility with the other Sound Managers.
*
* @method Phaser.Sound.NoAudioSoundManager#play
* @since 3.0.0
*
* @param {string} key - Asset key for the sound.
* @param {(Phaser.Types.Sound.SoundConfig|Phaser.Types.Sound.SoundMarker)} [extra] - An optional additional object containing settings to be applied to the sound. It could be either config or marker object.
*
* @return {boolean} Always 'false' for the No Audio Sound Manager.
*/
// eslint-disable-next-line no-unused-vars
play: function(key, extra) {
return false;
},
/**
* This method does nothing but return 'false' for the No Audio Sound Manager, to maintain
* compatibility with the other Sound Managers.
*
* @method Phaser.Sound.NoAudioSoundManager#playAudioSprite
* @since 3.0.0
*
* @param {string} key - Asset key for the sound.
* @param {string} spriteName - The name of the sound sprite to play.
* @param {Phaser.Types.Sound.SoundConfig} [config] - An optional config object containing default sound settings.
*
* @return {boolean} Always 'false' for the No Audio Sound Manager.
*/
// eslint-disable-next-line no-unused-vars
playAudioSprite: function(key, spriteName, config) {
return false;
},
/**
* Removes a sound from the sound manager.
* The removed sound is destroyed before removal.
*
* @method Phaser.Sound.NoAudioSoundManager#remove
* @since 3.0.0
*
* @param {Phaser.Sound.BaseSound} sound - The sound object to remove.
*
* @return {boolean} True if the sound was removed successfully, otherwise false.
*/
remove: function(sound) {
return BaseSoundManager.prototype.remove.call(this, sound);
},
/**
* Removes all sounds from the manager, destroying the sounds.
*
* @method Phaser.Sound.NoAudioSoundManager#removeAll
* @since 3.23.0
*/
removeAll: function() {
return BaseSoundManager.prototype.removeAll.call(this);
},
/**
* Removes all sounds from the sound manager that have an asset key matching the given value.
* The removed sounds are destroyed before removal.
*
* @method Phaser.Sound.NoAudioSoundManager#removeByKey
* @since 3.0.0
*
* @param {string} key - The key to match when removing sound objects.
*
* @return {number} The number of matching sound objects that were removed.
*/
removeByKey: function(key) {
return BaseSoundManager.prototype.removeByKey.call(this, key);
},
/**
* Stops any sounds matching the given key.
*
* @method Phaser.Sound.NoAudioSoundManager#stopByKey
* @since 3.23.0
*
* @param {string} key - Sound asset key.
*
* @return {number} - How many sounds were stopped.
*/
stopByKey: function(key) {
return BaseSoundManager.prototype.stopByKey.call(this, key);
},
/**
* Empty function for the No Audio Sound Manager.
*
* @method Phaser.Sound.NoAudioSoundManager#onBlur
* @since 3.0.0
*/
onBlur: NOOP,
/**
* Empty function for the No Audio Sound Manager.
*
* @method Phaser.Sound.NoAudioSoundManager#onFocus
* @since 3.0.0
*/
onFocus: NOOP,
/**
* Empty function for the No Audio Sound Manager.
*
* @method Phaser.Sound.NoAudioSoundManager#onGameBlur
* @since 3.0.0
*/
onGameBlur: NOOP,
/**
* Empty function for the No Audio Sound Manager.
*
* @method Phaser.Sound.NoAudioSoundManager#onGameFocus
* @since 3.0.0
*/
onGameFocus: NOOP,
/**
* Empty function for the No Audio Sound Manager.
*
* @method Phaser.Sound.NoAudioSoundManager#pauseAll
* @since 3.0.0
*/
pauseAll: NOOP,
/**
* Empty function for the No Audio Sound Manager.
*
* @method Phaser.Sound.NoAudioSoundManager#resumeAll
* @since 3.0.0
*/
resumeAll: NOOP,
/**
* Empty function for the No Audio Sound Manager.
*
* @method Phaser.Sound.NoAudioSoundManager#stopAll
* @since 3.0.0
*/
stopAll: NOOP,
/**
* Empty function for the No Audio Sound Manager.
*
* @method Phaser.Sound.NoAudioSoundManager#update
* @since 3.0.0
*/
update: NOOP,
/**
* Empty function for the No Audio Sound Manager.
*
* @method Phaser.Sound.NoAudioSoundManager#setRate
* @since 3.0.0
*
* @return {this} This Sound Manager.
*/
setRate: NOOP,
/**
* Empty function for the No Audio Sound Manager.
*
* @method Phaser.Sound.NoAudioSoundManager#setDetune
* @since 3.0.0
*
* @return {this} This Sound Manager.
*/
setDetune: NOOP,
/**
* Empty function for the No Audio Sound Manager.
*
* @method Phaser.Sound.NoAudioSoundManager#setMute
* @since 3.0.0
*/
setMute: NOOP,
/**
* Empty function for the No Audio Sound Manager.
*
* @method Phaser.Sound.NoAudioSoundManager#setVolume
* @since 3.0.0
*/
setVolume: NOOP,
/**
* Empty function for the No Audio Sound Manager.
*
* @method Phaser.Sound.NoAudioSoundManager#unlock
* @since 3.0.0
*/
unlock: NOOP,
/**
* Method used internally for iterating only over active sounds and skipping sounds that are marked for removal.
*
* @method Phaser.Sound.NoAudioSoundManager#forEachActiveSound
* @private
* @since 3.0.0
*
* @param {Phaser.Types.Sound.EachActiveSoundCallback} callback - Callback function. (manager: Phaser.Sound.BaseSoundManager, sound: Phaser.Sound.BaseSound, index: number, sounds: Phaser.Manager.BaseSound[]) => void
* @param {*} [scope] - Callback context.
*/
forEachActiveSound: function(callbackfn, scope) {
BaseSoundManager.prototype.forEachActiveSound.call(this, callbackfn, scope);
},
/**
* Destroys all the sounds in the game and all associated events.
*
* @method Phaser.Sound.NoAudioSoundManager#destroy
* @since 3.0.0
*/
destroy: function() {
BaseSoundManager.prototype.destroy.call(this);
}
});
module2.exports = NoAudioSoundManager;
}
),
/***/
71741: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BaseSound = __webpack_require__2(30341);
var Class = __webpack_require__2(83419);
var Events = __webpack_require__2(14463);
var GetFastValue = __webpack_require__2(95540);
var WebAudioSound = new Class({
Extends: BaseSound,
initialize: function WebAudioSound2(manager, key, config) {
if (config === void 0) {
config = {};
}
this.audioBuffer = manager.game.cache.audio.get(key);
if (!this.audioBuffer) {
throw new Error('Audio key "' + key + '" not found in cache');
}
this.source = null;
this.loopSource = null;
this.muteNode = manager.context.createGain();
this.volumeNode = manager.context.createGain();
this.pannerNode = null;
this.spatialNode = null;
this.spatialSource = null;
this.playTime = 0;
this.startTime = 0;
this.loopTime = 0;
this.rateUpdates = [];
this.hasEnded = false;
this.hasLooped = false;
this.muteNode.connect(this.volumeNode);
if (manager.context.createPanner) {
this.spatialNode = manager.context.createPanner();
this.volumeNode.connect(this.spatialNode);
}
if (manager.context.createStereoPanner) {
this.pannerNode = manager.context.createStereoPanner();
if (manager.context.createPanner) {
this.spatialNode.connect(this.pannerNode);
} else {
this.volumeNode.connect(this.pannerNode);
}
this.pannerNode.connect(manager.destination);
} else if (manager.context.createPanner) {
this.spatialNode.connect(manager.destination);
} else {
this.volumeNode.connect(manager.destination);
}
this.duration = this.audioBuffer.duration;
this.totalDuration = this.audioBuffer.duration;
BaseSound.call(this, manager, key, config);
},
/**
* Play this sound, or a marked section of it.
*
* It always plays the sound from the start. If you want to start playback from a specific time
* you can set 'seek' setting of the config object, provided to this call, to that value.
*
* If you want to play the same sound simultaneously, then you need to create another instance
* of it and play that Sound.
*
* @method Phaser.Sound.WebAudioSound#play
* @fires Phaser.Sound.Events#PLAY
* @since 3.0.0
*
* @param {(string|Phaser.Types.Sound.SoundConfig)} [markerName=''] - If you want to play a marker then provide the marker name here. Alternatively, this parameter can be a SoundConfig object.
* @param {Phaser.Types.Sound.SoundConfig} [config] - Optional sound config object to be applied to this marker or entire sound if no marker name is provided. It gets memorized for future plays of current section of the sound.
*
* @return {boolean} Whether the sound started playing successfully.
*/
play: function(markerName, config) {
if (!BaseSound.prototype.play.call(this, markerName, config)) {
return false;
}
this.stopAndRemoveBufferSource();
this.createAndStartBufferSource();
this.emit(Events.PLAY, this);
return true;
},
/**
* Pauses the sound.
*
* @method Phaser.Sound.WebAudioSound#pause
* @fires Phaser.Sound.Events#PAUSE
* @since 3.0.0
*
* @return {boolean} Whether the sound was paused successfully.
*/
pause: function() {
if (this.manager.context.currentTime < this.startTime) {
return false;
}
if (!BaseSound.prototype.pause.call(this)) {
return false;
}
this.currentConfig.seek = this.getCurrentTime();
this.stopAndRemoveBufferSource();
this.emit(Events.PAUSE, this);
return true;
},
/**
* Resumes the sound.
*
* @method Phaser.Sound.WebAudioSound#resume
* @fires Phaser.Sound.Events#RESUME
* @since 3.0.0
*
* @return {boolean} Whether the sound was resumed successfully.
*/
resume: function() {
if (this.manager.context.currentTime < this.startTime) {
return false;
}
if (!BaseSound.prototype.resume.call(this)) {
return false;
}
this.createAndStartBufferSource();
this.emit(Events.RESUME, this);
return true;
},
/**
* Stop playing this sound.
*
* @method Phaser.Sound.WebAudioSound#stop
* @fires Phaser.Sound.Events#STOP
* @since 3.0.0
*
* @return {boolean} Whether the sound was stopped successfully.
*/
stop: function() {
if (!BaseSound.prototype.stop.call(this)) {
return false;
}
this.stopAndRemoveBufferSource();
this.emit(Events.STOP, this);
return true;
},
/**
* Used internally.
*
* @method Phaser.Sound.WebAudioSound#createAndStartBufferSource
* @private
* @since 3.0.0
*/
createAndStartBufferSource: function() {
var seek = this.currentConfig.seek;
var delay = this.currentConfig.delay;
var when = this.manager.context.currentTime + delay;
var offset = (this.currentMarker ? this.currentMarker.start : 0) + seek;
var duration = this.duration - seek;
this.playTime = when - seek;
this.startTime = when;
this.source = this.createBufferSource();
this.applyConfig();
this.source.start(Math.max(0, when), Math.max(0, offset), Math.max(0, duration));
this.resetConfig();
},
/**
* This method is only used internally and it creates a looping buffer source.
*
* @method Phaser.Sound.WebAudioSound#createAndStartLoopBufferSource
* @since 3.0.0
*/
createAndStartLoopBufferSource: function() {
var when = this.getLoopTime();
var offset = this.currentMarker ? this.currentMarker.start : 0;
var duration = this.duration;
this.loopTime = when;
this.loopSource = this.createBufferSource();
this.loopSource.playbackRate.setValueAtTime(this.totalRate, 0);
this.loopSource.start(Math.max(0, when), Math.max(0, offset), Math.max(0, duration));
},
/**
* This method is only used internally and it creates a buffer source.
*
* @method Phaser.Sound.WebAudioSound#createBufferSource
* @since 3.0.0
*
* @return {AudioBufferSourceNode}
*/
createBufferSource: function() {
var _this = this;
var source = this.manager.context.createBufferSource();
source.buffer = this.audioBuffer;
source.connect(this.muteNode);
source.onended = function(ev) {
var target = ev.target;
if (target === _this.source || target === _this.loopSource) {
if (_this.currentConfig.loop) {
_this.hasLooped = true;
} else {
_this.hasEnded = true;
}
}
};
return source;
},
/**
* This method is only used internally and it stops and removes a buffer source.
*
* @method Phaser.Sound.WebAudioSound#stopAndRemoveBufferSource
* @since 3.0.0
*/
stopAndRemoveBufferSource: function() {
if (this.source) {
var tempSource = this.source;
this.source = null;
tempSource.stop();
tempSource.disconnect();
}
this.playTime = 0;
this.startTime = 0;
this.hasEnded = false;
this.stopAndRemoveLoopBufferSource();
},
/**
* This method is only used internally and it stops and removes a looping buffer source.
*
* @method Phaser.Sound.WebAudioSound#stopAndRemoveLoopBufferSource
* @since 3.0.0
*/
stopAndRemoveLoopBufferSource: function() {
if (this.loopSource) {
this.loopSource.stop();
this.loopSource.disconnect();
this.loopSource = null;
}
this.loopTime = 0;
},
/**
* Method used internally for applying config values to some of the sound properties.
*
* @method Phaser.Sound.WebAudioSound#applyConfig
* @since 3.0.0
*/
applyConfig: function() {
this.rateUpdates.length = 0;
this.rateUpdates.push({
time: 0,
rate: 1
});
var source = this.currentConfig.source;
if (source && this.manager.context.createPanner) {
var node = this.spatialNode;
node.panningModel = GetFastValue(source, "panningModel", "equalpower");
node.distanceModel = GetFastValue(source, "distanceModel", "inverse");
node.orientationX.value = GetFastValue(source, "orientationX", 0);
node.orientationY.value = GetFastValue(source, "orientationY", 0);
node.orientationZ.value = GetFastValue(source, "orientationZ", -1);
node.refDistance = GetFastValue(source, "refDistance", 1);
node.maxDistance = GetFastValue(source, "maxDistance", 1e4);
node.rolloffFactor = GetFastValue(source, "rolloffFactor", 1);
node.coneInnerAngle = GetFastValue(source, "coneInnerAngle", 360);
node.coneOuterAngle = GetFastValue(source, "coneOuterAngle", 0);
node.coneOuterGain = GetFastValue(source, "coneOuterGain", 0);
this.spatialSource = GetFastValue(source, "follow", null);
if (!this.spatialSource) {
node.positionX.value = GetFastValue(source, "x", 0);
node.positionY.value = GetFastValue(source, "y", 0);
node.positionZ.value = GetFastValue(source, "z", 0);
}
}
BaseSound.prototype.applyConfig.call(this);
},
/**
* Sets the x position of this Sound in Spatial Audio space.
*
* This only has any effect if the sound was created with a SpatialSoundConfig object.
*
* Also see the `WebAudioSoundManager.setListenerPosition` method.
*
* If you find that the sound becomes too quiet, too quickly, as it moves away from
* the listener, then try different `refDistance` property values when configuring
* the spatial sound.
*
* @name Phaser.Sound.WebAudioSound#x
* @type {number}
* @since 3.60.0
*/
x: {
get: function() {
if (this.spatialNode) {
return this.spatialNode.positionX;
} else {
return 0;
}
},
set: function(value) {
if (this.spatialNode) {
this.spatialNode.positionX.value = value;
}
}
},
/**
* Sets the y position of this Sound in Spatial Audio space.
*
* This only has any effect if the sound was created with a SpatialSoundConfig object.
*
* Also see the `WebAudioSoundManager.setListenerPosition` method.
*
* If you find that the sound becomes too quiet, too quickly, as it moves away from
* the listener, then try different `refDistance` property values when configuring
* the spatial sound.
*
* @name Phaser.Sound.WebAudioSound#y
* @type {number}
* @since 3.60.0
*/
y: {
get: function() {
if (this.spatialNode) {
return this.spatialNode.positionY;
} else {
return 0;
}
},
set: function(value) {
if (this.spatialNode) {
this.spatialNode.positionY.value = value;
}
}
},
/**
* Update method called automatically by sound manager on every game step.
*
* @method Phaser.Sound.WebAudioSound#update
* @fires Phaser.Sound.Events#COMPLETE
* @fires Phaser.Sound.Events#LOOPED
* @since 3.0.0
*/
update: function() {
if (this.isPlaying && this.spatialSource) {
var x = GetFastValue(this.spatialSource, "x", null);
var y = GetFastValue(this.spatialSource, "y", null);
if (x && x !== this._spatialx) {
this._spatialx = this.spatialNode.positionX.value = x;
}
if (y && y !== this._spatialy) {
this._spatialy = this.spatialNode.positionY.value = y;
}
}
if (this.hasEnded) {
BaseSound.prototype.stop.call(this);
this.stopAndRemoveBufferSource();
this.emit(Events.COMPLETE, this);
} else if (this.hasLooped) {
this.hasLooped = false;
this.source = this.loopSource;
this.loopSource = null;
this.playTime = this.startTime = this.loopTime;
this.rateUpdates.length = 0;
this.rateUpdates.push({
time: 0,
rate: this.totalRate
});
this.createAndStartLoopBufferSource();
this.emit(Events.LOOPED, this);
}
},
/**
* Calls Phaser.Sound.BaseSound#destroy method
* and cleans up all Web Audio API related stuff.
*
* @method Phaser.Sound.WebAudioSound#destroy
* @since 3.0.0
*/
destroy: function() {
if (this.pendingRemove) {
return;
}
BaseSound.prototype.destroy.call(this);
this.audioBuffer = null;
this.stopAndRemoveBufferSource();
this.muteNode.disconnect();
this.muteNode = null;
this.volumeNode.disconnect();
this.volumeNode = null;
if (this.pannerNode) {
this.pannerNode.disconnect();
this.pannerNode = null;
}
if (this.spatialNode) {
this.spatialNode.disconnect();
this.spatialNode = null;
this.spatialSource = null;
}
this.rateUpdates.length = 0;
this.rateUpdates = null;
},
/**
* Method used internally to calculate total playback rate of the sound.
*
* @method Phaser.Sound.WebAudioSound#calculateRate
* @since 3.0.0
*/
calculateRate: function() {
BaseSound.prototype.calculateRate.call(this);
var now = this.manager.context.currentTime;
if (this.source && typeof this.totalRate === "number") {
this.source.playbackRate.setValueAtTime(this.totalRate, now);
}
if (this.isPlaying) {
this.rateUpdates.push({
time: Math.max(this.startTime, now) - this.playTime,
rate: this.totalRate
});
if (this.loopSource) {
this.stopAndRemoveLoopBufferSource();
this.createAndStartLoopBufferSource();
}
}
},
/**
* Method used internally for calculating current playback time of a playing sound.
*
* @method Phaser.Sound.WebAudioSound#getCurrentTime
* @since 3.0.0
*/
getCurrentTime: function() {
var currentTime = 0;
for (var i = 0; i < this.rateUpdates.length; i++) {
var nextTime = 0;
if (i < this.rateUpdates.length - 1) {
nextTime = this.rateUpdates[i + 1].time;
} else {
nextTime = this.manager.context.currentTime - this.playTime;
}
currentTime += (nextTime - this.rateUpdates[i].time) * this.rateUpdates[i].rate;
}
return currentTime;
},
/**
* Method used internally for calculating the time
* at witch the loop source should start playing.
*
* @method Phaser.Sound.WebAudioSound#getLoopTime
* @since 3.0.0
*/
getLoopTime: function() {
var lastRateUpdateCurrentTime = 0;
for (var i = 0; i < this.rateUpdates.length - 1; i++) {
lastRateUpdateCurrentTime += (this.rateUpdates[i + 1].time - this.rateUpdates[i].time) * this.rateUpdates[i].rate;
}
var lastRateUpdate = this.rateUpdates[this.rateUpdates.length - 1];
return this.playTime + lastRateUpdate.time + (this.duration - lastRateUpdateCurrentTime) / lastRateUpdate.rate;
},
/**
* Rate at which this Sound will be played.
* Value of 1.0 plays the audio at full speed, 0.5 plays the audio at half speed
* and 2.0 doubles the audios playback speed.
*
* @name Phaser.Sound.WebAudioSound#rate
* @type {number}
* @default 1
* @fires Phaser.Sound.Events#RATE
* @since 3.0.0
*/
rate: {
get: function() {
return this.currentConfig.rate;
},
set: function(value) {
this.currentConfig.rate = value;
this.calculateRate();
this.emit(Events.RATE, this, value);
}
},
/**
* Sets the playback rate of this Sound.
*
* For example, a value of 1.0 plays the audio at full speed, 0.5 plays the audio at half speed
* and 2.0 doubles the audios playback speed.
*
* @method Phaser.Sound.WebAudioSound#setRate
* @fires Phaser.Sound.Events#RATE
* @since 3.3.0
*
* @param {number} value - The playback rate at of this Sound.
*
* @return {this} This Sound instance.
*/
setRate: function(value) {
this.rate = value;
return this;
},
/**
* The detune value of this Sound, given in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29).
* The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent).
*
* @name Phaser.Sound.WebAudioSound#detune
* @type {number}
* @default 0
* @fires Phaser.Sound.Events#DETUNE
* @since 3.0.0
*/
detune: {
get: function() {
return this.currentConfig.detune;
},
set: function(value) {
this.currentConfig.detune = value;
this.calculateRate();
this.emit(Events.DETUNE, this, value);
}
},
/**
* Sets the detune value of this Sound, given in [cents](https://en.wikipedia.org/wiki/Cent_%28music%29).
* The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent).
*
* @method Phaser.Sound.WebAudioSound#setDetune
* @fires Phaser.Sound.Events#DETUNE
* @since 3.3.0
*
* @param {number} value - The range of the value is -1200 to 1200, but we recommend setting it to [50](https://en.wikipedia.org/wiki/50_Cent).
*
* @return {this} This Sound instance.
*/
setDetune: function(value) {
this.detune = value;
return this;
},
/**
* Boolean indicating whether the sound is muted or not.
* Gets or sets the muted state of this sound.
*
* @name Phaser.Sound.WebAudioSound#mute
* @type {boolean}
* @default false
* @fires Phaser.Sound.Events#MUTE
* @since 3.0.0
*/
mute: {
get: function() {
return this.muteNode.gain.value === 0;
},
set: function(value) {
this.currentConfig.mute = value;
this.muteNode.gain.setValueAtTime(value ? 0 : 1, 0);
this.emit(Events.MUTE, this, value);
}
},
/**
* Sets the muted state of this Sound.
*
* @method Phaser.Sound.WebAudioSound#setMute
* @fires Phaser.Sound.Events#MUTE
* @since 3.4.0
*
* @param {boolean} value - `true` to mute this sound, `false` to unmute it.
*
* @return {this} This Sound instance.
*/
setMute: function(value) {
this.mute = value;
return this;
},
/**
* Gets or sets the volume of this sound, a value between 0 (silence) and 1 (full volume).
*
* @name Phaser.Sound.WebAudioSound#volume
* @type {number}
* @default 1
* @fires Phaser.Sound.Events#VOLUME
* @since 3.0.0
*/
volume: {
get: function() {
return this.volumeNode.gain.value;
},
set: function(value) {
this.currentConfig.volume = value;
this.volumeNode.gain.setValueAtTime(value, 0);
this.emit(Events.VOLUME, this, value);
}
},
/**
* Sets the volume of this Sound.
*
* @method Phaser.Sound.WebAudioSound#setVolume
* @fires Phaser.Sound.Events#VOLUME
* @since 3.4.0
*
* @param {number} value - The volume of the sound.
*
* @return {this} This Sound instance.
*/
setVolume: function(value) {
this.volume = value;
return this;
},
/**
* Property representing the position of playback for this sound, in seconds.
* Setting it to a specific value moves current playback to that position.
* The value given is clamped to the range 0 to current marker duration.
* Setting seek of a stopped sound has no effect.
*
* @name Phaser.Sound.WebAudioSound#seek
* @type {number}
* @fires Phaser.Sound.Events#SEEK
* @since 3.0.0
*/
seek: {
get: function() {
if (this.isPlaying) {
if (this.manager.context.currentTime < this.startTime) {
return this.startTime - this.playTime;
}
return this.getCurrentTime();
} else if (this.isPaused) {
return this.currentConfig.seek;
} else {
return 0;
}
},
set: function(value) {
if (this.manager.context.currentTime < this.startTime) {
return;
}
if (this.isPlaying || this.isPaused) {
value = Math.min(Math.max(0, value), this.duration);
this.currentConfig.seek = value;
if (this.isPlaying) {
this.stopAndRemoveBufferSource();
this.createAndStartBufferSource();
}
this.emit(Events.SEEK, this, value);
}
}
},
/**
* Seeks to a specific point in this sound.
*
* @method Phaser.Sound.WebAudioSound#setSeek
* @fires Phaser.Sound.Events#SEEK
* @since 3.4.0
*
* @param {number} value - The point in the sound to seek to.
*
* @return {this} This Sound instance.
*/
setSeek: function(value) {
this.seek = value;
return this;
},
/**
* Flag indicating whether or not the sound or current sound marker will loop.
*
* @name Phaser.Sound.WebAudioSound#loop
* @type {boolean}
* @default false
* @fires Phaser.Sound.Events#LOOP
* @since 3.0.0
*/
loop: {
get: function() {
return this.currentConfig.loop;
},
set: function(value) {
this.currentConfig.loop = value;
if (this.isPlaying) {
this.stopAndRemoveLoopBufferSource();
if (value) {
this.createAndStartLoopBufferSource();
}
}
this.emit(Events.LOOP, this, value);
}
},
/**
* Sets the loop state of this Sound.
*
* @method Phaser.Sound.WebAudioSound#setLoop
* @fires Phaser.Sound.Events#LOOP
* @since 3.4.0
*
* @param {boolean} value - `true` to loop this sound, `false` to not loop it.
*
* @return {this} This Sound instance.
*/
setLoop: function(value) {
this.loop = value;
return this;
},
/**
* Gets or sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan).
*
* Always returns zero on iOS / Safari as it doesn't support the stereo panner node.
*
* @name Phaser.Sound.WebAudioSound#pan
* @type {number}
* @default 0
* @fires Phaser.Sound.Events#PAN
* @since 3.50.0
*/
pan: {
get: function() {
if (this.pannerNode) {
return this.pannerNode.pan.value;
} else {
return 0;
}
},
set: function(value) {
this.currentConfig.pan = value;
if (this.pannerNode) {
this.pannerNode.pan.setValueAtTime(value, this.manager.context.currentTime);
}
this.emit(Events.PAN, this, value);
}
},
/**
* Sets the pan of this sound, a value between -1 (full left pan) and 1 (full right pan).
*
* Note: iOS / Safari doesn't support the stereo panner node.
*
* @method Phaser.Sound.WebAudioSound#setPan
* @fires Phaser.Sound.Events#PAN
* @since 3.50.0
*
* @param {number} value - The pan of the sound. A value between -1 (full left pan) and 1 (full right pan).
*
* @return {this} This Sound instance.
*/
setPan: function(value) {
this.pan = value;
return this;
}
});
module2.exports = WebAudioSound;
}
),
/***/
57490: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Base64ToArrayBuffer = __webpack_require__2(53134);
var BaseSoundManager = __webpack_require__2(85034);
var Class = __webpack_require__2(83419);
var Events = __webpack_require__2(14463);
var GameEvents = __webpack_require__2(8443);
var WebAudioSound = __webpack_require__2(71741);
var GetFastValue = __webpack_require__2(95540);
var WebAudioSoundManager = new Class({
Extends: BaseSoundManager,
initialize: function WebAudioSoundManager2(game) {
this.context = this.createAudioContext(game);
this.masterMuteNode = this.context.createGain();
this.masterVolumeNode = this.context.createGain();
this.masterMuteNode.connect(this.masterVolumeNode);
this.masterVolumeNode.connect(this.context.destination);
this.destination = this.masterMuteNode;
this.locked = this.context.state === "suspended" && ("ontouchstart" in window || "onclick" in window);
BaseSoundManager.call(this, game);
if (this.locked && game.isBooted) {
this.unlock();
} else {
game.events.once(GameEvents.BOOT, this.unlock, this);
}
},
/**
* Method responsible for instantiating and returning AudioContext instance.
* If an instance of an AudioContext class was provided through the game config,
* that instance will be returned instead. This can come in handy if you are reloading
* a Phaser game on a page that never properly refreshes (such as in an SPA project)
* and you want to reuse already instantiated AudioContext.
*
* @method Phaser.Sound.WebAudioSoundManager#createAudioContext
* @since 3.0.0
*
* @param {Phaser.Game} game - Reference to the current game instance.
*
* @return {AudioContext} The AudioContext instance to be used for playback.
*/
createAudioContext: function(game) {
var audioConfig = game.config.audio;
if (audioConfig.context) {
audioConfig.context.resume();
return audioConfig.context;
}
if (window.hasOwnProperty("AudioContext")) {
return new AudioContext();
} else if (window.hasOwnProperty("webkitAudioContext")) {
return new window.webkitAudioContext();
}
},
/**
* This method takes a new AudioContext reference and then sets
* this Sound Manager to use that context for all playback.
*
* As part of this call it also disconnects the master mute and volume
* nodes and then re-creates them on the new given context.
*
* @method Phaser.Sound.WebAudioSoundManager#setAudioContext
* @since 3.21.0
*
* @param {AudioContext} context - Reference to an already created AudioContext instance.
*
* @return {this} The WebAudioSoundManager instance.
*/
setAudioContext: function(context) {
if (this.context) {
this.context.close();
}
if (this.masterMuteNode) {
this.masterMuteNode.disconnect();
}
if (this.masterVolumeNode) {
this.masterVolumeNode.disconnect();
}
this.context = context;
this.masterMuteNode = context.createGain();
this.masterVolumeNode = context.createGain();
this.masterMuteNode.connect(this.masterVolumeNode);
this.masterVolumeNode.connect(context.destination);
this.destination = this.masterMuteNode;
return this;
},
/**
* Adds a new sound into the sound manager.
*
* @method Phaser.Sound.WebAudioSoundManager#add
* @since 3.0.0
*
* @param {string} key - Asset key for the sound.
* @param {Phaser.Types.Sound.SoundConfig} [config] - An optional config object containing default sound settings.
*
* @return {Phaser.Sound.WebAudioSound} The new sound instance.
*/
add: function(key, config) {
var sound = new WebAudioSound(this, key, config);
this.sounds.push(sound);
return sound;
},
/**
* Decode audio data into a format ready for playback via Web Audio.
*
* The audio data can be a base64 encoded string, an audio media-type data uri, or an ArrayBuffer instance.
*
* The `audioKey` is the key that will be used to save the decoded audio to the audio cache.
*
* Instead of passing a single entry you can instead pass an array of `Phaser.Types.Sound.DecodeAudioConfig`
* objects as the first and only argument.
*
* Decoding is an async process, so be sure to listen for the events to know when decoding has completed.
*
* Once the audio has decoded it can be added to the Sound Manager or played via its key.
*
* @method Phaser.Sound.WebAudioSoundManager#decodeAudio
* @fires Phaser.Sound.Events#DECODED
* @fires Phaser.Sound.Events#DECODED_ALL
* @since 3.18.0
*
* @param {(Phaser.Types.Sound.DecodeAudioConfig[]|string)} [audioKey] - The string-based key to be used to reference the decoded audio in the audio cache, or an array of audio config objects.
* @param {(ArrayBuffer|string)} [audioData] - The audio data, either a base64 encoded string, an audio media-type data uri, or an ArrayBuffer instance.
*/
decodeAudio: function(audioKey, audioData) {
var audioFiles;
if (!Array.isArray(audioKey)) {
audioFiles = [{ key: audioKey, data: audioData }];
} else {
audioFiles = audioKey;
}
var cache = this.game.cache.audio;
var remaining = audioFiles.length;
for (var i = 0; i < audioFiles.length; i++) {
var entry = audioFiles[i];
var key = entry.key;
var data = entry.data;
if (typeof data === "string") {
data = Base64ToArrayBuffer(data);
}
var success = (function(key2, audioBuffer) {
cache.add(key2, audioBuffer);
this.emit(Events.DECODED, key2);
remaining--;
if (remaining === 0) {
this.emit(Events.DECODED_ALL);
}
}).bind(this, key);
var failure = (function(key2, error) {
console.error("Error decoding audio: " + key2 + " - ", error ? error.message : "");
remaining--;
if (remaining === 0) {
this.emit(Events.DECODED_ALL);
}
}).bind(this, key);
this.context.decodeAudioData(data, success, failure);
}
},
/**
* Sets the X and Y position of the Spatial Audio listener on this Web Audios context.
*
* If you call this method with no parameters it will default to the center-point of
* the game canvas. Depending on the type of game you're making, you may need to call
* this method constantly to reset the listener position as the camera scrolls.
*
* Calling this method does nothing on HTML5Audio.
*
* @method Phaser.Sound.WebAudioSoundManager#setListenerPosition
* @since 3.60.0
*
* @param {number} [x] - The x position of the Spatial Audio listener.
* @param {number} [y] - The y position of the Spatial Audio listener.
*/
setListenerPosition: function(x, y) {
if (x === void 0) {
x = this.game.scale.width / 2;
}
if (y === void 0) {
y = this.game.scale.height / 2;
}
this.listenerPosition.set(x, y);
return this;
},
/**
* Unlocks Web Audio API on the initial input event.
*
* Read more about how this issue is handled here in [this article](https://medium.com/@pgoloskokovic/unlocking-web-audio-the-smarter-way-8858218c0e09).
*
* @method Phaser.Sound.WebAudioSoundManager#unlock
* @since 3.0.0
*/
unlock: function() {
var _this = this;
var body = document.body;
var unlockHandler = function unlockHandler2() {
if (_this.context && body) {
var bodyRemove = body.removeEventListener.bind(body);
_this.context.resume().then(function() {
bodyRemove("touchstart", unlockHandler2);
bodyRemove("touchend", unlockHandler2);
bodyRemove("click", unlockHandler2);
bodyRemove("keydown", unlockHandler2);
_this.unlocked = true;
}, function() {
bodyRemove("touchstart", unlockHandler2);
bodyRemove("touchend", unlockHandler2);
bodyRemove("click", unlockHandler2);
bodyRemove("keydown", unlockHandler2);
});
}
};
if (body) {
body.addEventListener("touchstart", unlockHandler, false);
body.addEventListener("touchend", unlockHandler, false);
body.addEventListener("click", unlockHandler, false);
body.addEventListener("keydown", unlockHandler, false);
}
},
/**
* Method used internally for pausing sound manager if
* Phaser.Sound.WebAudioSoundManager#pauseOnBlur is set to true.
*
* @method Phaser.Sound.WebAudioSoundManager#onBlur
* @protected
* @since 3.0.0
*/
onBlur: function() {
if (!this.locked) {
this.context.suspend();
}
},
/**
* Method used internally for resuming sound manager if
* Phaser.Sound.WebAudioSoundManager#pauseOnBlur is set to true.
*
* @method Phaser.Sound.WebAudioSoundManager#onFocus
* @protected
* @since 3.0.0
*/
onFocus: function() {
var context = this.context;
if (context && !this.locked && (context.state === "suspended" || context.state === "interrupted")) {
context.resume();
}
},
/**
* Update method called on every game step.
*
* Removes destroyed sounds and updates every active sound in the game.
*
* @method Phaser.Sound.WebAudioSoundManager#update
* @protected
* @fires Phaser.Sound.Events#UNLOCKED
* @since 3.0.0
*
* @param {number} time - The current timestamp as generated by the Request Animation Frame or SetTimeout.
* @param {number} delta - The delta time elapsed since the last frame.
*/
update: function(time, delta) {
var listener = this.context.listener;
if (listener && listener.positionX !== void 0) {
var x = GetFastValue(this.listenerPosition, "x", null);
var y = GetFastValue(this.listenerPosition, "y", null);
if (x && x !== this._spatialx) {
this._spatialx = listener.positionX.value = x;
}
if (y && y !== this._spatialy) {
this._spatialy = listener.positionY.value = y;
}
}
BaseSoundManager.prototype.update.call(this, time, delta);
if (!this.gameLostFocus) {
this.onFocus();
}
},
/**
* Calls Phaser.Sound.BaseSoundManager#destroy method
* and cleans up all Web Audio API related stuff.
*
* @method Phaser.Sound.WebAudioSoundManager#destroy
* @since 3.0.0
*/
destroy: function() {
this.destination = null;
this.masterVolumeNode.disconnect();
this.masterVolumeNode = null;
this.masterMuteNode.disconnect();
this.masterMuteNode = null;
if (this.game.config.audio.context) {
this.context.suspend();
} else {
var _this = this;
this.context.close().then(function() {
_this.context = null;
});
}
BaseSoundManager.prototype.destroy.call(this);
},
/**
* Sets the muted state of all this Sound Manager.
*
* @method Phaser.Sound.WebAudioSoundManager#setMute
* @fires Phaser.Sound.Events#GLOBAL_MUTE
* @since 3.3.0
*
* @param {boolean} value - `true` to mute all sounds, `false` to unmute them.
*
* @return {Phaser.Sound.WebAudioSoundManager} This Sound Manager.
*/
setMute: function(value) {
this.mute = value;
return this;
},
/**
* @name Phaser.Sound.WebAudioSoundManager#mute
* @type {boolean}
* @fires Phaser.Sound.Events#GLOBAL_MUTE
* @since 3.0.0
*/
mute: {
get: function() {
return this.masterMuteNode.gain.value === 0;
},
set: function(value) {
this.masterMuteNode.gain.setValueAtTime(value ? 0 : 1, 0);
this.emit(Events.GLOBAL_MUTE, this, value);
}
},
/**
* Sets the volume of this Sound Manager.
*
* @method Phaser.Sound.WebAudioSoundManager#setVolume
* @fires Phaser.Sound.Events#GLOBAL_VOLUME
* @since 3.3.0
*
* @param {number} value - The global volume of this Sound Manager.
*
* @return {Phaser.Sound.WebAudioSoundManager} This Sound Manager.
*/
setVolume: function(value) {
this.volume = value;
return this;
},
/**
* @name Phaser.Sound.WebAudioSoundManager#volume
* @type {number}
* @fires Phaser.Sound.Events#GLOBAL_VOLUME
* @since 3.0.0
*/
volume: {
get: function() {
return this.masterVolumeNode.gain.value;
},
set: function(value) {
this.masterVolumeNode.gain.setValueAtTime(value, 0);
this.emit(Events.GLOBAL_VOLUME, this, value);
}
}
});
module2.exports = WebAudioSoundManager;
}
),
/***/
73162: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var ArrayUtils = __webpack_require__2(37105);
var Class = __webpack_require__2(83419);
var NOOP = __webpack_require__2(29747);
var StableSort = __webpack_require__2(19186);
var List = new Class({
initialize: function List2(parent) {
this.parent = parent;
this.list = [];
this.position = 0;
this.addCallback = NOOP;
this.removeCallback = NOOP;
this._sortKey = "";
},
/**
* Adds the given item to the end of the list. Each item must be unique.
*
* @method Phaser.Structs.List#add
* @since 3.0.0
*
* @param {*|Array.<*>} child - The item, or array of items, to add to the list.
* @param {boolean} [skipCallback=false] - Skip calling the List.addCallback if this child is added successfully.
*
* @return {*} The list's underlying array.
*/
add: function(child, skipCallback) {
if (skipCallback) {
return ArrayUtils.Add(this.list, child);
} else {
return ArrayUtils.Add(this.list, child, 0, this.addCallback, this);
}
},
/**
* Adds an item to list, starting at a specified index. Each item must be unique within the list.
*
* @method Phaser.Structs.List#addAt
* @since 3.0.0
*
* @genericUse {(T|T[])} - [child,$return]
*
* @param {*} child - The item, or array of items, to add to the list.
* @param {number} [index=0] - The index in the list at which the element(s) will be inserted.
* @param {boolean} [skipCallback=false] - Skip calling the List.addCallback if this child is added successfully.
*
* @return {*} The List's underlying array.
*/
addAt: function(child, index, skipCallback) {
if (skipCallback) {
return ArrayUtils.AddAt(this.list, child, index);
} else {
return ArrayUtils.AddAt(this.list, child, index, 0, this.addCallback, this);
}
},
/**
* Retrieves the item at a given position inside the List.
*
* @method Phaser.Structs.List#getAt
* @since 3.0.0
*
* @genericUse {T} - [$return]
*
* @param {number} index - The index of the item.
*
* @return {*} The retrieved item, or `undefined` if it's outside the List's bounds.
*/
getAt: function(index) {
return this.list[index];
},
/**
* Locates an item within the List and returns its index.
*
* @method Phaser.Structs.List#getIndex
* @since 3.0.0
*
* @genericUse {T} - [child]
*
* @param {*} child - The item to locate.
*
* @return {number} The index of the item within the List, or -1 if it's not in the List.
*/
getIndex: function(child) {
return this.list.indexOf(child);
},
/**
* Sort the contents of this List so the items are in order based on the given property.
* For example, `sort('alpha')` would sort the List contents based on the value of their `alpha` property.
*
* @method Phaser.Structs.List#sort
* @since 3.0.0
*
* @genericUse {T[]} - [children,$return]
*
* @param {string} property - The property to lexically sort by.
* @param {function} [handler] - Provide your own custom handler function. Will receive 2 children which it should compare and return a boolean.
*
* @return {Phaser.Structs.List} This List object.
*/
sort: function(property, handler) {
if (!property) {
return this;
}
if (handler === void 0) {
handler = function(childA, childB) {
return childA[property] - childB[property];
};
}
StableSort(this.list, handler);
return this;
},
/**
* Searches for the first instance of a child with its `name`
* property matching the given argument. Should more than one child have
* the same name only the first is returned.
*
* @method Phaser.Structs.List#getByName
* @since 3.0.0
*
* @genericUse {T | null} - [$return]
*
* @param {string} name - The name to search for.
*
* @return {?*} The first child with a matching name, or null if none were found.
*/
getByName: function(name) {
return ArrayUtils.GetFirst(this.list, "name", name);
},
/**
* Returns a random child from the group.
*
* @method Phaser.Structs.List#getRandom
* @since 3.0.0
*
* @genericUse {T | null} - [$return]
*
* @param {number} [startIndex=0] - Offset from the front of the group (lowest child).
* @param {number} [length=(to top)] - Restriction on the number of values you want to randomly select from.
*
* @return {?*} A random child of this Group.
*/
getRandom: function(startIndex, length) {
return ArrayUtils.GetRandom(this.list, startIndex, length);
},
/**
* Returns the first element in a given part of the List which matches a specific criterion.
*
* @method Phaser.Structs.List#getFirst
* @since 3.0.0
*
* @genericUse {T | null} - [$return]
*
* @param {string} property - The name of the property to test or a falsey value to have no criterion.
* @param {*} value - The value to test the `property` against, or `undefined` to allow any value and only check for existence.
* @param {number} [startIndex=0] - The position in the List to start the search at.
* @param {number} [endIndex] - The position in the List to optionally stop the search at. It won't be checked.
*
* @return {?*} The first item which matches the given criterion, or `null` if no such item exists.
*/
getFirst: function(property, value, startIndex, endIndex) {
return ArrayUtils.GetFirst(this.list, property, value, startIndex, endIndex);
},
/**
* Returns all children in this List.
*
* You can optionally specify a matching criteria using the `property` and `value` arguments.
*
* For example: `getAll('parent')` would return only children that have a property called `parent`.
*
* You can also specify a value to compare the property to:
*
* `getAll('visible', true)` would return only children that have their visible property set to `true`.
*
* Optionally you can specify a start and end index. For example if this List had 100 children,
* and you set `startIndex` to 0 and `endIndex` to 50, it would return matches from only
* the first 50 children in the List.
*
* @method Phaser.Structs.List#getAll
* @since 3.0.0
*
* @genericUse {T[]} - [$return]
*
* @param {string} [property] - An optional property to test against the value argument.
* @param {any} [value] - If property is set then Child.property must strictly equal this value to be included in the results.
* @param {number} [startIndex] - The first child index to start the search from.
* @param {number} [endIndex] - The last child index to search up until.
*
* @return {Array.<*>} All items of the List which match the given criterion, if any.
*/
getAll: function(property, value, startIndex, endIndex) {
return ArrayUtils.GetAll(this.list, property, value, startIndex, endIndex);
},
/**
* Returns the total number of items in the List which have a property matching the given value.
*
* @method Phaser.Structs.List#count
* @since 3.0.0
*
* @genericUse {T} - [value]
*
* @param {string} property - The property to test on each item.
* @param {*} value - The value to test the property against.
*
* @return {number} The total number of matching elements.
*/
count: function(property, value) {
return ArrayUtils.CountAllMatching(this.list, property, value);
},
/**
* Swaps the positions of two items in the list.
*
* @method Phaser.Structs.List#swap
* @since 3.0.0
*
* @genericUse {T} - [child1,child2]
*
* @param {*} child1 - The first item to swap.
* @param {*} child2 - The second item to swap.
*/
swap: function(child1, child2) {
ArrayUtils.Swap(this.list, child1, child2);
},
/**
* Moves an item in the List to a new position.
*
* @method Phaser.Structs.List#moveTo
* @since 3.0.0
*
* @genericUse {T} - [child,$return]
*
* @param {*} child - The item to move.
* @param {number} index - Moves an item in the List to a new position.
*
* @return {*} The item that was moved.
*/
moveTo: function(child, index) {
return ArrayUtils.MoveTo(this.list, child, index);
},
/**
* Moves an item above another one in the List.
* If the given item is already above the other, it isn't moved.
* Above means toward the end of the List.
*
* @method Phaser.Structs.List#moveAbove
* @since 3.55.0
*
* @genericUse {T} - [child1,child2]
*
* @param {*} child1 - The element to move above base element.
* @param {*} child2 - The base element.
*/
moveAbove: function(child1, child2) {
return ArrayUtils.MoveAbove(this.list, child1, child2);
},
/**
* Moves an item below another one in the List.
* If the given item is already below the other, it isn't moved.
* Below means toward the start of the List.
*
* @method Phaser.Structs.List#moveBelow
* @since 3.55.0
*
* @genericUse {T} - [child1,child2]
*
* @param {*} child1 - The element to move below base element.
* @param {*} child2 - The base element.
*/
moveBelow: function(child1, child2) {
return ArrayUtils.MoveBelow(this.list, child1, child2);
},
/**
* Removes one or many items from the List.
*
* @method Phaser.Structs.List#remove
* @since 3.0.0
*
* @param {*} child - The item, or array of items, to remove.
* @param {boolean} [skipCallback=false] - Skip calling the List.removeCallback.
*
* @return {*} The item, or array of items, which were successfully removed from the List.
*/
remove: function(child, skipCallback) {
if (skipCallback) {
return ArrayUtils.Remove(this.list, child);
} else {
return ArrayUtils.Remove(this.list, child, this.removeCallback, this);
}
},
/**
* Removes the item at the given position in the List.
*
* @method Phaser.Structs.List#removeAt
* @since 3.0.0
*
* @genericUse {T} - [$return]
*
* @param {number} index - The position to remove the item from.
* @param {boolean} [skipCallback=false] - Skip calling the List.removeCallback.
*
* @return {*} The item that was removed.
*/
removeAt: function(index, skipCallback) {
if (skipCallback) {
return ArrayUtils.RemoveAt(this.list, index);
} else {
return ArrayUtils.RemoveAt(this.list, index, this.removeCallback, this);
}
},
/**
* Removes the items within the given range in the List.
*
* @method Phaser.Structs.List#removeBetween
* @since 3.0.0
*
* @genericUse {T[]} - [$return]
*
* @param {number} [startIndex=0] - The index to start removing from.
* @param {number} [endIndex] - The position to stop removing at. The item at this position won't be removed.
* @param {boolean} [skipCallback=false] - Skip calling the List.removeCallback.
*
* @return {Array.<*>} An array of the items which were removed.
*/
removeBetween: function(startIndex, endIndex, skipCallback) {
if (skipCallback) {
return ArrayUtils.RemoveBetween(this.list, startIndex, endIndex);
} else {
return ArrayUtils.RemoveBetween(this.list, startIndex, endIndex, this.removeCallback, this);
}
},
/**
* Removes all the items.
*
* @method Phaser.Structs.List#removeAll
* @since 3.0.0
*
* @param {boolean} [skipCallback=false] - Skip calling the List.removeCallback.
*
* @return {this} This List object.
*/
removeAll: function(skipCallback) {
var i = this.list.length;
while (i--) {
this.remove(this.list[i], skipCallback);
}
return this;
},
/**
* Brings the given child to the top of this List.
*
* @method Phaser.Structs.List#bringToTop
* @since 3.0.0
*
* @genericUse {T} - [child,$return]
*
* @param {*} child - The item to bring to the top of the List.
*
* @return {*} The item which was moved.
*/
bringToTop: function(child) {
return ArrayUtils.BringToTop(this.list, child);
},
/**
* Sends the given child to the bottom of this List.
*
* @method Phaser.Structs.List#sendToBack
* @since 3.0.0
*
* @genericUse {T} - [child,$return]
*
* @param {*} child - The item to send to the back of the list.
*
* @return {*} The item which was moved.
*/
sendToBack: function(child) {
return ArrayUtils.SendToBack(this.list, child);
},
/**
* Moves the given child up one place in this group unless it's already at the top.
*
* @method Phaser.Structs.List#moveUp
* @since 3.0.0
*
* @genericUse {T} - [child,$return]
*
* @param {*} child - The item to move up.
*
* @return {*} The item which was moved.
*/
moveUp: function(child) {
ArrayUtils.MoveUp(this.list, child);
return child;
},
/**
* Moves the given child down one place in this group unless it's already at the bottom.
*
* @method Phaser.Structs.List#moveDown
* @since 3.0.0
*
* @genericUse {T} - [child,$return]
*
* @param {*} child - The item to move down.
*
* @return {*} The item which was moved.
*/
moveDown: function(child) {
ArrayUtils.MoveDown(this.list, child);
return child;
},
/**
* Reverses the order of all children in this List.
*
* @method Phaser.Structs.List#reverse
* @since 3.0.0
*
* @genericUse {Phaser.Structs.List.<T>} - [$return]
*
* @return {Phaser.Structs.List} This List object.
*/
reverse: function() {
this.list.reverse();
return this;
},
/**
* Shuffles the items in the list.
*
* @method Phaser.Structs.List#shuffle
* @since 3.0.0
*
* @genericUse {Phaser.Structs.List.<T>} - [$return]
*
* @return {Phaser.Structs.List} This List object.
*/
shuffle: function() {
ArrayUtils.Shuffle(this.list);
return this;
},
/**
* Replaces a child of this List with the given newChild. The newChild cannot be a member of this List.
*
* @method Phaser.Structs.List#replace
* @since 3.0.0
*
* @genericUse {T} - [oldChild,newChild,$return]
*
* @param {*} oldChild - The child in this List that will be replaced.
* @param {*} newChild - The child to be inserted into this List.
*
* @return {*} Returns the oldChild that was replaced within this group.
*/
replace: function(oldChild, newChild) {
return ArrayUtils.Replace(this.list, oldChild, newChild);
},
/**
* Checks if an item exists within the List.
*
* @method Phaser.Structs.List#exists
* @since 3.0.0
*
* @genericUse {T} - [child]
*
* @param {*} child - The item to check for the existence of.
*
* @return {boolean} `true` if the item is found in the list, otherwise `false`.
*/
exists: function(child) {
return this.list.indexOf(child) > -1;
},
/**
* Sets the property `key` to the given value on all members of this List.
*
* @method Phaser.Structs.List#setAll
* @since 3.0.0
*
* @genericUse {T} - [value]
*
* @param {string} property - The name of the property to set.
* @param {*} value - The value to set the property to.
* @param {number} [startIndex] - The first child index to start the search from.
* @param {number} [endIndex] - The last child index to search up until.
*/
setAll: function(property, value, startIndex, endIndex) {
ArrayUtils.SetAll(this.list, property, value, startIndex, endIndex);
return this;
},
/**
* Passes all children to the given callback.
*
* @method Phaser.Structs.List#each
* @since 3.0.0
*
* @genericUse {EachListCallback.<T>} - [callback]
*
* @param {EachListCallback} callback - The function to call.
* @param {*} [context] - Value to use as `this` when executing callback.
* @param {...*} [args] - Additional arguments that will be passed to the callback, after the child.
*/
each: function(callback, context) {
var args = [null];
for (var i = 2; i < arguments.length; i++) {
args.push(arguments[i]);
}
for (i = 0; i < this.list.length; i++) {
args[0] = this.list[i];
callback.apply(context, args);
}
},
/**
* Clears the List and recreates its internal array.
*
* @method Phaser.Structs.List#shutdown
* @since 3.0.0
*/
shutdown: function() {
this.removeAll();
this.list = [];
},
/**
* Destroys this List.
*
* @method Phaser.Structs.List#destroy
* @since 3.0.0
*/
destroy: function() {
this.removeAll();
this.parent = null;
this.addCallback = null;
this.removeCallback = null;
},
/**
* The number of items inside the List.
*
* @name Phaser.Structs.List#length
* @type {number}
* @readonly
* @since 3.0.0
*/
length: {
get: function() {
return this.list.length;
}
},
/**
* The first item in the List or `null` for an empty List.
*
* @name Phaser.Structs.List#first
* @genericUse {T} - [$type]
* @type {*}
* @readonly
* @since 3.0.0
*/
first: {
get: function() {
this.position = 0;
if (this.list.length > 0) {
return this.list[0];
} else {
return null;
}
}
},
/**
* The last item in the List, or `null` for an empty List.
*
* @name Phaser.Structs.List#last
* @genericUse {T} - [$type]
* @type {*}
* @readonly
* @since 3.0.0
*/
last: {
get: function() {
if (this.list.length > 0) {
this.position = this.list.length - 1;
return this.list[this.position];
} else {
return null;
}
}
},
/**
* The next item in the List, or `null` if the entire List has been traversed.
*
* This property can be read successively after reading {@link #first} or manually setting the {@link #position} to iterate the List.
*
* @name Phaser.Structs.List#next
* @genericUse {T} - [$type]
* @type {*}
* @readonly
* @since 3.0.0
*/
next: {
get: function() {
if (this.position < this.list.length) {
this.position++;
return this.list[this.position];
} else {
return null;
}
}
},
/**
* The previous item in the List, or `null` if the entire List has been traversed.
*
* This property can be read successively after reading {@link #last} or manually setting the {@link #position} to iterate the List backwards.
*
* @name Phaser.Structs.List#previous
* @genericUse {T} - [$type]
* @type {*}
* @readonly
* @since 3.0.0
*/
previous: {
get: function() {
if (this.position > 0) {
this.position--;
return this.list[this.position];
} else {
return null;
}
}
}
});
module2.exports = List;
}
),
/***/
90330: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Map = new Class({
initialize: function Map2(elements) {
this.entries = {};
this.size = 0;
this.setAll(elements);
},
/**
* Adds all the elements in the given array to this Map.
*
* If the element already exists, the value will be skipped.
*
* @method Phaser.Structs.Map#setAll
* @since 3.70.0
*
* @generic K
* @generic V
* @genericUse {V[]} - [elements]
*
* @param {Array.<*>} elements - An array of key-value pairs to populate this Map with.
*
* @return {this} This Map object.
*/
setAll: function(elements) {
if (Array.isArray(elements)) {
for (var i = 0; i < elements.length; i++) {
this.set(elements[i][0], elements[i][1]);
}
}
return this;
},
/**
* Adds an element with a specified `key` and `value` to this Map.
*
* If the `key` already exists, the value will be replaced.
*
* If you wish to add multiple elements in a single call, use the `setAll` method instead.
*
* @method Phaser.Structs.Map#set
* @since 3.0.0
*
* @genericUse {K} - [key]
* @genericUse {V} - [value]
* @genericUse {Phaser.Structs.Map.<K, V>} - [$return]
*
* @param {string} key - The key of the element to be added to this Map.
* @param {*} value - The value of the element to be added to this Map.
*
* @return {this} This Map object.
*/
set: function(key, value) {
if (!this.has(key)) {
this.size++;
}
this.entries[key] = value;
return this;
},
/**
* Returns the value associated to the `key`, or `undefined` if there is none.
*
* @method Phaser.Structs.Map#get
* @since 3.0.0
*
* @genericUse {K} - [key]
* @genericUse {V} - [$return]
*
* @param {string} key - The key of the element to return from the `Map` object.
*
* @return {*} The element associated with the specified key or `undefined` if the key can't be found in this Map object.
*/
get: function(key) {
if (this.has(key)) {
return this.entries[key];
}
},
/**
* Returns an `Array` of all the values stored in this Map.
*
* @method Phaser.Structs.Map#getArray
* @since 3.0.0
*
* @genericUse {V[]} - [$return]
*
* @return {Array.<*>} An array of the values stored in this Map.
*/
getArray: function() {
var output = [];
var entries = this.entries;
for (var key in entries) {
output.push(entries[key]);
}
return output;
},
/**
* Returns a boolean indicating whether an element with the specified key exists or not.
*
* @method Phaser.Structs.Map#has
* @since 3.0.0
*
* @genericUse {K} - [key]
*
* @param {string} key - The key of the element to test for presence of in this Map.
*
* @return {boolean} Returns `true` if an element with the specified key exists in this Map, otherwise `false`.
*/
has: function(key) {
return this.entries.hasOwnProperty(key);
},
/**
* Delete the specified element from this Map.
*
* @method Phaser.Structs.Map#delete
* @since 3.0.0
*
* @genericUse {K} - [key]
* @genericUse {Phaser.Structs.Map.<K, V>} - [$return]
*
* @param {string} key - The key of the element to delete from this Map.
*
* @return {this} This Map object.
*/
delete: function(key) {
if (this.has(key)) {
delete this.entries[key];
this.size--;
}
return this;
},
/**
* Delete all entries from this Map.
*
* @method Phaser.Structs.Map#clear
* @since 3.0.0
*
* @genericUse {Phaser.Structs.Map.<K, V>} - [$return]
*
* @return {this} This Map object.
*/
clear: function() {
Object.keys(this.entries).forEach(function(prop) {
delete this.entries[prop];
}, this);
this.size = 0;
return this;
},
/**
* Returns all entries keys in this Map.
*
* @method Phaser.Structs.Map#keys
* @since 3.0.0
*
* @genericUse {K[]} - [$return]
*
* @return {string[]} Array containing entries' keys.
*/
keys: function() {
return Object.keys(this.entries);
},
/**
* Returns an `Array` of all entries.
*
* @method Phaser.Structs.Map#values
* @since 3.0.0
*
* @genericUse {V[]} - [$return]
*
* @return {Array.<*>} An `Array` of entries.
*/
values: function() {
var output = [];
var entries = this.entries;
for (var key in entries) {
output.push(entries[key]);
}
return output;
},
/**
* Dumps the contents of this Map to the console via `console.group`.
*
* @method Phaser.Structs.Map#dump
* @since 3.0.0
*/
dump: function() {
var entries = this.entries;
console.group("Map");
for (var key in entries) {
console.log(key, entries[key]);
}
console.groupEnd();
},
/**
* Iterates through all entries in this Map, passing each one to the given callback.
*
* If the callback returns `false`, the iteration will break.
*
* @method Phaser.Structs.Map#each
* @since 3.0.0
*
* @genericUse {EachMapCallback.<V>} - [callback]
* @genericUse {Phaser.Structs.Map.<K, V>} - [$return]
*
* @param {EachMapCallback} callback - The callback which will receive the keys and entries held in this Map.
*
* @return {this} This Map object.
*/
each: function(callback) {
var entries = this.entries;
for (var key in entries) {
if (callback(key, entries[key]) === false) {
break;
}
}
return this;
},
/**
* Returns `true` if the value exists within this Map. Otherwise, returns `false`.
*
* @method Phaser.Structs.Map#contains
* @since 3.0.0
*
* @genericUse {V} - [value]
*
* @param {*} value - The value to search for.
*
* @return {boolean} `true` if the value is found, otherwise `false`.
*/
contains: function(value) {
var entries = this.entries;
for (var key in entries) {
if (entries[key] === value) {
return true;
}
}
return false;
},
/**
* Merges all new keys from the given Map into this one.
* If it encounters a key that already exists it will be skipped unless override is set to `true`.
*
* @method Phaser.Structs.Map#merge
* @since 3.0.0
*
* @genericUse {Phaser.Structs.Map.<K, V>} - [map,$return]
*
* @param {Phaser.Structs.Map} map - The Map to merge in to this Map.
* @param {boolean} [override=false] - Set to `true` to replace values in this Map with those from the source map, or `false` to skip them.
*
* @return {this} This Map object.
*/
merge: function(map, override) {
if (override === void 0) {
override = false;
}
var local = this.entries;
var source = map.entries;
for (var key in source) {
if (local.hasOwnProperty(key) && override) {
local[key] = source[key];
} else {
this.set(key, source[key]);
}
}
return this;
}
});
module2.exports = Map;
}
),
/***/
25774: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var EventEmitter = __webpack_require__2(50792);
var Events = __webpack_require__2(82348);
var ProcessQueue = new Class({
Extends: EventEmitter,
initialize: function ProcessQueue2() {
EventEmitter.call(this);
this._pending = [];
this._active = [];
this._destroy = [];
this._toProcess = 0;
this.checkQueue = false;
},
/**
* Checks the given item to see if it is already active within this Process Queue.
*
* @method Phaser.Structs.ProcessQueue#isActive
* @since 3.60.0
*
* @genericUse {T} - [item]
* @genericUse {Phaser.Structs.ProcessQueue.<T>} - [$return]
*
* @param {*} item - The item to check.
*
* @return {boolean} `true` if the item is active, otherwise `false`.
*/
isActive: function(item) {
return this._active.indexOf(item) > -1;
},
/**
* Checks the given item to see if it is already pending addition to this Process Queue.
*
* @method Phaser.Structs.ProcessQueue#isPending
* @since 3.60.0
*
* @genericUse {T} - [item]
* @genericUse {Phaser.Structs.ProcessQueue.<T>} - [$return]
*
* @param {*} item - The item to check.
*
* @return {boolean} `true` if the item is pending insertion, otherwise `false`.
*/
isPending: function(item) {
return this._toProcess > 0 && this._pending.indexOf(item) > -1;
},
/**
* Checks the given item to see if it is already pending destruction from this Process Queue.
*
* @method Phaser.Structs.ProcessQueue#isDestroying
* @since 3.60.0
*
* @genericUse {T} - [item]
* @genericUse {Phaser.Structs.ProcessQueue.<T>} - [$return]
*
* @param {*} item - The item to check.
*
* @return {boolean} `true` if the item is pending destruction, otherwise `false`.
*/
isDestroying: function(item) {
return this._destroy.indexOf(item) > -1;
},
/**
* Adds a new item to the Process Queue.
*
* The item is added to the pending list and made active in the next update.
*
* @method Phaser.Structs.ProcessQueue#add
* @since 3.0.0
*
* @genericUse {T} - [item]
* @genericUse {Phaser.Structs.ProcessQueue.<T>} - [$return]
*
* @param {*} item - The item to add to the queue.
*
* @return {*} The item that was added.
*/
add: function(item) {
if (this.checkQueue && (this.isActive(item) && !this.isDestroying(item)) || this.isPending(item)) {
return item;
}
this._pending.push(item);
this._toProcess++;
return item;
},
/**
* Removes an item from the Process Queue.
*
* The item is added to the 'destroy' list and is fully removed in the next update.
*
* @method Phaser.Structs.ProcessQueue#remove
* @since 3.0.0
*
* @genericUse {T} - [item]
* @genericUse {Phaser.Structs.ProcessQueue.<T>} - [$return]
*
* @param {*} item - The item to be removed from the queue.
*
* @return {*} The item that was removed.
*/
remove: function(item) {
if (this.isPending(item)) {
var pending = this._pending;
var idx = pending.indexOf(item);
if (idx !== -1) {
pending.splice(idx, 1);
}
} else if (this.isActive(item)) {
this._destroy.push(item);
this._toProcess++;
}
return item;
},
/**
* Removes all active items from this Process Queue.
*
* All the items are marked as 'pending destroy' and fully removed in the next update.
*
* @method Phaser.Structs.ProcessQueue#removeAll
* @since 3.20.0
*
* @return {this} This Process Queue object.
*/
removeAll: function() {
var list = this._active;
var destroy = this._destroy;
var i = list.length;
while (i--) {
destroy.push(list[i]);
this._toProcess++;
}
return this;
},
/**
* Update this queue. First it will process any items awaiting destruction, and remove them.
*
* Then it will check to see if there are any items pending insertion, and move them to an
* active state. Finally, it will return a list of active items for further processing.
*
* @method Phaser.Structs.ProcessQueue#update
* @since 3.0.0
*
* @genericUse {T[]} - [$return]
*
* @return {Array.<*>} A list of active items.
*/
update: function() {
if (this._toProcess === 0) {
return this._active;
}
var list = this._destroy;
var active = this._active;
var i;
var item;
for (i = 0; i < list.length; i++) {
item = list[i];
var idx = active.indexOf(item);
if (idx !== -1) {
active.splice(idx, 1);
this.emit(Events.PROCESS_QUEUE_REMOVE, item);
}
}
list.length = 0;
list = this._pending;
for (i = 0; i < list.length; i++) {
item = list[i];
if (!this.checkQueue || this.checkQueue && active.indexOf(item) === -1) {
active.push(item);
this.emit(Events.PROCESS_QUEUE_ADD, item);
}
}
list.length = 0;
this._toProcess = 0;
return active;
},
/**
* Returns the current list of active items.
*
* This method returns a reference to the active list array, not a copy of it.
* Therefore, be careful to not modify this array outside of the ProcessQueue.
*
* @method Phaser.Structs.ProcessQueue#getActive
* @since 3.0.0
*
* @genericUse {T[]} - [$return]
*
* @return {Array.<*>} A list of active items.
*/
getActive: function() {
return this._active;
},
/**
* The number of entries in the active list.
*
* @name Phaser.Structs.ProcessQueue#length
* @type {number}
* @readonly
* @since 3.20.0
*/
length: {
get: function() {
return this._active.length;
}
},
/**
* Immediately destroys this process queue, clearing all of its internal arrays and resetting the process totals.
*
* @method Phaser.Structs.ProcessQueue#destroy
* @since 3.0.0
*/
destroy: function() {
this._toProcess = 0;
this._pending = [];
this._active = [];
this._destroy = [];
}
});
module2.exports = ProcessQueue;
}
),
/***/
59542: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var quickselect = __webpack_require__2(43886);
function rbush(maxEntries) {
var format = [".left", ".top", ".right", ".bottom"];
if (!(this instanceof rbush)) return new rbush(maxEntries, format);
this._maxEntries = Math.max(4, maxEntries || 9);
this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));
this.clear();
}
rbush.prototype = {
all: function() {
return this._all(this.data, []);
},
search: function(bbox) {
var node = this.data, result = [], toBBox = this.toBBox;
if (!intersects(bbox, node)) return result;
var nodesToSearch = [], i, len, child, childBBox;
while (node) {
for (i = 0, len = node.children.length; i < len; i++) {
child = node.children[i];
childBBox = node.leaf ? toBBox(child) : child;
if (intersects(bbox, childBBox)) {
if (node.leaf) result.push(child);
else if (contains(bbox, childBBox)) this._all(child, result);
else nodesToSearch.push(child);
}
}
node = nodesToSearch.pop();
}
return result;
},
collides: function(bbox) {
var node = this.data, toBBox = this.toBBox;
if (!intersects(bbox, node)) return false;
var nodesToSearch = [], i, len, child, childBBox;
while (node) {
for (i = 0, len = node.children.length; i < len; i++) {
child = node.children[i];
childBBox = node.leaf ? toBBox(child) : child;
if (intersects(bbox, childBBox)) {
if (node.leaf || contains(bbox, childBBox)) return true;
nodesToSearch.push(child);
}
}
node = nodesToSearch.pop();
}
return false;
},
load: function(data) {
if (!(data && data.length)) return this;
if (data.length < this._minEntries) {
for (var i = 0, len = data.length; i < len; i++) {
this.insert(data[i]);
}
return this;
}
var node = this._build(data.slice(), 0, data.length - 1, 0);
if (!this.data.children.length) {
this.data = node;
} else if (this.data.height === node.height) {
this._splitRoot(this.data, node);
} else {
if (this.data.height < node.height) {
var tmpNode = this.data;
this.data = node;
node = tmpNode;
}
this._insert(node, this.data.height - node.height - 1, true);
}
return this;
},
insert: function(item) {
if (item) this._insert(item, this.data.height - 1);
return this;
},
clear: function() {
this.data = createNode([]);
return this;
},
remove: function(item, equalsFn) {
if (!item) return this;
var node = this.data, bbox = this.toBBox(item), path = [], indexes = [], i, parent, index, goingUp;
while (node || path.length) {
if (!node) {
node = path.pop();
parent = path[path.length - 1];
i = indexes.pop();
goingUp = true;
}
if (node.leaf) {
index = findItem(item, node.children, equalsFn);
if (index !== -1) {
node.children.splice(index, 1);
path.push(node);
this._condense(path);
return this;
}
}
if (!goingUp && !node.leaf && contains(node, bbox)) {
path.push(node);
indexes.push(i);
i = 0;
parent = node;
node = node.children[0];
} else if (parent) {
i++;
node = parent.children[i];
goingUp = false;
} else node = null;
}
return this;
},
toBBox: function(item) {
return item;
},
compareMinX: compareNodeMinX,
compareMinY: compareNodeMinY,
toJSON: function() {
return this.data;
},
fromJSON: function(data) {
this.data = data;
return this;
},
_all: function(node, result) {
var nodesToSearch = [];
while (node) {
if (node.leaf) result.push.apply(result, node.children);
else nodesToSearch.push.apply(nodesToSearch, node.children);
node = nodesToSearch.pop();
}
return result;
},
_build: function(items, left, right, height) {
var N = right - left + 1, M = this._maxEntries, node;
if (N <= M) {
node = createNode(items.slice(left, right + 1));
calcBBox(node, this.toBBox);
return node;
}
if (!height) {
height = Math.ceil(Math.log(N) / Math.log(M));
M = Math.ceil(N / Math.pow(M, height - 1));
}
node = createNode([]);
node.leaf = false;
node.height = height;
var N2 = Math.ceil(N / M), N1 = N2 * Math.ceil(Math.sqrt(M)), i, j, right2, right3;
multiSelect(items, left, right, N1, this.compareMinX);
for (i = left; i <= right; i += N1) {
right2 = Math.min(i + N1 - 1, right);
multiSelect(items, i, right2, N2, this.compareMinY);
for (j = i; j <= right2; j += N2) {
right3 = Math.min(j + N2 - 1, right2);
node.children.push(this._build(items, j, right3, height - 1));
}
}
calcBBox(node, this.toBBox);
return node;
},
_chooseSubtree: function(bbox, node, level, path) {
var i, len, child, targetNode, area, enlargement, minArea, minEnlargement;
while (true) {
path.push(node);
if (node.leaf || path.length - 1 === level) break;
minArea = minEnlargement = Infinity;
for (i = 0, len = node.children.length; i < len; i++) {
child = node.children[i];
area = bboxArea(child);
enlargement = enlargedArea(bbox, child) - area;
if (enlargement < minEnlargement) {
minEnlargement = enlargement;
minArea = area < minArea ? area : minArea;
targetNode = child;
} else if (enlargement === minEnlargement) {
if (area < minArea) {
minArea = area;
targetNode = child;
}
}
}
node = targetNode || node.children[0];
}
return node;
},
_insert: function(item, level, isNode) {
var toBBox = this.toBBox, bbox = isNode ? item : toBBox(item), insertPath = [];
var node = this._chooseSubtree(bbox, this.data, level, insertPath);
node.children.push(item);
extend(node, bbox);
while (level >= 0) {
if (insertPath[level].children.length > this._maxEntries) {
this._split(insertPath, level);
level--;
} else break;
}
this._adjustParentBBoxes(bbox, insertPath, level);
},
// split overflowed node into two
_split: function(insertPath, level) {
var node = insertPath[level], M = node.children.length, m = this._minEntries;
this._chooseSplitAxis(node, m, M);
var splitIndex = this._chooseSplitIndex(node, m, M);
var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex));
newNode.height = node.height;
newNode.leaf = node.leaf;
calcBBox(node, this.toBBox);
calcBBox(newNode, this.toBBox);
if (level) insertPath[level - 1].children.push(newNode);
else this._splitRoot(node, newNode);
},
_splitRoot: function(node, newNode) {
this.data = createNode([node, newNode]);
this.data.height = node.height + 1;
this.data.leaf = false;
calcBBox(this.data, this.toBBox);
},
_chooseSplitIndex: function(node, m, M) {
var i, bbox1, bbox2, overlap, area, minOverlap, minArea, index;
minOverlap = minArea = Infinity;
for (i = m; i <= M - m; i++) {
bbox1 = distBBox(node, 0, i, this.toBBox);
bbox2 = distBBox(node, i, M, this.toBBox);
overlap = intersectionArea(bbox1, bbox2);
area = bboxArea(bbox1) + bboxArea(bbox2);
if (overlap < minOverlap) {
minOverlap = overlap;
index = i;
minArea = area < minArea ? area : minArea;
} else if (overlap === minOverlap) {
if (area < minArea) {
minArea = area;
index = i;
}
}
}
return index;
},
// sorts node children by the best axis for split
_chooseSplitAxis: function(node, m, M) {
var compareMinX = node.leaf ? this.compareMinX : compareNodeMinX, compareMinY = node.leaf ? this.compareMinY : compareNodeMinY, xMargin = this._allDistMargin(node, m, M, compareMinX), yMargin = this._allDistMargin(node, m, M, compareMinY);
if (xMargin < yMargin) node.children.sort(compareMinX);
},
// total margin of all possible split distributions where each node is at least m full
_allDistMargin: function(node, m, M, compare) {
node.children.sort(compare);
var toBBox = this.toBBox, leftBBox = distBBox(node, 0, m, toBBox), rightBBox = distBBox(node, M - m, M, toBBox), margin = bboxMargin(leftBBox) + bboxMargin(rightBBox), i, child;
for (i = m; i < M - m; i++) {
child = node.children[i];
extend(leftBBox, node.leaf ? toBBox(child) : child);
margin += bboxMargin(leftBBox);
}
for (i = M - m - 1; i >= m; i--) {
child = node.children[i];
extend(rightBBox, node.leaf ? toBBox(child) : child);
margin += bboxMargin(rightBBox);
}
return margin;
},
_adjustParentBBoxes: function(bbox, path, level) {
for (var i = level; i >= 0; i--) {
extend(path[i], bbox);
}
},
_condense: function(path) {
for (var i = path.length - 1, siblings; i >= 0; i--) {
if (path[i].children.length === 0) {
if (i > 0) {
siblings = path[i - 1].children;
siblings.splice(siblings.indexOf(path[i]), 1);
} else this.clear();
} else calcBBox(path[i], this.toBBox);
}
},
compareMinX: function(a, b) {
return a.left - b.left;
},
compareMinY: function(a, b) {
return a.top - b.top;
},
toBBox: function(a) {
return {
minX: a.left,
minY: a.top,
maxX: a.right,
maxY: a.bottom
};
}
};
function findItem(item, items, equalsFn) {
if (!equalsFn) return items.indexOf(item);
for (var i = 0; i < items.length; i++) {
if (equalsFn(item, items[i])) return i;
}
return -1;
}
function calcBBox(node, toBBox) {
distBBox(node, 0, node.children.length, toBBox, node);
}
function distBBox(node, k, p, toBBox, destNode) {
if (!destNode) destNode = createNode(null);
destNode.minX = Infinity;
destNode.minY = Infinity;
destNode.maxX = -Infinity;
destNode.maxY = -Infinity;
for (var i = k, child; i < p; i++) {
child = node.children[i];
extend(destNode, node.leaf ? toBBox(child) : child);
}
return destNode;
}
function extend(a, b) {
a.minX = Math.min(a.minX, b.minX);
a.minY = Math.min(a.minY, b.minY);
a.maxX = Math.max(a.maxX, b.maxX);
a.maxY = Math.max(a.maxY, b.maxY);
return a;
}
function compareNodeMinX(a, b) {
return a.minX - b.minX;
}
function compareNodeMinY(a, b) {
return a.minY - b.minY;
}
function bboxArea(a) {
return (a.maxX - a.minX) * (a.maxY - a.minY);
}
function bboxMargin(a) {
return a.maxX - a.minX + (a.maxY - a.minY);
}
function enlargedArea(a, b) {
return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) * (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY));
}
function intersectionArea(a, b) {
var minX = Math.max(a.minX, b.minX), minY = Math.max(a.minY, b.minY), maxX = Math.min(a.maxX, b.maxX), maxY = Math.min(a.maxY, b.maxY);
return Math.max(0, maxX - minX) * Math.max(0, maxY - minY);
}
function contains(a, b) {
return a.minX <= b.minX && a.minY <= b.minY && b.maxX <= a.maxX && b.maxY <= a.maxY;
}
function intersects(a, b) {
return b.minX <= a.maxX && b.minY <= a.maxY && b.maxX >= a.minX && b.maxY >= a.minY;
}
function createNode(children) {
return {
children,
height: 1,
leaf: true,
minX: Infinity,
minY: Infinity,
maxX: -Infinity,
maxY: -Infinity
};
}
function multiSelect(arr, left, right, n, compare) {
var stack = [left, right], mid;
while (stack.length) {
right = stack.pop();
left = stack.pop();
if (right - left <= n) continue;
mid = left + Math.ceil((right - left) / n / 2) * n;
quickselect(arr, mid, left, right, compare);
stack.push(left, mid, mid, right);
}
}
module2.exports = rbush;
}
),
/***/
35072: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Set = new Class({
initialize: function Set2(elements) {
this.entries = [];
if (Array.isArray(elements)) {
for (var i = 0; i < elements.length; i++) {
this.set(elements[i]);
}
}
},
/**
* Inserts the provided value into this Set. If the value is already contained in this Set this method will have no effect.
*
* @method Phaser.Structs.Set#set
* @since 3.0.0
*
* @genericUse {T} - [value]
* @genericUse {Phaser.Structs.Set.<T>} - [$return]
*
* @param {*} value - The value to insert into this Set.
*
* @return {Phaser.Structs.Set} This Set object.
*/
set: function(value) {
if (this.entries.indexOf(value) === -1) {
this.entries.push(value);
}
return this;
},
/**
* Get an element of this Set which has a property of the specified name, if that property is equal to the specified value.
* If no elements of this Set satisfy the condition then this method will return `null`.
*
* @method Phaser.Structs.Set#get
* @since 3.0.0
*
* @genericUse {T} - [value,$return]
*
* @param {string} property - The property name to check on the elements of this Set.
* @param {*} value - The value to check for.
*
* @return {*} The first element of this Set that meets the required condition, or `null` if this Set contains no elements that meet the condition.
*/
get: function(property, value) {
for (var i = 0; i < this.entries.length; i++) {
var entry = this.entries[i];
if (entry[property] === value) {
return entry;
}
}
},
/**
* Returns an array containing all the values in this Set.
*
* @method Phaser.Structs.Set#getArray
* @since 3.0.0
*
* @genericUse {T[]} - [$return]
*
* @return {Array.<*>} An array containing all the values in this Set.
*/
getArray: function() {
return this.entries.slice(0);
},
/**
* Removes the given value from this Set if this Set contains that value.
*
* @method Phaser.Structs.Set#delete
* @since 3.0.0
*
* @genericUse {T} - [value]
* @genericUse {Phaser.Structs.Set.<T>} - [$return]
*
* @param {*} value - The value to remove from the Set.
*
* @return {Phaser.Structs.Set} This Set object.
*/
delete: function(value) {
var index = this.entries.indexOf(value);
if (index > -1) {
this.entries.splice(index, 1);
}
return this;
},
/**
* Dumps the contents of this Set to the console via `console.group`.
*
* @method Phaser.Structs.Set#dump
* @since 3.0.0
*/
dump: function() {
console.group("Set");
for (var i = 0; i < this.entries.length; i++) {
var entry = this.entries[i];
console.log(entry);
}
console.groupEnd();
},
/**
* Passes each value in this Set to the given callback.
* Use this function when you know this Set will be modified during the iteration, otherwise use `iterate`.
*
* @method Phaser.Structs.Set#each
* @since 3.0.0
*
* @genericUse {EachSetCallback.<T>} - [callback]
* @genericUse {Phaser.Structs.Set.<T>} - [$return]
*
* @param {EachSetCallback} callback - The callback to be invoked and passed each value this Set contains.
* @param {*} [callbackScope] - The scope of the callback.
*
* @return {Phaser.Structs.Set} This Set object.
*/
each: function(callback, callbackScope) {
var i;
var temp = this.entries.slice();
var len = temp.length;
if (callbackScope) {
for (i = 0; i < len; i++) {
if (callback.call(callbackScope, temp[i], i) === false) {
break;
}
}
} else {
for (i = 0; i < len; i++) {
if (callback(temp[i], i) === false) {
break;
}
}
}
return this;
},
/**
* Passes each value in this Set to the given callback.
*
* For when you absolutely know this Set won't be modified during the iteration.
*
* The callback must return a boolean. If it returns `false` then it will abort
* the Set iteration immediately. If it returns `true`, it will carry on
* iterating the next child in the Set.
*
* @method Phaser.Structs.Set#iterate
* @since 3.0.0
*
* @genericUse {EachSetCallback.<T>} - [callback]
* @genericUse {Phaser.Structs.Set.<T>} - [$return]
*
* @param {EachSetCallback} callback - The callback to be invoked and passed each value this Set contains.
* @param {*} [callbackScope] - The scope of the callback.
*
* @return {Phaser.Structs.Set} This Set object.
*/
iterate: function(callback, callbackScope) {
var i;
var len = this.entries.length;
if (callbackScope) {
for (i = 0; i < len; i++) {
if (callback.call(callbackScope, this.entries[i], i) === false) {
break;
}
}
} else {
for (i = 0; i < len; i++) {
if (callback(this.entries[i], i) === false) {
break;
}
}
}
return this;
},
/**
* Goes through each entry in this Set and invokes the given function on them, passing in the arguments.
*
* @method Phaser.Structs.Set#iterateLocal
* @since 3.0.0
*
* @genericUse {Phaser.Structs.Set.<T>} - [$return]
*
* @param {string} callbackKey - The key of the function to be invoked on each Set entry.
* @param {...*} [args] - Additional arguments that will be passed to the callback, after the child.
*
* @return {Phaser.Structs.Set} This Set object.
*/
iterateLocal: function(callbackKey) {
var i;
var args = [];
for (i = 1; i < arguments.length; i++) {
args.push(arguments[i]);
}
var len = this.entries.length;
for (i = 0; i < len; i++) {
var entry = this.entries[i];
entry[callbackKey].apply(entry, args);
}
return this;
},
/**
* Clears this Set so that it no longer contains any values.
*
* @method Phaser.Structs.Set#clear
* @since 3.0.0
*
* @genericUse {Phaser.Structs.Set.<T>} - [$return]
*
* @return {Phaser.Structs.Set} This Set object.
*/
clear: function() {
this.entries.length = 0;
return this;
},
/**
* Returns `true` if this Set contains the given value, otherwise returns `false`.
*
* @method Phaser.Structs.Set#contains
* @since 3.0.0
*
* @genericUse {T} - [value]
*
* @param {*} value - The value to check for in this Set.
*
* @return {boolean} `true` if the given value was found in this Set, otherwise `false`.
*/
contains: function(value) {
return this.entries.indexOf(value) > -1;
},
/**
* Returns a new Set containing all values that are either in this Set or in the Set provided as an argument.
*
* @method Phaser.Structs.Set#union
* @since 3.0.0
*
* @genericUse {Phaser.Structs.Set.<T>} - [set,$return]
*
* @param {Phaser.Structs.Set} set - The Set to perform the union with.
*
* @return {Phaser.Structs.Set} A new Set containing all the values in this Set and the Set provided as an argument.
*/
union: function(set) {
var newSet = new Set();
set.entries.forEach(function(value) {
newSet.set(value);
});
this.entries.forEach(function(value) {
newSet.set(value);
});
return newSet;
},
/**
* Returns a new Set that contains only the values which are in this Set and that are also in the given Set.
*
* @method Phaser.Structs.Set#intersect
* @since 3.0.0
*
* @genericUse {Phaser.Structs.Set.<T>} - [set,$return]
*
* @param {Phaser.Structs.Set} set - The Set to intersect this set with.
*
* @return {Phaser.Structs.Set} The result of the intersection, as a new Set.
*/
intersect: function(set) {
var newSet = new Set();
this.entries.forEach(function(value) {
if (set.contains(value)) {
newSet.set(value);
}
});
return newSet;
},
/**
* Returns a new Set containing all the values in this Set which are *not* also in the given Set.
*
* @method Phaser.Structs.Set#difference
* @since 3.0.0
*
* @genericUse {Phaser.Structs.Set.<T>} - [set,$return]
*
* @param {Phaser.Structs.Set} set - The Set to perform the difference with.
*
* @return {Phaser.Structs.Set} A new Set containing all the values in this Set that are not also in the Set provided as an argument to this method.
*/
difference: function(set) {
var newSet = new Set();
this.entries.forEach(function(value) {
if (!set.contains(value)) {
newSet.set(value);
}
});
return newSet;
},
/**
* The size of this Set. This is the number of entries within it.
* Changing the size will truncate the Set if the given value is smaller than the current size.
* Increasing the size larger than the current size has no effect.
*
* @name Phaser.Structs.Set#size
* @type {number}
* @since 3.0.0
*/
size: {
get: function() {
return this.entries.length;
},
set: function(value) {
if (value < this.entries.length) {
return this.entries.length = value;
} else {
return this.entries.length;
}
}
}
});
module2.exports = Set;
}
),
/***/
86555: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Clamp = __webpack_require__2(45319);
var Class = __webpack_require__2(83419);
var SnapFloor = __webpack_require__2(56583);
var Vector2 = __webpack_require__2(26099);
var Size = new Class({
initialize: function Size2(width, height, aspectMode, parent) {
if (width === void 0) {
width = 0;
}
if (height === void 0) {
height = width;
}
if (aspectMode === void 0) {
aspectMode = 0;
}
if (parent === void 0) {
parent = null;
}
this._width = width;
this._height = height;
this._parent = parent;
this.aspectMode = aspectMode;
this.aspectRatio = height === 0 ? 1 : width / height;
this.minWidth = 0;
this.minHeight = 0;
this.maxWidth = Number.MAX_VALUE;
this.maxHeight = Number.MAX_VALUE;
this.snapTo = new Vector2();
},
/**
* Sets the aspect mode of this Size component.
*
* The aspect mode controls what happens when you modify the `width` or `height` properties, or call `setSize`.
*
* It can be a number from 0 to 4, or a Size constant:
*
* 0. NONE = Do not make the size fit the aspect ratio. Change the ratio when the size changes.
* 1. WIDTH_CONTROLS_HEIGHT = The height is automatically adjusted based on the width.
* 2. HEIGHT_CONTROLS_WIDTH = The width is automatically adjusted based on the height.
* 3. FIT = The width and height are automatically adjusted to fit inside the given target area, while keeping the aspect ratio. Depending on the aspect ratio there may be some space inside the area which is not covered.
* 4. ENVELOP = The width and height are automatically adjusted to make the size cover the entire target area while keeping the aspect ratio. This may extend further out than the target size.
*
* Calling this method automatically recalculates the `width` and the `height`, if required.
*
* @method Phaser.Structs.Size#setAspectMode
* @since 3.16.0
*
* @param {number} [value=0] - The aspect mode value.
*
* @return {this} This Size component instance.
*/
setAspectMode: function(value) {
if (value === void 0) {
value = 0;
}
this.aspectMode = value;
return this.setSize(this._width, this._height);
},
/**
* By setting snap values, when this Size component is modified its dimensions will automatically
* be snapped to the nearest grid slice, using floor. For example, if you have snap value of 16,
* and the width changes to 68, then it will snap down to 64 (the closest multiple of 16 when floored)
*
* Note that snapping takes place before adjustments by the parent, or the min / max settings. If these
* values are not multiples of the given snap values, then this can result in un-snapped dimensions.
*
* Call this method with no arguments to reset the snap values.
*
* Calling this method automatically recalculates the `width` and the `height`, if required.
*
* @method Phaser.Structs.Size#setSnap
* @since 3.16.0
*
* @param {number} [snapWidth=0] - The amount to snap the width to. If you don't want to snap the width, pass a value of zero.
* @param {number} [snapHeight=snapWidth] - The amount to snap the height to. If not provided it will use the `snapWidth` value. If you don't want to snap the height, pass a value of zero.
*
* @return {this} This Size component instance.
*/
setSnap: function(snapWidth, snapHeight) {
if (snapWidth === void 0) {
snapWidth = 0;
}
if (snapHeight === void 0) {
snapHeight = snapWidth;
}
this.snapTo.set(snapWidth, snapHeight);
return this.setSize(this._width, this._height);
},
/**
* Sets, or clears, the parent of this Size component.
*
* To clear the parent call this method with no arguments.
*
* The parent influences the maximum extents to which this Size component can expand,
* based on the aspect mode:
*
* NONE - The parent clamps both the width and height.
* WIDTH_CONTROLS_HEIGHT - The parent clamps just the width.
* HEIGHT_CONTROLS_WIDTH - The parent clamps just the height.
* FIT - The parent clamps whichever axis is required to ensure the size fits within it.
* ENVELOP - The parent is used to ensure the size fully envelops the parent.
*
* Calling this method automatically calls `setSize`.
*
* @method Phaser.Structs.Size#setParent
* @since 3.16.0
*
* @param {any} [parent] - Sets the parent of this Size component. Don't provide a value to clear an existing parent.
*
* @return {this} This Size component instance.
*/
setParent: function(parent) {
this._parent = parent;
return this.setSize(this._width, this._height);
},
/**
* Set the minimum width and height values this Size component will allow.
*
* The minimum values can never be below zero, or greater than the maximum values.
*
* Setting this will automatically adjust both the `width` and `height` properties to ensure they are within range.
*
* Note that based on the aspect mode, and if this Size component has a parent set or not, the minimums set here
* _can_ be exceed in some situations.
*
* @method Phaser.Structs.Size#setMin
* @since 3.16.0
*
* @param {number} [width=0] - The minimum allowed width of the Size component.
* @param {number} [height=width] - The minimum allowed height of the Size component. If not given, it will use the `width`.
*
* @return {this} This Size component instance.
*/
setMin: function(width, height) {
if (width === void 0) {
width = 0;
}
if (height === void 0) {
height = width;
}
this.minWidth = Clamp(width, 0, this.maxWidth);
this.minHeight = Clamp(height, 0, this.maxHeight);
return this.setSize(this._width, this._height);
},
/**
* Set the maximum width and height values this Size component will allow.
*
* Setting this will automatically adjust both the `width` and `height` properties to ensure they are within range.
*
* Note that based on the aspect mode, and if this Size component has a parent set or not, the maximums set here
* _can_ be exceed in some situations.
*
* @method Phaser.Structs.Size#setMax
* @since 3.16.0
*
* @param {number} [width=Number.MAX_VALUE] - The maximum allowed width of the Size component.
* @param {number} [height=width] - The maximum allowed height of the Size component. If not given, it will use the `width`.
*
* @return {this} This Size component instance.
*/
setMax: function(width, height) {
if (width === void 0) {
width = Number.MAX_VALUE;
}
if (height === void 0) {
height = width;
}
this.maxWidth = Clamp(width, this.minWidth, Number.MAX_VALUE);
this.maxHeight = Clamp(height, this.minHeight, Number.MAX_VALUE);
return this.setSize(this._width, this._height);
},
/**
* Sets the width and height of this Size component based on the aspect mode.
*
* If the aspect mode is 'none' then calling this method will change the aspect ratio, otherwise the current
* aspect ratio is honored across all other modes.
*
* If snapTo values have been set then the given width and height are snapped first, prior to any further
* adjustment via min/max values, or a parent.
*
* If minimum and/or maximum dimensions have been specified, the values given to this method will be clamped into
* that range prior to adjustment, but may still exceed them depending on the aspect mode.
*
* If this Size component has a parent set, and the aspect mode is `fit` or `envelop`, then the given sizes will
* be clamped to the range specified by the parent.
*
* @method Phaser.Structs.Size#setSize
* @since 3.16.0
*
* @param {number} [width=0] - The new width of the Size component.
* @param {number} [height=width] - The new height of the Size component. If not given, it will use the `width`.
*
* @return {this} This Size component instance.
*/
setSize: function(width, height) {
if (width === void 0) {
width = 0;
}
if (height === void 0) {
height = width;
}
switch (this.aspectMode) {
case Size.NONE:
this._width = this.getNewWidth(SnapFloor(width, this.snapTo.x));
this._height = this.getNewHeight(SnapFloor(height, this.snapTo.y));
this.aspectRatio = this._height === 0 ? 1 : this._width / this._height;
break;
case Size.WIDTH_CONTROLS_HEIGHT:
this._width = this.getNewWidth(SnapFloor(width, this.snapTo.x));
this._height = this.getNewHeight(this._width * (1 / this.aspectRatio), false);
break;
case Size.HEIGHT_CONTROLS_WIDTH:
this._height = this.getNewHeight(SnapFloor(height, this.snapTo.y));
this._width = this.getNewWidth(this._height * this.aspectRatio, false);
break;
case Size.FIT:
this.constrain(width, height, true);
break;
case Size.ENVELOP:
this.constrain(width, height, false);
break;
}
return this;
},
/**
* Sets a new aspect ratio, overriding what was there previously.
*
* It then calls `setSize` immediately using the current dimensions.
*
* @method Phaser.Structs.Size#setAspectRatio
* @since 3.16.0
*
* @param {number} ratio - The new aspect ratio.
*
* @return {this} This Size component instance.
*/
setAspectRatio: function(ratio) {
this.aspectRatio = ratio;
return this.setSize(this._width, this._height);
},
/**
* Sets a new width and height for this Size component and updates the aspect ratio based on them.
*
* It _doesn't_ change the `aspectMode` and still factors in size limits such as the min max and parent bounds.
*
* @method Phaser.Structs.Size#resize
* @since 3.16.0
*
* @param {number} width - The new width of the Size component.
* @param {number} [height=width] - The new height of the Size component. If not given, it will use the `width`.
*
* @return {this} This Size component instance.
*/
resize: function(width, height) {
this._width = this.getNewWidth(SnapFloor(width, this.snapTo.x));
this._height = this.getNewHeight(SnapFloor(height, this.snapTo.y));
this.aspectRatio = this._height === 0 ? 1 : this._width / this._height;
return this;
},
/**
* Takes a new width and passes it through the min/max clamp and then checks it doesn't exceed the parent width.
*
* @method Phaser.Structs.Size#getNewWidth
* @since 3.16.0
*
* @param {number} value - The value to clamp and check.
* @param {boolean} [checkParent=true] - Check the given value against the parent, if set.
*
* @return {number} The modified width value.
*/
getNewWidth: function(value, checkParent) {
if (checkParent === void 0) {
checkParent = true;
}
value = Clamp(value, this.minWidth, this.maxWidth);
if (checkParent && this._parent && value > this._parent.width) {
value = Math.max(this.minWidth, this._parent.width);
}
return value;
},
/**
* Takes a new height and passes it through the min/max clamp and then checks it doesn't exceed the parent height.
*
* @method Phaser.Structs.Size#getNewHeight
* @since 3.16.0
*
* @param {number} value - The value to clamp and check.
* @param {boolean} [checkParent=true] - Check the given value against the parent, if set.
*
* @return {number} The modified height value.
*/
getNewHeight: function(value, checkParent) {
if (checkParent === void 0) {
checkParent = true;
}
value = Clamp(value, this.minHeight, this.maxHeight);
if (checkParent && this._parent && value > this._parent.height) {
value = Math.max(this.minHeight, this._parent.height);
}
return value;
},
/**
* The current `width` and `height` are adjusted to fit inside the given dimensions, while keeping the aspect ratio.
*
* If `fit` is true there may be some space inside the target area which is not covered if its aspect ratio differs.
* If `fit` is false the size may extend further out than the target area if the aspect ratios differ.
*
* If this Size component has a parent set, then the width and height passed to this method will be clamped so
* it cannot exceed that of the parent.
*
* @method Phaser.Structs.Size#constrain
* @since 3.16.0
*
* @param {number} [width=0] - The new width of the Size component.
* @param {number} [height] - The new height of the Size component. If not given, it will use the width value.
* @param {boolean} [fit=true] - Perform a `fit` (true) constraint, or an `envelop` (false) constraint.
*
* @return {this} This Size component instance.
*/
constrain: function(width, height, fit) {
if (width === void 0) {
width = 0;
}
if (height === void 0) {
height = width;
}
if (fit === void 0) {
fit = true;
}
width = this.getNewWidth(width);
height = this.getNewHeight(height);
var snap = this.snapTo;
var newRatio = height === 0 ? 1 : width / height;
if (fit && this.aspectRatio > newRatio || !fit && this.aspectRatio < newRatio) {
width = SnapFloor(width, snap.x);
height = width / this.aspectRatio;
if (snap.y > 0) {
height = SnapFloor(height, snap.y);
width = height * this.aspectRatio;
}
} else if (fit && this.aspectRatio < newRatio || !fit && this.aspectRatio > newRatio) {
height = SnapFloor(height, snap.y);
width = height * this.aspectRatio;
if (snap.x > 0) {
width = SnapFloor(width, snap.x);
height = width * (1 / this.aspectRatio);
}
}
this._width = width;
this._height = height;
return this;
},
/**
* The current `width` and `height` are adjusted to fit inside the given dimensions, while keeping the aspect ratio.
*
* There may be some space inside the target area which is not covered if its aspect ratio differs.
*
* If this Size component has a parent set, then the width and height passed to this method will be clamped so
* it cannot exceed that of the parent.
*
* @method Phaser.Structs.Size#fitTo
* @since 3.16.0
*
* @param {number} [width=0] - The new width of the Size component.
* @param {number} [height] - The new height of the Size component. If not given, it will use the width value.
*
* @return {this} This Size component instance.
*/
fitTo: function(width, height) {
return this.constrain(width, height, true);
},
/**
* The current `width` and `height` are adjusted so that they fully envelope the given dimensions, while keeping the aspect ratio.
*
* The size may extend further out than the target area if the aspect ratios differ.
*
* If this Size component has a parent set, then the values are clamped so that it never exceeds the parent
* on the longest axis.
*
* @method Phaser.Structs.Size#envelop
* @since 3.16.0
*
* @param {number} [width=0] - The new width of the Size component.
* @param {number} [height] - The new height of the Size component. If not given, it will use the width value.
*
* @return {this} This Size component instance.
*/
envelop: function(width, height) {
return this.constrain(width, height, false);
},
/**
* Sets the width of this Size component.
*
* Depending on the aspect mode, changing the width may also update the height and aspect ratio.
*
* @method Phaser.Structs.Size#setWidth
* @since 3.16.0
*
* @param {number} width - The new width of the Size component.
*
* @return {this} This Size component instance.
*/
setWidth: function(value) {
return this.setSize(value, this._height);
},
/**
* Sets the height of this Size component.
*
* Depending on the aspect mode, changing the height may also update the width and aspect ratio.
*
* @method Phaser.Structs.Size#setHeight
* @since 3.16.0
*
* @param {number} height - The new height of the Size component.
*
* @return {this} This Size component instance.
*/
setHeight: function(value) {
return this.setSize(this._width, value);
},
/**
* Returns a string representation of this Size component.
*
* @method Phaser.Structs.Size#toString
* @since 3.16.0
*
* @return {string} A string representation of this Size component.
*/
toString: function() {
return "[{ Size (width=" + this._width + " height=" + this._height + " aspectRatio=" + this.aspectRatio + " aspectMode=" + this.aspectMode + ") }]";
},
/**
* Sets the values of this Size component to the `element.style.width` and `height`
* properties of the given DOM Element. The properties are set as `px` values.
*
* @method Phaser.Structs.Size#setCSS
* @since 3.17.0
*
* @param {HTMLElement} element - The DOM Element to set the CSS style on.
*/
setCSS: function(element) {
if (element && element.style) {
element.style.width = this._width + "px";
element.style.height = this._height + "px";
}
},
/**
* Copies the aspect mode, aspect ratio, width and height from this Size component
* to the given Size component. Note that the parent, if set, is not copied across.
*
* @method Phaser.Structs.Size#copy
* @since 3.16.0
*
* @param {Phaser.Structs.Size} destination - The Size component to copy the values to.
*
* @return {Phaser.Structs.Size} The updated destination Size component.
*/
copy: function(destination) {
destination.setAspectMode(this.aspectMode);
destination.aspectRatio = this.aspectRatio;
return destination.setSize(this.width, this.height);
},
/**
* Destroys this Size component.
*
* This clears the local properties and any parent object, if set.
*
* A destroyed Size component cannot be re-used.
*
* @method Phaser.Structs.Size#destroy
* @since 3.16.0
*/
destroy: function() {
this._parent = null;
this.snapTo = null;
},
/**
* The width of this Size component.
*
* This value is clamped to the range specified by `minWidth` and `maxWidth`, if enabled.
*
* A width can never be less than zero.
*
* Changing this value will automatically update the `height` if the aspect ratio lock is enabled.
* You can also use the `setWidth` and `getWidth` methods.
*
* @name Phaser.Structs.Size#width
* @type {number}
* @since 3.16.0
*/
width: {
get: function() {
return this._width;
},
set: function(value) {
this.setSize(value, this._height);
}
},
/**
* The height of this Size component.
*
* This value is clamped to the range specified by `minHeight` and `maxHeight`, if enabled.
*
* A height can never be less than zero.
*
* Changing this value will automatically update the `width` if the aspect ratio lock is enabled.
* You can also use the `setHeight` and `getHeight` methods.
*
* @name Phaser.Structs.Size#height
* @type {number}
* @since 3.16.0
*/
height: {
get: function() {
return this._height;
},
set: function(value) {
this.setSize(this._width, value);
}
}
});
Size.NONE = 0;
Size.WIDTH_CONTROLS_HEIGHT = 1;
Size.HEIGHT_CONTROLS_WIDTH = 2;
Size.FIT = 3;
Size.ENVELOP = 4;
module2.exports = Size;
}
),
/***/
15238: (
/***/
(module2) => {
module2.exports = "add";
}
),
/***/
56187: (
/***/
(module2) => {
module2.exports = "remove";
}
),
/***/
82348: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
PROCESS_QUEUE_ADD: __webpack_require__2(15238),
PROCESS_QUEUE_REMOVE: __webpack_require__2(56187)
};
}
),
/***/
41392: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Events: __webpack_require__2(82348),
List: __webpack_require__2(73162),
Map: __webpack_require__2(90330),
ProcessQueue: __webpack_require__2(25774),
RTree: __webpack_require__2(59542),
Set: __webpack_require__2(35072),
Size: __webpack_require__2(86555)
};
}
),
/***/
57382: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Clamp = __webpack_require__2(45319);
var Color = __webpack_require__2(40987);
var CONST = __webpack_require__2(8054);
var IsSizePowerOfTwo = __webpack_require__2(50030);
var Texture = __webpack_require__2(79237);
var CanvasTexture = new Class({
Extends: Texture,
initialize: function CanvasTexture2(manager, key, source, width, height) {
Texture.call(this, manager, key, source, width, height);
this.add("__BASE", 0, 0, 0, width, height);
this._source = this.frames["__BASE"].source;
this.canvas = this._source.image;
this.context = this.canvas.getContext("2d", { willReadFrequently: true });
this.width = width;
this.height = height;
this.imageData = this.context.getImageData(0, 0, width, height);
this.data = null;
if (this.imageData) {
this.data = this.imageData.data;
}
this.pixels = null;
this.buffer;
if (this.data) {
if (this.imageData.data.buffer) {
this.buffer = this.imageData.data.buffer;
this.pixels = new Uint32Array(this.buffer);
} else if (window.ArrayBuffer) {
this.buffer = new ArrayBuffer(this.imageData.data.length);
this.pixels = new Uint32Array(this.buffer);
} else {
this.pixels = this.imageData.data;
}
}
},
/**
* This re-creates the `imageData` from the current context.
* It then re-builds the ArrayBuffer, the `data` Uint8ClampedArray reference and the `pixels` Int32Array.
*
* Warning: This is a very expensive operation, so use it sparingly.
*
* @method Phaser.Textures.CanvasTexture#update
* @since 3.13.0
*
* @return {Phaser.Textures.CanvasTexture} This CanvasTexture.
*/
update: function() {
this.imageData = this.context.getImageData(0, 0, this.width, this.height);
this.data = this.imageData.data;
if (this.imageData.data.buffer) {
this.buffer = this.imageData.data.buffer;
this.pixels = new Uint32Array(this.buffer);
} else if (window.ArrayBuffer) {
this.buffer = new ArrayBuffer(this.imageData.data.length);
this.pixels = new Uint32Array(this.buffer);
} else {
this.pixels = this.imageData.data;
}
if (this.manager.game.config.renderType === CONST.WEBGL) {
this.refresh();
}
return this;
},
/**
* Draws the given Image or Canvas element to this CanvasTexture, then updates the internal
* ImageData buffer and arrays.
*
* @method Phaser.Textures.CanvasTexture#draw
* @since 3.13.0
*
* @param {number} x - The x coordinate to draw the source at.
* @param {number} y - The y coordinate to draw the source at.
* @param {(HTMLImageElement|HTMLCanvasElement)} source - The element to draw to this canvas.
* @param {boolean} [update=true] - Update the internal ImageData buffer and arrays.
*
* @return {Phaser.Textures.CanvasTexture} This CanvasTexture.
*/
draw: function(x, y, source, update) {
if (update === void 0) {
update = true;
}
this.context.drawImage(source, x, y);
if (update) {
this.update();
}
return this;
},
/**
* Draws the given texture frame to this CanvasTexture, then updates the internal
* ImageData buffer and arrays.
*
* @method Phaser.Textures.CanvasTexture#drawFrame
* @since 3.16.0
*
* @param {string} key - The unique string-based key of the Texture.
* @param {(string|number)} [frame] - The string-based name, or integer based index, of the Frame to get from the Texture.
* @param {number} [x=0] - The x coordinate to draw the source at.
* @param {number} [y=0] - The y coordinate to draw the source at.
* @param {boolean} [update=true] - Update the internal ImageData buffer and arrays.
*
* @return {Phaser.Textures.CanvasTexture} This CanvasTexture.
*/
drawFrame: function(key, frame, x, y, update) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (update === void 0) {
update = true;
}
var textureFrame = this.manager.getFrame(key, frame);
if (textureFrame) {
var cd = textureFrame.canvasData;
var width = textureFrame.cutWidth;
var height = textureFrame.cutHeight;
var res = textureFrame.source.resolution;
this.context.drawImage(
textureFrame.source.image,
cd.x,
cd.y,
width,
height,
x,
y,
width / res,
height / res
);
if (update) {
this.update();
}
}
return this;
},
/**
* Sets a pixel in the CanvasTexture to the given color and alpha values.
*
* This is an expensive operation to run in large quantities, so use sparingly.
*
* @method Phaser.Textures.CanvasTexture#setPixel
* @since 3.16.0
*
* @param {number} x - The x coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer.
* @param {number} y - The y coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer.
* @param {number} red - The red color value. A number between 0 and 255.
* @param {number} green - The green color value. A number between 0 and 255.
* @param {number} blue - The blue color value. A number between 0 and 255.
* @param {number} [alpha=255] - The alpha value. A number between 0 and 255.
*
* @return {this} This CanvasTexture.
*/
setPixel: function(x, y, red, green, blue, alpha) {
if (alpha === void 0) {
alpha = 255;
}
x = Math.abs(Math.floor(x));
y = Math.abs(Math.floor(y));
var index = this.getIndex(x, y);
if (index > -1) {
var imageData = this.context.getImageData(x, y, 1, 1);
imageData.data[0] = red;
imageData.data[1] = green;
imageData.data[2] = blue;
imageData.data[3] = alpha;
this.context.putImageData(imageData, x, y);
}
return this;
},
/**
* Puts the ImageData into the context of this CanvasTexture at the given coordinates.
*
* @method Phaser.Textures.CanvasTexture#putData
* @since 3.16.0
*
* @param {ImageData} imageData - The ImageData to put at the given location.
* @param {number} x - The x coordinate to put the imageData. Must lay within the dimensions of this CanvasTexture and be an integer.
* @param {number} y - The y coordinate to put the imageData. Must lay within the dimensions of this CanvasTexture and be an integer.
* @param {number} [dirtyX=0] - Horizontal position (x coordinate) of the top-left corner from which the image data will be extracted.
* @param {number} [dirtyY=0] - Vertical position (x coordinate) of the top-left corner from which the image data will be extracted.
* @param {number} [dirtyWidth] - Width of the rectangle to be painted. Defaults to the width of the image data.
* @param {number} [dirtyHeight] - Height of the rectangle to be painted. Defaults to the height of the image data.
*
* @return {this} This CanvasTexture.
*/
putData: function(imageData, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight) {
if (dirtyX === void 0) {
dirtyX = 0;
}
if (dirtyY === void 0) {
dirtyY = 0;
}
if (dirtyWidth === void 0) {
dirtyWidth = imageData.width;
}
if (dirtyHeight === void 0) {
dirtyHeight = imageData.height;
}
this.context.putImageData(imageData, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight);
return this;
},
/**
* Gets an ImageData region from this CanvasTexture from the position and size specified.
* You can write this back using `CanvasTexture.putData`, or manipulate it.
*
* @method Phaser.Textures.CanvasTexture#getData
* @since 3.16.0
*
* @param {number} x - The x coordinate of the top-left of the area to get the ImageData from. Must lay within the dimensions of this CanvasTexture and be an integer.
* @param {number} y - The y coordinate of the top-left of the area to get the ImageData from. Must lay within the dimensions of this CanvasTexture and be an integer.
* @param {number} width - The width of the rectangle from which the ImageData will be extracted. Positive values are to the right, and negative to the left.
* @param {number} height - The height of the rectangle from which the ImageData will be extracted. Positive values are down, and negative are up.
*
* @return {ImageData} The ImageData extracted from this CanvasTexture.
*/
getData: function(x, y, width, height) {
x = Clamp(Math.floor(x), 0, this.width - 1);
y = Clamp(Math.floor(y), 0, this.height - 1);
width = Clamp(width, 1, this.width - x);
height = Clamp(height, 1, this.height - y);
var imageData = this.context.getImageData(x, y, width, height);
return imageData;
},
/**
* Get the color of a specific pixel from this texture and store it in a Color object.
*
* If you have drawn anything to this CanvasTexture since it was created you must call `CanvasTexture.update` to refresh the array buffer,
* otherwise this may return out of date color values, or worse - throw a run-time error as it tries to access an array element that doesn't exist.
*
* @method Phaser.Textures.CanvasTexture#getPixel
* @since 3.13.0
*
* @param {number} x - The x coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer.
* @param {number} y - The y coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer.
* @param {Phaser.Display.Color} [out] - A Color object to store the pixel values in. If not provided a new Color object will be created.
*
* @return {Phaser.Display.Color} An object with the red, green, blue and alpha values set in the r, g, b and a properties.
*/
getPixel: function(x, y, out) {
if (!out) {
out = new Color();
}
var index = this.getIndex(x, y);
if (index > -1) {
var data = this.data;
var r = data[index + 0];
var g = data[index + 1];
var b = data[index + 2];
var a = data[index + 3];
out.setTo(r, g, b, a);
}
return out;
},
/**
* Returns an array containing all of the pixels in the given region.
*
* If the requested region extends outside the bounds of this CanvasTexture,
* the region is truncated to fit.
*
* If you have drawn anything to this CanvasTexture since it was created you must call `CanvasTexture.update` to refresh the array buffer,
* otherwise this may return out of date color values, or worse - throw a run-time error as it tries to access an array element that doesn't exist.
*
* @method Phaser.Textures.CanvasTexture#getPixels
* @since 3.16.0
*
* @param {number} [x=0] - The x coordinate of the top-left of the region. Must lay within the dimensions of this CanvasTexture and be an integer.
* @param {number} [y=0] - The y coordinate of the top-left of the region. Must lay within the dimensions of this CanvasTexture and be an integer.
* @param {number} [width] - The width of the region to get. Must be an integer. Defaults to the canvas width if not given.
* @param {number} [height] - The height of the region to get. Must be an integer. If not given will be set to the `width`.
*
* @return {Phaser.Types.Textures.PixelConfig[][]} A 2d array of Pixel objects.
*/
getPixels: function(x, y, width, height) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (width === void 0) {
width = this.width;
}
if (height === void 0) {
height = width;
}
x = Math.abs(Math.round(x));
y = Math.abs(Math.round(y));
var left = Clamp(x, 0, this.width);
var right = Clamp(x + width, 0, this.width);
var top = Clamp(y, 0, this.height);
var bottom = Clamp(y + height, 0, this.height);
var pixel = new Color();
var out = [];
for (var py = top; py < bottom; py++) {
var row = [];
for (var px = left; px < right; px++) {
pixel = this.getPixel(px, py, pixel);
row.push({ x: px, y: py, color: pixel.color, alpha: pixel.alphaGL });
}
out.push(row);
}
return out;
},
/**
* Returns the Image Data index for the given pixel in this CanvasTexture.
*
* The index can be used to read directly from the `this.data` array.
*
* The index points to the red value in the array. The subsequent 3 indexes
* point to green, blue and alpha respectively.
*
* @method Phaser.Textures.CanvasTexture#getIndex
* @since 3.16.0
*
* @param {number} x - The x coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer.
* @param {number} y - The y coordinate of the pixel to get. Must lay within the dimensions of this CanvasTexture and be an integer.
*
* @return {number}
*/
getIndex: function(x, y) {
x = Math.abs(Math.round(x));
y = Math.abs(Math.round(y));
if (x < this.width && y < this.height) {
return (x + y * this.width) * 4;
} else {
return -1;
}
},
/**
* This should be called manually if you are running under WebGL.
* It will refresh the WebGLTexture from the Canvas source. Only call this if you know that the
* canvas has changed, as there is a significant GPU texture allocation cost involved in doing so.
*
* @method Phaser.Textures.CanvasTexture#refresh
* @since 3.7.0
*
* @return {Phaser.Textures.CanvasTexture} This CanvasTexture.
*/
refresh: function() {
this._source.update();
return this;
},
/**
* Gets the Canvas Element.
*
* @method Phaser.Textures.CanvasTexture#getCanvas
* @since 3.7.0
*
* @return {HTMLCanvasElement} The Canvas DOM element this texture is using.
*/
getCanvas: function() {
return this.canvas;
},
/**
* Gets the 2D Canvas Rendering Context.
*
* @method Phaser.Textures.CanvasTexture#getContext
* @since 3.7.0
*
* @return {CanvasRenderingContext2D} The Canvas Rendering Context this texture is using.
*/
getContext: function() {
return this.context;
},
/**
* Clears the given region of this Canvas Texture, resetting it back to transparent.
* If no region is given, the whole Canvas Texture is cleared.
*
* @method Phaser.Textures.CanvasTexture#clear
* @since 3.7.0
*
* @param {number} [x=0] - The x coordinate of the top-left of the region to clear.
* @param {number} [y=0] - The y coordinate of the top-left of the region to clear.
* @param {number} [width] - The width of the region.
* @param {number} [height] - The height of the region.
* @param {boolean} [update=true] - Update the internal ImageData buffer and arrays.
*
* @return {Phaser.Textures.CanvasTexture} The Canvas Texture.
*/
clear: function(x, y, width, height, update) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (width === void 0) {
width = this.width;
}
if (height === void 0) {
height = this.height;
}
if (update === void 0) {
update = true;
}
this.context.clearRect(x, y, width, height);
if (update) {
this.update();
}
return this;
},
/**
* Changes the size of this Canvas Texture.
*
* @method Phaser.Textures.CanvasTexture#setSize
* @since 3.7.0
*
* @param {number} width - The new width of the Canvas.
* @param {number} [height] - The new height of the Canvas. If not given it will use the width as the height.
*
* @return {Phaser.Textures.CanvasTexture} The Canvas Texture.
*/
setSize: function(width, height) {
if (height === void 0) {
height = width;
}
if (width !== this.width || height !== this.height) {
this.canvas.width = width;
this.canvas.height = height;
this._source.width = width;
this._source.height = height;
this._source.isPowerOf2 = IsSizePowerOfTwo(width, height);
this.frames["__BASE"].setSize(width, height, 0, 0);
this.width = width;
this.height = height;
this.refresh();
}
return this;
},
/**
* Destroys this Texture and releases references to its sources and frames.
*
* @method Phaser.Textures.CanvasTexture#destroy
* @since 3.16.0
*/
destroy: function() {
Texture.prototype.destroy.call(this);
this._source = null;
this.canvas = null;
this.context = null;
this.imageData = null;
this.data = null;
this.pixels = null;
this.buffer = null;
}
});
module2.exports = CanvasTexture;
}
),
/***/
81320: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BlendModes = __webpack_require__2(10312);
var Camera = __webpack_require__2(38058);
var CanvasPool = __webpack_require__2(27919);
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(8054);
var Frame = __webpack_require__2(4327);
var GetFastValue = __webpack_require__2(95540);
var PIPELINES = __webpack_require__2(36060);
var RenderTarget = __webpack_require__2(32302);
var Texture = __webpack_require__2(79237);
var Utils = __webpack_require__2(70554);
var DynamicTexture = new Class({
Extends: Texture,
initialize: function DynamicTexture2(manager, key, width, height) {
if (width === void 0) {
width = 256;
}
if (height === void 0) {
height = 256;
}
this.type = "DynamicTexture";
var renderer = manager.game.renderer;
var isCanvas = renderer && renderer.type === CONST.CANVAS;
var source = isCanvas ? CanvasPool.create2D(this, width, height) : [this];
Texture.call(this, manager, key, source, width, height);
this.add("__BASE", 0, 0, 0, width, height);
this.renderer = renderer;
this.width = -1;
this.height = -1;
this.isDrawing = false;
this.canvas = isCanvas ? source : null;
this.context = isCanvas ? source.getContext("2d", { willReadFrequently: true }) : null;
this.dirty = false;
this.isSpriteTexture = true;
this._eraseMode = false;
this.camera = new Camera(0, 0, width, height).setScene(manager.game.scene.systemScene, false);
this.renderTarget = !isCanvas ? new RenderTarget(renderer, width, height, 1, 0, false, false, true, false) : null;
this.pipeline = !isCanvas ? renderer.pipelines.get(PIPELINES.SINGLE_PIPELINE) : null;
this.setSize(width, height);
},
/**
* Resizes this Dynamic Texture to the new dimensions given.
*
* In WebGL it will destroy and then re-create the frame buffer being used by this Dynamic Texture.
* In Canvas it will resize the underlying canvas DOM element.
*
* Both approaches will erase everything currently drawn to this texture.
*
* If the dimensions given are the same as those already being used, calling this method will do nothing.
*
* @method Phaser.Textures.DynamicTexture#setSize
* @since 3.10.0
*
* @param {number} width - The new width of this Dynamic Texture.
* @param {number} [height=width] - The new height of this Dynamic Texture. If not specified, will be set the same as the `width`.
*
* @return {this} This Dynamic Texture.
*/
setSize: function(width, height) {
if (height === void 0) {
height = width;
}
var frame = this.get();
var source = frame.source;
if (width !== this.width || height !== this.height) {
if (this.canvas) {
this.canvas.width = width;
this.canvas.height = height;
}
var renderTarget = this.renderTarget;
if (renderTarget) {
if (renderTarget.willResize(width, height)) {
renderTarget.resize(width, height);
}
if (renderTarget.texture !== source.glTexture) {
this.renderer.deleteTexture(source.glTexture);
}
this.setFromRenderTarget();
}
this.camera.setSize(width, height);
source.width = width;
source.height = height;
frame.setSize(width, height);
this.width = width;
this.height = height;
} else {
var baseFrame = this.getSourceImage();
if (frame.cutX + width > baseFrame.width) {
width = baseFrame.width - frame.cutX;
}
if (frame.cutY + height > baseFrame.height) {
height = baseFrame.height - frame.cutY;
}
frame.setSize(width, height, frame.cutX, frame.cutY);
}
return this;
},
/**
* Links the WebGL Textures used by this Dynamic Texture to its Render Target.
*
* This method is called internally by the Dynamic Texture when it is first created,
* or if you change its size.
*
* @method Phaser.Textures.DynamicTexture#setFromRenderTarget
* @since 3.70.0
*
* @return {this} This Dynamic Texture instance.
*/
setFromRenderTarget: function() {
var frame = this.get();
var source = frame.source;
var renderTarget = this.renderTarget;
source.isRenderTexture = true;
source.isGLTexture = true;
source.glTexture = renderTarget.texture;
return this;
},
/**
* If you are planning on using this Render Texture as a base texture for Sprite
* Game Objects, then you should call this method with a value of `true` before
* drawing anything to it, otherwise you will get inverted frames in WebGL.
*
* @method Phaser.Textures.DynamicTexture#setIsSpriteTexture
* @since 3.60.0
*
* @param {boolean} value - Is this Render Target being used as a Sprite Texture, or not?
*
* @return {this} This Dynamic Texture instance.
*/
setIsSpriteTexture: function(value) {
this.isSpriteTexture = value;
return this;
},
/**
* Fills this Dynamic Texture with the given color.
*
* By default it will fill the entire texture, however you can set it to fill a specific
* rectangular area by using the x, y, width and height arguments.
*
* The color should be given in hex format, i.e. 0xff0000 for red, 0x00ff00 for green, etc.
*
* @method Phaser.Textures.DynamicTexture#fill
* @since 3.2.0
*
* @param {number} rgb - The color to fill this Dynamic Texture with, such as 0xff0000 for red.
* @param {number} [alpha=1] - The alpha value used by the fill.
* @param {number} [x=0] - The left coordinate of the fill rectangle.
* @param {number} [y=0] - The top coordinate of the fill rectangle.
* @param {number} [width=this.width] - The width of the fill rectangle.
* @param {number} [height=this.height] - The height of the fill rectangle.
*
* @return {this} This Dynamic Texture instance.
*/
fill: function(rgb, alpha, x, y, width, height) {
var camera = this.camera;
var renderer = this.renderer;
if (alpha === void 0) {
alpha = 1;
}
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (width === void 0) {
width = this.width;
}
if (height === void 0) {
height = this.height;
}
var r = rgb >> 16 & 255;
var g = rgb >> 8 & 255;
var b = rgb & 255;
var renderTarget = this.renderTarget;
camera.preRender();
if (renderTarget) {
renderTarget.bind(true);
var pipeline = this.pipeline.manager.set(this.pipeline);
var sx = renderer.width / renderTarget.width;
var sy = renderer.height / renderTarget.height;
var ty = renderTarget.height - (y + height);
pipeline.drawFillRect(
x * sx,
ty * sy,
width * sx,
height * sy,
Utils.getTintFromFloats(b / 255, g / 255, r / 255, 1),
alpha
);
renderTarget.unbind(true);
} else {
var ctx = this.context;
renderer.setContext(ctx);
ctx.globalCompositeOperation = "source-over";
ctx.fillStyle = "rgba(" + r + "," + g + "," + b + "," + alpha + ")";
ctx.fillRect(x, y, width, height);
renderer.setContext();
}
this.dirty = true;
return this;
},
/**
* Clears a portion or everything from this Dynamic Texture by erasing it and resetting it back to
* a blank, transparent, texture. To clear an area, specify the `x`, `y`, `width` and `height`.
* @method Phaser.Textures.DynamicTexture#clear
* @since 3.2.0
*
* @param {number} [x=0] - The left coordinate of the fill rectangle.
* @param {number} [y=0] - The top coordinate of the fill rectangle.
* @param {number} [width=this.width] - The width of the fill rectangle.
* @param {number} [height=this.height] - The height of the fill rectangle.
*
* @return {this} This Dynamic Texture instance.
*/
clear: function(x, y, width, height) {
if (this.dirty) {
var ctx = this.context;
var renderTarget = this.renderTarget;
if (renderTarget) {
renderTarget.clear(x, y, width, height);
} else if (ctx) {
if (x !== void 0 && y !== void 0 && width !== void 0 && height !== void 0) {
ctx.clearRect(x, y, width, height);
} else {
ctx.save();
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, this.width, this.height);
ctx.restore();
}
}
this.dirty = false;
}
return this;
},
/**
* Takes the given texture key and frame and then stamps it at the given
* x and y coordinates. You can use the optional 'config' argument to provide
* lots more options about how the stamp is applied, including the alpha,
* tint, angle, scale and origin.
*
* By default, the frame will stamp on the x/y coordinates based on its center.
*
* If you wish to stamp from the top-left, set the config `originX` and
* `originY` properties both to zero.
*
* @method Phaser.Textures.DynamicTexture#stamp
* @since 3.60.0
*
* @param {string} key - The key of the texture to be used, as stored in the Texture Manager.
* @param {(string|number)} [frame] - The name or index of the frame within the Texture. Set to `null` to skip this argument if not required.
* @param {number} [x=0] - The x position to draw the frame at.
* @param {number} [y=0] - The y position to draw the frame at.
* @param {Phaser.Types.Textures.StampConfig} [config] - The stamp configuration object, allowing you to set the alpha, tint, angle, scale and origin of the stamp.
*
* @return {this} This Dynamic Texture instance.
*/
stamp: function(key, frame, x, y, config) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
var alpha = GetFastValue(config, "alpha", 1);
var tint = GetFastValue(config, "tint", 16777215);
var angle = GetFastValue(config, "angle", 0);
var rotation = GetFastValue(config, "rotation", 0);
var scale = GetFastValue(config, "scale", 1);
var scaleX = GetFastValue(config, "scaleX", scale);
var scaleY = GetFastValue(config, "scaleY", scale);
var originX = GetFastValue(config, "originX", 0.5);
var originY = GetFastValue(config, "originY", 0.5);
var blendMode = GetFastValue(config, "blendMode", 0);
var erase = GetFastValue(config, "erase", false);
var skipBatch = GetFastValue(config, "skipBatch", false);
var stamp = this.manager.resetStamp(alpha, tint);
stamp.setAngle(0);
if (angle !== 0) {
stamp.setAngle(angle);
} else if (rotation !== 0) {
stamp.setRotation(rotation);
}
stamp.setScale(scaleX, scaleY);
stamp.setTexture(key, frame);
stamp.setOrigin(originX, originY);
stamp.setBlendMode(blendMode);
if (erase) {
this._eraseMode = true;
}
if (!skipBatch) {
this.draw(stamp, x, y);
} else {
this.batchGameObject(stamp, x, y);
}
if (erase) {
this._eraseMode = false;
}
return this;
},
/**
* Draws the given object, or an array of objects, to this Dynamic Texture using a blend mode of ERASE.
* This has the effect of erasing any filled pixels present in the objects from this texture.
*
* It can accept any of the following:
*
* * Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite.
* * Tilemap Layers.
* * A Group. The contents of which will be iterated and drawn in turn.
* * A Container. The contents of which will be iterated fully, and drawn in turn.
* * A Scene Display List. Pass in `Scene.children` to draw the whole list.
* * Another Dynamic Texture, or a Render Texture.
* * A Texture Frame instance.
* * A string. This is used to look-up the texture from the Texture Manager.
*
* Note: You cannot erase a Dynamic Texture from itself.
*
* If passing in a Group or Container it will only draw children that return `true`
* when their `willRender()` method is called. I.e. a Container with 10 children,
* 5 of which have `visible=false` will only draw the 5 visible ones.
*
* If passing in an array of Game Objects it will draw them all, regardless if
* they pass a `willRender` check or not.
*
* You can pass in a string in which case it will look for a texture in the Texture
* Manager matching that string, and draw the base frame.
*
* You can pass in the `x` and `y` coordinates to draw the objects at. The use of
* the coordinates differ based on what objects are being drawn. If the object is
* a Group, Container or Display List, the coordinates are _added_ to the positions
* of the children. For all other types of object, the coordinates are exact.
*
* Calling this method causes the WebGL batch to flush, so it can write the texture
* data to the framebuffer being used internally. The batch is flushed at the end,
* after the entries have been iterated. So if you've a bunch of objects to draw,
* try and pass them in an array in one single call, rather than making lots of
* separate calls.
*
* If you are not planning on using this Dynamic Texture as a base texture for Sprite
* Game Objects, then you should set `DynamicTexture.isSpriteTexture = false` before
* calling this method, otherwise you will get vertically inverted frames in WebGL.
*
* @method Phaser.Textures.DynamicTexture#erase
* @since 3.16.0
*
* @param {any} entries - Any renderable Game Object, or Group, Container, Display List, Render Texture, Texture Frame, or an array of any of these.
* @param {number} [x=0] - The x position to draw the Frame at, or the offset applied to the object.
* @param {number} [y=0] - The y position to draw the Frame at, or the offset applied to the object.
*
* @return {this} This Dynamic Texture instance.
*/
erase: function(entries, x, y) {
this._eraseMode = true;
this.draw(entries, x, y);
this._eraseMode = false;
return this;
},
/**
* Draws the given object, or an array of objects, to this Dynamic Texture.
*
* It can accept any of the following:
*
* * Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite.
* * Tilemap Layers.
* * A Group. The contents of which will be iterated and drawn in turn.
* * A Container. The contents of which will be iterated fully, and drawn in turn.
* * A Scene Display List. Pass in `Scene.children` to draw the whole list.
* * Another Dynamic Texture, or a Render Texture.
* * A Texture Frame instance.
* * A string. This is used to look-up the texture from the Texture Manager.
*
* Note 1: You cannot draw a Dynamic Texture to itself.
*
* Note 2: For Game Objects that have Post FX Pipelines, the pipeline _cannot_ be
* used when drawn to this texture.
*
* If passing in a Group or Container it will only draw children that return `true`
* when their `willRender()` method is called. I.e. a Container with 10 children,
* 5 of which have `visible=false` will only draw the 5 visible ones.
*
* If passing in an array of Game Objects it will draw them all, regardless if
* they pass a `willRender` check or not.
*
* You can pass in a string in which case it will look for a texture in the Texture
* Manager matching that string, and draw the base frame. If you need to specify
* exactly which frame to draw then use the method `drawFrame` instead.
*
* You can pass in the `x` and `y` coordinates to draw the objects at. The use of
* the coordinates differ based on what objects are being drawn. If the object is
* a Group, Container or Display List, the coordinates are _added_ to the positions
* of the children. For all other types of object, the coordinates are exact.
*
* The `alpha` and `tint` values are only used by Texture Frames.
* Game Objects use their own alpha and tint values when being drawn.
*
* Calling this method causes the WebGL batch to flush, so it can write the texture
* data to the framebuffer being used internally. The batch is flushed at the end,
* after the entries have been iterated. So if you've a bunch of objects to draw,
* try and pass them in an array in one single call, rather than making lots of
* separate calls.
*
* If you are not planning on using this Dynamic Texture as a base texture for Sprite
* Game Objects, then you should set `DynamicTexture.isSpriteTexture = false` before
* calling this method, otherwise you will get vertically inverted frames in WebGL.
*
* @method Phaser.Textures.DynamicTexture#draw
* @since 3.2.0
*
* @param {any} entries - Any renderable Game Object, or Group, Container, Display List, other Render Texture, Texture Frame or an array of any of these.
* @param {number} [x=0] - The x position to draw the Frame at, or the offset applied to the object.
* @param {number} [y=0] - The y position to draw the Frame at, or the offset applied to the object.
* @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha.
* @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only.
*
* @return {this} This Dynamic Texture instance.
*/
draw: function(entries, x, y, alpha, tint) {
this.beginDraw();
this.batchDraw(entries, x, y, alpha, tint);
this.endDraw();
return this;
},
/**
* Draws the Texture Frame to the Render Texture at the given position.
*
* Textures are referenced by their string-based keys, as stored in the Texture Manager.
*
* ```javascript
* var rt = this.add.renderTexture(0, 0, 800, 600);
* rt.drawFrame(key, frame);
* ```
*
* You can optionally provide a position, alpha and tint value to apply to the frame
* before it is drawn.
*
* Calling this method will cause a batch flush, so if you've got a stack of things to draw
* in a tight loop, try using the `draw` method instead.
*
* If you need to draw a Sprite to this Render Texture, use the `draw` method instead.
*
* If you are not planning on using this Dynamic Texture as a base texture for Sprite
* Game Objects, then you should set `DynamicTexture.isSpriteTexture = false` before
* calling this method, otherwise you will get vertically inverted frames in WebGL.
*
* @method Phaser.Textures.DynamicTexture#drawFrame
* @since 3.12.0
*
* @param {string} key - The key of the texture to be used, as stored in the Texture Manager.
* @param {(string|number)} [frame] - The name or index of the frame within the Texture. Set to `null` to skip this argument if not required.
* @param {number} [x=0] - The x position to draw the frame at.
* @param {number} [y=0] - The y position to draw the frame at.
* @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture.
* @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. WebGL only.
*
* @return {this} This Dynamic Texture instance.
*/
drawFrame: function(key, frame, x, y, alpha, tint) {
this.beginDraw();
this.batchDrawFrame(key, frame, x, y, alpha, tint);
this.endDraw();
return this;
},
/**
* Takes the given Texture Frame and draws it to this Dynamic Texture as a fill pattern,
* i.e. in a grid-layout based on the frame dimensions.
*
* Textures are referenced by their string-based keys, as stored in the Texture Manager.
*
* You can optionally provide a position, width, height, alpha and tint value to apply to
* the frames before they are drawn. The position controls the top-left where the repeating
* fill will start from. The width and height control the size of the filled area.
*
* The position can be negative if required, but the dimensions cannot.
*
* Calling this method will cause a batch flush by default. Use the `skipBatch` argument
* to disable this if this call is part of a larger batch draw.
*
* If you are not planning on using this Dynamic Texture as a base texture for Sprite
* Game Objects, then you should set `DynamicTexture.isSpriteTexture = false` before
* calling this method, otherwise you will get vertically inverted frames in WebGL.
*
* @method Phaser.Textures.DynamicTexture#repeat
* @since 3.60.0
*
* @param {string} key - The key of the texture to be used, as stored in the Texture Manager.
* @param {(string|number)} [frame] - The name or index of the frame within the Texture. Set to `null` to skip this argument if not required.
* @param {number} [x=0] - The x position to start drawing the frames from (can be negative to offset).
* @param {number} [y=0] - The y position to start drawing the frames from (can be negative to offset).
* @param {number} [width=this.width] - The width of the area to repeat the frame within. Defaults to the width of this Dynamic Texture.
* @param {number} [height=this.height] - The height of the area to repeat the frame within. Defaults to the height of this Dynamic Texture.
* @param {number} [alpha=1] - The alpha to use. Defaults to 1, no alpha.
* @param {number} [tint=0xffffff] - WebGL only. The tint color to use. Leave as undefined, or 0xffffff to have no tint.
* @param {boolean} [skipBatch=false] - Skip beginning and ending a batch with this call. Use if this is part of a bigger batched draw.
*
* @return {this} This Dynamic Texture instance.
*/
repeat: function(key, frame, x, y, width, height, alpha, tint, skipBatch) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (width === void 0) {
width = this.width;
}
if (height === void 0) {
height = this.height;
}
if (alpha === void 0) {
alpha = 1;
}
if (tint === void 0) {
tint = 16777215;
}
if (skipBatch === void 0) {
skipBatch = false;
}
if (key instanceof Frame) {
frame = key;
} else {
frame = this.manager.getFrame(key, frame);
}
if (!frame) {
return this;
}
var stamp = this.manager.resetStamp(alpha, tint);
stamp.setFrame(frame);
stamp.setOrigin(0);
var frameWidth = frame.width;
var frameHeight = frame.height;
width = Math.floor(width);
height = Math.floor(height);
var hmax = Math.ceil(width / frameWidth);
var vmax = Math.ceil(height / frameHeight);
var hdiff = hmax * frameWidth - width;
var vdiff = vmax * frameHeight - height;
if (hdiff > 0) {
hdiff = frameWidth - hdiff;
}
if (vdiff > 0) {
vdiff = frameHeight - vdiff;
}
if (x < 0) {
hmax += Math.ceil(Math.abs(x) / frameWidth);
}
if (y < 0) {
vmax += Math.ceil(Math.abs(y) / frameHeight);
}
var dx = x;
var dy = y;
var useCrop = false;
var cropRect = this.manager.stampCrop.setTo(0, 0, frameWidth, frameHeight);
if (!skipBatch) {
this.beginDraw();
}
for (var ty = 0; ty < vmax; ty++) {
if (dy + frameHeight < 0) {
dy += frameHeight;
continue;
}
for (var tx = 0; tx < hmax; tx++) {
useCrop = false;
if (dx + frameWidth < 0) {
dx += frameWidth;
continue;
} else if (dx < 0) {
useCrop = true;
cropRect.width = frameWidth + dx;
cropRect.x = frameWidth - cropRect.width;
}
if (dy < 0) {
useCrop = true;
cropRect.height = frameHeight + dy;
cropRect.y = frameHeight - cropRect.height;
}
if (hdiff > 0 && tx === hmax - 1) {
useCrop = true;
cropRect.width = hdiff;
}
if (vdiff > 0 && ty === vmax - 1) {
useCrop = true;
cropRect.height = vdiff;
}
if (useCrop) {
stamp.setCrop(cropRect);
}
this.batchGameObject(stamp, dx, dy);
stamp.isCropped = false;
cropRect.setTo(0, 0, frameWidth, frameHeight);
dx += frameWidth;
}
dx = x;
dy += frameHeight;
}
if (!skipBatch) {
this.endDraw();
}
return this;
},
/**
* Use this method if you need to batch draw a large number of Game Objects to
* this Dynamic Texture in a single pass, or on a frequent basis. This is especially
* useful under WebGL, however, if your game is using Canvas only, it will not make
* any speed difference in that situation.
*
* This method starts the beginning of a batched draw, unless one is already open.
*
* Batched drawing is faster than calling `draw` in loop, but you must be careful
* to manage the flow of code and remember to call `endDraw()` when you're finished.
*
* If you don't need to draw large numbers of objects it's much safer and easier
* to use the `draw` method instead.
*
* The flow should be:
*
* ```javascript
* // Call once:
* DynamicTexture.beginDraw();
*
* // repeat n times:
* DynamicTexture.batchDraw();
* // or
* DynamicTexture.batchDrawFrame();
*
* // Call once:
* DynamicTexture.endDraw();
* ```
*
* Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you
* have started a batch. Also, be very careful not to destroy this Dynamic Texture while the
* batch is still open. Doing so will cause a run-time error in the WebGL Renderer.
*
* You can use the `DynamicTexture.isDrawing` boolean property to tell if a batch is
* currently open, or not.
*
* @method Phaser.Textures.DynamicTexture#beginDraw
* @since 3.50.0
*
* @return {this} This Dynamic Texture instance.
*/
beginDraw: function() {
if (!this.isDrawing) {
var camera = this.camera;
var renderer = this.renderer;
var renderTarget = this.renderTarget;
camera.preRender();
if (renderTarget) {
renderer.beginCapture(renderTarget.width, renderTarget.height);
} else {
renderer.setContext(this.context);
}
this.isDrawing = true;
}
return this;
},
/**
* Use this method if you have already called `beginDraw` and need to batch
* draw a large number of objects to this Dynamic Texture.
*
* This method batches the drawing of the given objects to this texture,
* without causing a WebGL bind or batch flush for each one.
*
* It is faster than calling `draw`, but you must be careful to manage the
* flow of code and remember to call `endDraw()`. If you don't need to draw large
* numbers of objects it's much safer and easier to use the `draw` method instead.
*
* The flow should be:
*
* ```javascript
* // Call once:
* DynamicTexture.beginDraw();
*
* // repeat n times:
* DynamicTexture.batchDraw();
* // or
* DynamicTexture.batchDrawFrame();
*
* // Call once:
* DynamicTexture.endDraw();
* ```
*
* Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you
* have started a batch. Also, be very careful not to destroy this Dynamic Texture while the
* batch is still open. Doing so will cause a run-time error in the WebGL Renderer.
*
* You can use the `DynamicTexture.isDrawing` boolean property to tell if a batch is
* currently open, or not.
*
* This method can accept any of the following:
*
* * Any renderable Game Object, such as a Sprite, Text, Graphics or TileSprite.
* * Tilemap Layers.
* * A Group. The contents of which will be iterated and drawn in turn.
* * A Container. The contents of which will be iterated fully, and drawn in turn.
* * A Scene's Display List. Pass in `Scene.children` to draw the whole list.
* * Another Dynamic Texture or Render Texture.
* * A Texture Frame instance.
* * A string. This is used to look-up a texture from the Texture Manager.
*
* Note: You cannot draw a Dynamic Texture to itself.
*
* If passing in a Group or Container it will only draw children that return `true`
* when their `willRender()` method is called. I.e. a Container with 10 children,
* 5 of which have `visible=false` will only draw the 5 visible ones.
*
* If passing in an array of Game Objects it will draw them all, regardless if
* they pass a `willRender` check or not.
*
* You can pass in a string in which case it will look for a texture in the Texture
* Manager matching that string, and draw the base frame. If you need to specify
* exactly which frame to draw then use the method `drawFrame` instead.
*
* You can pass in the `x` and `y` coordinates to draw the objects at. The use of
* the coordinates differ based on what objects are being drawn. If the object is
* a Group, Container or Display List, the coordinates are _added_ to the positions
* of the children. For all other types of object, the coordinates are exact.
*
* The `alpha` and `tint` values are only used by Texture Frames.
* Game Objects use their own alpha and tint values when being drawn.
*
* @method Phaser.Textures.DynamicTexture#batchDraw
* @since 3.50.0
*
* @param {any} entries - Any renderable Game Object, or Group, Container, Display List, other Dynamic or Texture, Texture Frame or an array of any of these.
* @param {number} [x=0] - The x position to draw the Frame at, or the offset applied to the object.
* @param {number} [y=0] - The y position to draw the Frame at, or the offset applied to the object.
* @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha.
* @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only.
*
* @return {this} This Dynamic Texture instance.
*/
batchDraw: function(entries, x, y, alpha, tint) {
if (!Array.isArray(entries)) {
entries = [entries];
}
this.batchList(entries, x, y, alpha, tint);
return this;
},
/**
* Use this method if you have already called `beginDraw` and need to batch
* draw a large number of texture frames to this Dynamic Texture.
*
* This method batches the drawing of the given frames to this Dynamic Texture,
* without causing a WebGL bind or batch flush for each one.
*
* It is faster than calling `drawFrame`, but you must be careful to manage the
* flow of code and remember to call `endDraw()`. If you don't need to draw large
* numbers of frames it's much safer and easier to use the `drawFrame` method instead.
*
* The flow should be:
*
* ```javascript
* // Call once:
* DynamicTexture.beginDraw();
*
* // repeat n times:
* DynamicTexture.batchDraw();
* // or
* DynamicTexture.batchDrawFrame();
*
* // Call once:
* DynamicTexture.endDraw();
* ```
*
* Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you
* have started a batch. Also, be very careful not to destroy this Dynamic Texture while the
* batch is still open. Doing so will cause a run-time error in the WebGL Renderer.
*
* You can use the `DynamicTexture.isDrawing` boolean property to tell if a batch is
* currently open, or not.
*
* Textures are referenced by their string-based keys, as stored in the Texture Manager.
*
* You can optionally provide a position, alpha and tint value to apply to the frame
* before it is drawn.
*
* @method Phaser.Textures.DynamicTexture#batchDrawFrame
* @since 3.50.0
*
* @param {string} key - The key of the texture to be used, as stored in the Texture Manager.
* @param {(string|number)} [frame] - The name or index of the frame within the Texture.
* @param {number} [x=0] - The x position to draw the frame at.
* @param {number} [y=0] - The y position to draw the frame at.
* @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha.
* @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only.
*
* @return {this} This Dynamic Texture instance.
*/
batchDrawFrame: function(key, frame, x, y, alpha, tint) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (alpha === void 0) {
alpha = 1;
}
if (tint === void 0) {
tint = 16777215;
}
var textureFrame = this.manager.getFrame(key, frame);
if (textureFrame) {
if (this.renderTarget) {
this.pipeline.batchTextureFrame(textureFrame, x, y, tint, alpha, this.camera.matrix, null);
} else {
this.batchTextureFrame(textureFrame, x, y, alpha, tint);
}
}
return this;
},
/**
* Use this method to finish batch drawing to this Dynamic Texture.
*
* Doing so will stop the WebGL Renderer from capturing draws and then blit the
* framebuffer to the Render Target owned by this texture.
*
* Calling this method without first calling `beginDraw` will have no effect.
*
* Batch drawing is faster than calling `draw`, but you must be careful to manage the
* flow of code and remember to call `endDraw()` when you're finished.
*
* If you don't need to draw large numbers of objects it's much safer and easier
* to use the `draw` method instead.
*
* The flow should be:
*
* ```javascript
* // Call once:
* DynamicTexture.beginDraw();
*
* // repeat n times:
* DynamicTexture.batchDraw();
* // or
* DynamicTexture.batchDrawFrame();
*
* // Call once:
* DynamicTexture.endDraw();
* ```
*
* Do not call any methods other than `batchDraw`, `batchDrawFrame`, or `endDraw` once you
* have started a batch. Also, be very careful not to destroy this Dynamic Texture while the
* batch is still open. Doing so will cause a run-time error in the WebGL Renderer.
*
* You can use the `DynamicTexture.isDrawing` boolean property to tell if a batch is
* currently open, or not.
*
* @method Phaser.Textures.DynamicTexture#endDraw
* @since 3.50.0
*
* @param {boolean} [erase=false] - Draws all objects in this batch using a blend mode of ERASE. This has the effect of erasing any filled pixels in the objects being drawn.
*
* @return {this} This Dynamic Texture instance.
*/
endDraw: function(erase) {
if (erase === void 0) {
erase = this._eraseMode;
}
if (this.isDrawing) {
var renderer = this.renderer;
var renderTarget = this.renderTarget;
if (renderTarget) {
var canvasTarget = renderer.endCapture();
var util = renderer.pipelines.setUtility();
util.blitFrame(canvasTarget, renderTarget, 1, false, false, erase, this.isSpriteTexture);
renderer.resetScissor();
renderer.resetViewport();
} else {
renderer.setContext();
}
this.dirty = true;
this.isDrawing = false;
}
return this;
},
/**
* Internal method that handles the drawing of an array of children.
*
* @method Phaser.Textures.DynamicTexture#batchList
* @private
* @since 3.12.0
*
* @param {array} children - The array of Game Objects, Textures or Frames to draw.
* @param {number} [x=0] - The x position to offset the Game Object by.
* @param {number} [y=0] - The y position to offset the Game Object by.
* @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha.
* @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only.
*/
batchList: function(children, x, y, alpha, tint) {
var len = children.length;
if (len === 0) {
return;
}
for (var i = 0; i < len; i++) {
var entry = children[i];
if (!entry || entry === this) {
continue;
}
if (entry.renderWebGL || entry.renderCanvas) {
this.batchGameObject(entry, x, y);
} else if (entry.isParent || entry.list) {
this.batchGroup(entry.getChildren(), x, y);
} else if (typeof entry === "string") {
this.batchTextureFrameKey(entry, null, x, y, alpha, tint);
} else if (entry instanceof Frame) {
this.batchTextureFrame(entry, x, y, alpha, tint);
} else if (Array.isArray(entry)) {
this.batchList(entry, x, y, alpha, tint);
}
}
},
/**
* Internal method that handles drawing the contents of a Phaser Group to this Dynamic Texture.
*
* @method Phaser.Textures.DynamicTexture#batchGroup
* @private
* @since 3.12.0
*
* @param {array} children - The array of Game Objects to draw.
* @param {number} [x=0] - The x position to offset the Game Objects by.
* @param {number} [y=0] - The y position to offset the Game Objects by.
*/
batchGroup: function(children, x, y) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
for (var i = 0; i < children.length; i++) {
var entry = children[i];
if (entry.willRender(this.camera)) {
this.batchGameObject(entry, entry.x + x, entry.y + y);
}
}
},
/**
* Internal method that handles drawing a single Phaser Game Object to this Dynamic Texture.
*
* @method Phaser.Textures.DynamicTexture#batchGameObject
* @private
* @since 3.12.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to draw.
* @param {number} [x=0] - The x position to draw the Game Object at.
* @param {number} [y=0] - The y position to draw the Game Object at.
*/
batchGameObject: function(gameObject, x, y) {
if (x === void 0) {
x = gameObject.x;
}
if (y === void 0) {
y = gameObject.y;
}
var prevX = gameObject.x;
var prevY = gameObject.y;
var camera = this.camera;
var renderer = this.renderer;
var eraseMode = this._eraseMode;
var mask = gameObject.mask;
gameObject.setPosition(x, y);
if (this.canvas) {
if (eraseMode) {
var blendMode = gameObject.blendMode;
gameObject.blendMode = BlendModes.ERASE;
}
if (mask) {
mask.preRenderCanvas(renderer, gameObject, camera);
}
gameObject.renderCanvas(renderer, gameObject, camera, null);
if (mask) {
mask.postRenderCanvas(renderer, gameObject, camera);
}
if (eraseMode) {
gameObject.blendMode = blendMode;
}
} else if (renderer) {
if (mask) {
mask.preRenderWebGL(renderer, gameObject, camera);
}
if (!eraseMode) {
renderer.setBlendMode(gameObject.blendMode);
}
gameObject.renderWebGL(renderer, gameObject, camera);
if (mask) {
mask.postRenderWebGL(renderer, camera, this.renderTarget);
}
}
gameObject.setPosition(prevX, prevY);
},
/**
* Internal method that handles the drawing a Texture Frame based on its key.
*
* @method Phaser.Textures.DynamicTexture#batchTextureFrameKey
* @private
* @since 3.12.0
*
* @param {string} key - The key of the texture to be used, as stored in the Texture Manager.
* @param {(string|number)} [frame] - The name or index of the frame within the Texture.
* @param {number} [x=0] - The x position to offset the Game Object by.
* @param {number} [y=0] - The y position to offset the Game Object by.
* @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha.
* @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only.
*/
batchTextureFrameKey: function(key, frame, x, y, alpha, tint) {
var textureFrame = this.manager.getFrame(key, frame);
if (textureFrame) {
this.batchTextureFrame(textureFrame, x, y, alpha, tint);
}
},
/**
* Internal method that handles the drawing of a Texture Frame to this Dynamic Texture.
*
* @method Phaser.Textures.DynamicTexture#batchTextureFrame
* @private
* @since 3.12.0
*
* @param {Phaser.Textures.Frame} textureFrame - The Texture Frame to draw.
* @param {number} [x=0] - The x position to draw the Frame at.
* @param {number} [y=0] - The y position to draw the Frame at.
* @param {number} [alpha=1] - The alpha value. Only used when drawing Texture Frames to this texture. Game Objects use their own alpha.
* @param {number} [tint=0xffffff] - The tint color value. Only used when drawing Texture Frames to this texture. Game Objects use their own tint. WebGL only.
*/
batchTextureFrame: function(textureFrame, x, y, alpha, tint) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (alpha === void 0) {
alpha = 1;
}
if (tint === void 0) {
tint = 16777215;
}
var matrix = this.camera.matrix;
var renderTarget = this.renderTarget;
if (renderTarget) {
this.pipeline.batchTextureFrame(textureFrame, x, y, tint, alpha, matrix, null);
} else {
var ctx = this.context;
var cd = textureFrame.canvasData;
var source = textureFrame.source.image;
ctx.save();
ctx.globalCompositeOperation = this._eraseMode ? "destination-out" : "source-over";
ctx.globalAlpha = alpha;
matrix.setToContext(ctx);
if (cd.width > 0 && cd.height > 0) {
ctx.drawImage(source, cd.x, cd.y, cd.width, cd.height, x, y, cd.width, cd.height);
}
ctx.restore();
}
},
/**
* Takes a snapshot of the given area of this Dynamic Texture.
*
* The snapshot is taken immediately, but the results are returned via the given callback.
*
* To capture the whole Dynamic Texture see the `snapshot` method.
* To capture just a specific pixel, see the `snapshotPixel` method.
*
* Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer
* into an ArrayBufferView. It then parses this, copying the contents to a temporary Canvas and finally
* creating an Image object from it, which is the image returned to the callback provided.
*
* All in all, this is a computationally expensive and blocking process, which gets more expensive
* the larger the resolution this Dynamic Texture has, so please be careful how you employ this in your game.
*
* @method Phaser.Textures.DynamicTexture#snapshotArea
* @since 3.19.0
*
* @param {number} x - The x coordinate to grab from.
* @param {number} y - The y coordinate to grab from.
* @param {number} width - The width of the area to grab.
* @param {number} height - The height of the area to grab.
* @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created.
* @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`.
* @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`.
*
* @return {this} This Dynamic Texture instance.
*/
snapshotArea: function(x, y, width, height, callback, type, encoderOptions) {
if (this.renderTarget) {
this.renderer.snapshotFramebuffer(this.renderTarget.framebuffer, this.width, this.height, callback, false, x, y, width, height, type, encoderOptions);
} else {
this.renderer.snapshotCanvas(this.canvas, callback, false, x, y, width, height, type, encoderOptions);
}
return this;
},
/**
* Takes a snapshot of the whole of this Dynamic Texture.
*
* The snapshot is taken immediately, but the results are returned via the given callback.
*
* To capture a portion of this Dynamic Texture see the `snapshotArea` method.
* To capture just a specific pixel, see the `snapshotPixel` method.
*
* Snapshots work by using the WebGL `readPixels` feature to grab every pixel from the frame buffer
* into an ArrayBufferView. It then parses this, copying the contents to a temporary Canvas and finally
* creating an Image object from it, which is the image returned to the callback provided.
*
* All in all, this is a computationally expensive and blocking process, which gets more expensive
* the larger the resolution this Dynamic Texture has, so please be careful how you employ this in your game.
*
* @method Phaser.Textures.DynamicTexture#snapshot
* @since 3.19.0
*
* @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot image is created.
* @param {string} [type='image/png'] - The format of the image to create, usually `image/png` or `image/jpeg`.
* @param {number} [encoderOptions=0.92] - The image quality, between 0 and 1. Used for image formats with lossy compression, such as `image/jpeg`.
*
* @return {this} This Dynamic Texture instance.
*/
snapshot: function(callback, type, encoderOptions) {
return this.snapshotArea(0, 0, this.width, this.height, callback, type, encoderOptions);
},
/**
* Takes a snapshot of the given pixel from this Dynamic Texture.
*
* The snapshot is taken immediately, but the results are returned via the given callback.
*
* To capture the whole Dynamic Texture see the `snapshot` method.
* To capture a portion of this Dynamic Texture see the `snapshotArea` method.
*
* Unlike the two other snapshot methods, this one will send your callback a `Color` object
* containing the color data for the requested pixel. It doesn't need to create an internal
* Canvas or Image object, so is a lot faster to execute, using less memory than the other snapshot methods.
*
* @method Phaser.Textures.DynamicTexture#snapshotPixel
* @since 3.19.0
*
* @param {number} x - The x coordinate of the pixel to get.
* @param {number} y - The y coordinate of the pixel to get.
* @param {Phaser.Types.Renderer.Snapshot.SnapshotCallback} callback - The Function to invoke after the snapshot pixel data is extracted.
*
* @return {this} This Dynamic Texture instance.
*/
snapshotPixel: function(x, y, callback) {
return this.snapshotArea(x, y, 1, 1, callback, "pixel");
},
/**
* Returns the underlying WebGLTextureWrapper, if not running in Canvas mode.
*
* @method Phaser.Textures.DynamicTexture#getWebGLTexture
* @since 3.60.0
*
* @return {?Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} The underlying WebGLTextureWrapper, if not running in Canvas mode.
*/
getWebGLTexture: function() {
if (this.renderTarget) {
return this.renderTarget.texture;
}
},
/**
* Renders this Dynamic Texture onto the Stamp Game Object as a BitmapMask.
*
* @method Phaser.Textures.DynamicTexture#renderWebGL
* @since 3.60.0
*
* @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active WebGL renderer.
* @param {Phaser.GameObjects.Image} src - The Game Object being rendered in this call.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
* @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
*/
renderWebGL: function(renderer, src, camera, parentMatrix) {
var stamp = this.manager.resetStamp();
stamp.setTexture(this);
stamp.setOrigin(0);
stamp.renderWebGL(renderer, stamp, camera, parentMatrix);
},
/**
* This is a NOOP method. Bitmap Masks are not supported by the Canvas Renderer.
*
* @method Phaser.Textures.DynamicTexture#renderCanvas
* @since 3.60.0
*
* @param {(Phaser.Renderer.Canvas.CanvasRenderer|Phaser.Renderer.WebGL.WebGLRenderer)} renderer - The Canvas Renderer which would be rendered to.
* @param {Phaser.GameObjects.GameObject} mask - The masked Game Object which would be rendered.
* @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera to render to.
*/
renderCanvas: function() {
},
/**
* Destroys this Texture and releases references to its sources and frames.
*
* @method Phaser.Textures.DynamicTexture#destroy
* @since 3.60.0
*/
destroy: function() {
var stamp = this.manager.stamp;
if (stamp && stamp.texture === this) {
this.manager.resetStamp();
}
Texture.prototype.destroy.call(this);
CanvasPool.remove(this.canvas);
if (this.renderTarget) {
this.renderTarget.destroy();
}
this.camera.destroy();
this.canvas = null;
this.context = null;
this.renderer = null;
}
});
module2.exports = DynamicTexture;
}
),
/***/
4327: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Clamp = __webpack_require__2(45319);
var Extend = __webpack_require__2(79291);
var Frame = new Class({
initialize: function Frame2(texture, name, sourceIndex, x, y, width, height) {
this.texture = texture;
this.name = name;
this.source = texture.source[sourceIndex];
this.sourceIndex = sourceIndex;
this.cutX;
this.cutY;
this.cutWidth;
this.cutHeight;
this.x = 0;
this.y = 0;
this.width;
this.height;
this.halfWidth;
this.halfHeight;
this.centerX;
this.centerY;
this.pivotX = 0;
this.pivotY = 0;
this.customPivot = false;
this.rotated = false;
this.autoRound = -1;
this.customData = {};
this.u0 = 0;
this.v0 = 0;
this.u1 = 0;
this.v1 = 0;
this.data = {
cut: {
x: 0,
y: 0,
w: 0,
h: 0,
r: 0,
b: 0
},
trim: false,
sourceSize: {
w: 0,
h: 0
},
spriteSourceSize: {
x: 0,
y: 0,
w: 0,
h: 0,
r: 0,
b: 0
},
radius: 0,
drawImage: {
x: 0,
y: 0,
width: 0,
height: 0
},
is3Slice: false,
scale9: false,
scale9Borders: {
x: 0,
y: 0,
w: 0,
h: 0
}
};
this.setSize(width, height, x, y);
},
/**
* Sets the x and y position within the source image to cut from.
*
* @method Phaser.Textures.Frame#setCutPosition
* @since 3.85.0
*
* @param {number} [x=0] - X position within the source image to cut from.
* @param {number} [y=0] - Y position within the source image to cut from.
*
* @return {this} This Frame object.
*/
setCutPosition: function(x, y) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
this.cutX = x;
this.cutY = y;
return this.updateUVs();
},
/**
* Sets the width, and height of the area in the source image to cut.
*
* @method Phaser.Textures.Frame#setCutSize
* @since 3.85.0
*
* @param {number} width - The width of the area in the source image to cut.
* @param {number} height - The height of the area in the source image to cut.
*
* @return {this} This Frame object.
*/
setCutSize: function(width, height) {
this.cutWidth = width;
this.cutHeight = height;
return this.updateUVs();
},
/**
* Sets the width, height, x and y of this Frame.
*
* This is called automatically by the constructor
* and should rarely be changed on-the-fly.
*
* @method Phaser.Textures.Frame#setSize
* @since 3.7.0
*
* @param {number} width - The width of the frame before being trimmed.
* @param {number} height - The height of the frame before being trimmed.
* @param {number} [x=0] - The x coordinate of the top-left of this Frame.
* @param {number} [y=0] - The y coordinate of the top-left of this Frame.
*
* @return {this} This Frame object.
*/
setSize: function(width, height, x, y) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
this.setCutPosition(x, y);
this.setCutSize(width, height);
this.width = width;
this.height = height;
this.halfWidth = Math.floor(width * 0.5);
this.halfHeight = Math.floor(height * 0.5);
this.centerX = Math.floor(width / 2);
this.centerY = Math.floor(height / 2);
var data = this.data;
var cut = data.cut;
cut.x = x;
cut.y = y;
cut.w = width;
cut.h = height;
cut.r = x + width;
cut.b = y + height;
data.sourceSize.w = width;
data.sourceSize.h = height;
data.spriteSourceSize.w = width;
data.spriteSourceSize.h = height;
data.radius = 0.5 * Math.sqrt(width * width + height * height);
var drawImage = data.drawImage;
drawImage.x = x;
drawImage.y = y;
drawImage.width = width;
drawImage.height = height;
return this.updateUVs();
},
/**
* If the frame was trimmed when added to the Texture Atlas, this records the trim and source data.
*
* @method Phaser.Textures.Frame#setTrim
* @since 3.0.0
*
* @param {number} actualWidth - The width of the frame before being trimmed.
* @param {number} actualHeight - The height of the frame before being trimmed.
* @param {number} destX - The destination X position of the trimmed frame for display.
* @param {number} destY - The destination Y position of the trimmed frame for display.
* @param {number} destWidth - The destination width of the trimmed frame for display.
* @param {number} destHeight - The destination height of the trimmed frame for display.
*
* @return {this} This Frame object.
*/
setTrim: function(actualWidth, actualHeight, destX, destY, destWidth, destHeight) {
var data = this.data;
var ss = data.spriteSourceSize;
data.trim = true;
data.sourceSize.w = actualWidth;
data.sourceSize.h = actualHeight;
ss.x = destX;
ss.y = destY;
ss.w = destWidth;
ss.h = destHeight;
ss.r = destX + destWidth;
ss.b = destY + destHeight;
this.x = destX;
this.y = destY;
this.width = destWidth;
this.height = destHeight;
this.halfWidth = destWidth * 0.5;
this.halfHeight = destHeight * 0.5;
this.centerX = Math.floor(destWidth / 2);
this.centerY = Math.floor(destHeight / 2);
return this.updateUVs();
},
/**
* Sets the scale9 center rectangle values.
*
* Scale9 is a feature of Texture Packer, allowing you to define a nine-slice scaling grid.
*
* This is set automatically by the JSONArray and JSONHash parsers.
*
* @method Phaser.Textures.Frame#setScale9
* @since 3.70.0
*
* @param {number} x - The left coordinate of the center scale9 rectangle.
* @param {number} y - The top coordinate of the center scale9 rectangle.
* @param {number} width - The width of the center scale9 rectangle.
* @param {number} height - The height coordinate of the center scale9 rectangle.
*
* @return {this} This Frame object.
*/
setScale9: function(x, y, width, height) {
var data = this.data;
data.scale9 = true;
data.is3Slice = y === 0 && height === this.height;
data.scale9Borders.x = x;
data.scale9Borders.y = y;
data.scale9Borders.w = width;
data.scale9Borders.h = height;
return this;
},
/**
* Takes a crop data object and, based on the rectangular region given, calculates the
* required UV coordinates in order to crop this Frame for WebGL and Canvas rendering.
*
* The crop size as well as coordinates can not exceed the the size of the frame.
*
* This is called directly by the Game Object Texture Components `setCrop` method.
* Please use that method to crop a Game Object.
*
* @method Phaser.Textures.Frame#setCropUVs
* @since 3.11.0
*
* @param {object} crop - The crop data object. This is the `GameObject._crop` property.
* @param {number} x - The x coordinate to start the crop from. Cannot be negative or exceed the Frame width.
* @param {number} y - The y coordinate to start the crop from. Cannot be negative or exceed the Frame height.
* @param {number} width - The width of the crop rectangle. Cannot exceed the Frame width.
* @param {number} height - The height of the crop rectangle. Cannot exceed the Frame height.
* @param {boolean} flipX - Does the parent Game Object have flipX set?
* @param {boolean} flipY - Does the parent Game Object have flipY set?
*
* @return {object} The updated crop data object.
*/
setCropUVs: function(crop, x, y, width, height, flipX, flipY) {
var cx = this.cutX;
var cy = this.cutY;
var cw = this.cutWidth;
var ch = this.cutHeight;
var rw = this.realWidth;
var rh = this.realHeight;
x = Clamp(x, 0, rw);
y = Clamp(y, 0, rh);
width = Clamp(width, 0, rw - x);
height = Clamp(height, 0, rh - y);
var ox = cx + x;
var oy = cy + y;
var ow = width;
var oh = height;
var data = this.data;
if (data.trim) {
var ss = data.spriteSourceSize;
width = Clamp(width, 0, cw - x);
height = Clamp(height, 0, ch - y);
var cropRight = x + width;
var cropBottom = y + height;
var intersects = !(ss.r < x || ss.b < y || ss.x > cropRight || ss.y > cropBottom);
if (intersects) {
var ix = Math.max(ss.x, x);
var iy = Math.max(ss.y, y);
var iw = Math.min(ss.r, cropRight) - ix;
var ih = Math.min(ss.b, cropBottom) - iy;
ow = iw;
oh = ih;
if (flipX) {
ox = cx + (cw - (ix - ss.x) - iw);
} else {
ox = cx + (ix - ss.x);
}
if (flipY) {
oy = cy + (ch - (iy - ss.y) - ih);
} else {
oy = cy + (iy - ss.y);
}
x = ix;
y = iy;
width = iw;
height = ih;
} else {
ox = 0;
oy = 0;
ow = 0;
oh = 0;
}
} else {
if (flipX) {
ox = cx + (cw - x - width);
}
if (flipY) {
oy = cy + (ch - y - height);
}
}
var tw = this.source.width;
var th = this.source.height;
crop.u0 = Math.max(0, ox / tw);
crop.v0 = Math.max(0, oy / th);
crop.u1 = Math.min(1, (ox + ow) / tw);
crop.v1 = Math.min(1, (oy + oh) / th);
crop.x = x;
crop.y = y;
crop.cx = ox;
crop.cy = oy;
crop.cw = ow;
crop.ch = oh;
crop.width = width;
crop.height = height;
crop.flipX = flipX;
crop.flipY = flipY;
return crop;
},
/**
* Takes a crop data object and recalculates the UVs based on the dimensions inside the crop object.
* Called automatically by `setFrame`.
*
* @method Phaser.Textures.Frame#updateCropUVs
* @since 3.11.0
*
* @param {object} crop - The crop data object. This is the `GameObject._crop` property.
* @param {boolean} flipX - Does the parent Game Object have flipX set?
* @param {boolean} flipY - Does the parent Game Object have flipY set?
*
* @return {object} The updated crop data object.
*/
updateCropUVs: function(crop, flipX, flipY) {
return this.setCropUVs(crop, crop.x, crop.y, crop.width, crop.height, flipX, flipY);
},
/**
* Directly sets the canvas and WebGL UV data for this frame.
*
* Use this if you need to override the values that are generated automatically
* when the Frame is created.
*
* @method Phaser.Textures.Frame#setUVs
* @since 3.50.0
*
* @param {number} width - Width of this frame for the Canvas data.
* @param {number} height - Height of this frame for the Canvas data.
* @param {number} u0 - UV u0 value.
* @param {number} v0 - UV v0 value.
* @param {number} u1 - UV u1 value.
* @param {number} v1 - UV v1 value.
*
* @return {this} This Frame object.
*/
setUVs: function(width, height, u0, v0, u1, v1) {
var cd = this.data.drawImage;
cd.width = width;
cd.height = height;
this.u0 = u0;
this.v0 = v0;
this.u1 = u1;
this.v1 = v1;
return this;
},
/**
* Updates the internal WebGL UV cache and the drawImage cache.
*
* @method Phaser.Textures.Frame#updateUVs
* @since 3.0.0
*
* @return {this} This Frame object.
*/
updateUVs: function() {
var cx = this.cutX;
var cy = this.cutY;
var cw = this.cutWidth;
var ch = this.cutHeight;
var cd = this.data.drawImage;
cd.width = cw;
cd.height = ch;
var tw = this.source.width;
var th = this.source.height;
this.u0 = cx / tw;
this.v0 = cy / th;
this.u1 = (cx + cw) / tw;
this.v1 = (cy + ch) / th;
return this;
},
/**
* Updates the internal WebGL UV cache.
*
* @method Phaser.Textures.Frame#updateUVsInverted
* @since 3.0.0
*
* @return {this} This Frame object.
*/
updateUVsInverted: function() {
var tw = this.source.width;
var th = this.source.height;
this.u0 = (this.cutX + this.cutHeight) / tw;
this.v0 = this.cutY / th;
this.u1 = this.cutX / tw;
this.v1 = (this.cutY + this.cutWidth) / th;
return this;
},
/**
* Clones this Frame into a new Frame object.
*
* @method Phaser.Textures.Frame#clone
* @since 3.0.0
*
* @return {Phaser.Textures.Frame} A clone of this Frame.
*/
clone: function() {
var clone = new Frame(this.texture, this.name, this.sourceIndex);
clone.cutX = this.cutX;
clone.cutY = this.cutY;
clone.cutWidth = this.cutWidth;
clone.cutHeight = this.cutHeight;
clone.x = this.x;
clone.y = this.y;
clone.width = this.width;
clone.height = this.height;
clone.halfWidth = this.halfWidth;
clone.halfHeight = this.halfHeight;
clone.centerX = this.centerX;
clone.centerY = this.centerY;
clone.rotated = this.rotated;
clone.data = Extend(true, clone.data, this.data);
clone.updateUVs();
return clone;
},
/**
* Destroys this Frame by nulling its reference to the parent Texture and and data objects.
*
* @method Phaser.Textures.Frame#destroy
* @since 3.0.0
*/
destroy: function() {
this.texture = null;
this.source = null;
this.customData = null;
this.data = null;
},
/**
* A reference to the Texture Source WebGL Texture that this Frame is using.
*
* @name Phaser.Textures.Frame#glTexture
* @type {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper}
* @readonly
* @since 3.11.0
*/
glTexture: {
get: function() {
return this.source.glTexture;
}
},
/**
* The width of the Frame in its un-trimmed, un-padded state, as prepared in the art package,
* before being packed.
*
* @name Phaser.Textures.Frame#realWidth
* @type {number}
* @readonly
* @since 3.0.0
*/
realWidth: {
get: function() {
return this.data.sourceSize.w;
}
},
/**
* The height of the Frame in its un-trimmed, un-padded state, as prepared in the art package,
* before being packed.
*
* @name Phaser.Textures.Frame#realHeight
* @type {number}
* @readonly
* @since 3.0.0
*/
realHeight: {
get: function() {
return this.data.sourceSize.h;
}
},
/**
* The radius of the Frame (derived from sqrt(w * w + h * h) / 2)
*
* @name Phaser.Textures.Frame#radius
* @type {number}
* @readonly
* @since 3.0.0
*/
radius: {
get: function() {
return this.data.radius;
}
},
/**
* Is the Frame trimmed or not?
*
* @name Phaser.Textures.Frame#trimmed
* @type {boolean}
* @readonly
* @since 3.0.0
*/
trimmed: {
get: function() {
return this.data.trim;
}
},
/**
* Does the Frame have scale9 border data?
*
* @name Phaser.Textures.Frame#scale9
* @type {boolean}
* @readonly
* @since 3.70.0
*/
scale9: {
get: function() {
return this.data.scale9;
}
},
/**
* If the Frame has scale9 border data, is it 3-slice or 9-slice data?
*
* @name Phaser.Textures.Frame#is3Slice
* @type {boolean}
* @readonly
* @since 3.70.0
*/
is3Slice: {
get: function() {
return this.data.is3Slice;
}
},
/**
* The Canvas drawImage data object.
*
* @name Phaser.Textures.Frame#canvasData
* @type {object}
* @readonly
* @since 3.0.0
*/
canvasData: {
get: function() {
return this.data.drawImage;
}
}
});
module2.exports = Frame;
}
),
/***/
79237: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Frame = __webpack_require__2(4327);
var TextureSource = __webpack_require__2(11876);
var TEXTURE_MISSING_ERROR = 'Texture "%s" has no frame "%s"';
var Texture = new Class({
initialize: function Texture2(manager, key, source, width, height) {
if (!Array.isArray(source)) {
source = [source];
}
this.manager = manager;
this.key = key;
this.source = [];
this.dataSource = [];
this.frames = {};
this.customData = {};
this.firstFrame = "__BASE";
this.frameTotal = 0;
for (var i = 0; i < source.length; i++) {
this.source.push(new TextureSource(this, source[i], width, height));
}
},
/**
* Adds a new Frame to this Texture.
*
* A Frame is a rectangular region of a TextureSource with a unique index or string-based key.
*
* The name given must be unique within this Texture. If it already exists, this method will return `null`.
*
* @method Phaser.Textures.Texture#add
* @since 3.0.0
*
* @param {(number|string)} name - The name of this Frame. The name is unique within the Texture.
* @param {number} sourceIndex - The index of the TextureSource that this Frame is a part of.
* @param {number} x - The x coordinate of the top-left of this Frame.
* @param {number} y - The y coordinate of the top-left of this Frame.
* @param {number} width - The width of this Frame.
* @param {number} height - The height of this Frame.
*
* @return {?Phaser.Textures.Frame} The Frame that was added to this Texture, or `null` if the given name already exists.
*/
add: function(name, sourceIndex, x, y, width, height) {
if (this.has(name)) {
return null;
}
var frame = new Frame(this, name, sourceIndex, x, y, width, height);
this.frames[name] = frame;
if (this.firstFrame === "__BASE") {
this.firstFrame = name;
}
this.frameTotal++;
return frame;
},
/**
* Removes the given Frame from this Texture. The Frame is destroyed immediately.
*
* Any Game Objects using this Frame should stop using it _before_ you remove it,
* as it does not happen automatically.
*
* @method Phaser.Textures.Texture#remove
* @since 3.19.0
*
* @param {string} name - The key of the Frame to remove.
*
* @return {boolean} True if a Frame with the matching key was removed from this Texture.
*/
remove: function(name) {
if (this.has(name)) {
var frame = this.get(name);
frame.destroy();
delete this.frames[name];
return true;
}
return false;
},
/**
* Checks to see if a Frame matching the given key exists within this Texture.
*
* @method Phaser.Textures.Texture#has
* @since 3.0.0
*
* @param {string} name - The key of the Frame to check for.
*
* @return {boolean} True if a Frame with the matching key exists in this Texture.
*/
has: function(name) {
return this.frames.hasOwnProperty(name);
},
/**
* Gets a Frame from this Texture based on either the key or the index of the Frame.
*
* In a Texture Atlas Frames are typically referenced by a key.
* In a Sprite Sheet Frames are referenced by an index.
* Passing no value for the name returns the base texture.
*
* @method Phaser.Textures.Texture#get
* @since 3.0.0
*
* @param {(string|number)} [name] - The string-based name, or integer based index, of the Frame to get from this Texture.
*
* @return {Phaser.Textures.Frame} The Texture Frame.
*/
get: function(name) {
if (!name) {
name = this.firstFrame;
}
var frame = this.frames[name];
if (!frame) {
console.warn(TEXTURE_MISSING_ERROR, this.key, name);
frame = this.frames[this.firstFrame];
}
return frame;
},
/**
* Takes the given TextureSource and returns the index of it within this Texture.
* If it's not in this Texture, it returns -1.
* Unless this Texture has multiple TextureSources, such as with a multi-atlas, this
* method will always return zero or -1.
*
* @method Phaser.Textures.Texture#getTextureSourceIndex
* @since 3.0.0
*
* @param {Phaser.Textures.TextureSource} source - The TextureSource to check.
*
* @return {number} The index of the TextureSource within this Texture, or -1 if not in this Texture.
*/
getTextureSourceIndex: function(source) {
for (var i = 0; i < this.source.length; i++) {
if (this.source[i] === source) {
return i;
}
}
return -1;
},
/**
* Returns an array of all the Frames in the given TextureSource.
*
* @method Phaser.Textures.Texture#getFramesFromTextureSource
* @since 3.0.0
*
* @param {number} sourceIndex - The index of the TextureSource to get the Frames from.
* @param {boolean} [includeBase=false] - Include the `__BASE` Frame in the output array?
*
* @return {Phaser.Textures.Frame[]} An array of Texture Frames.
*/
getFramesFromTextureSource: function(sourceIndex, includeBase) {
if (includeBase === void 0) {
includeBase = false;
}
var out = [];
for (var frameName in this.frames) {
if (frameName === "__BASE" && !includeBase) {
continue;
}
var frame = this.frames[frameName];
if (frame.sourceIndex === sourceIndex) {
out.push(frame);
}
}
return out;
},
/**
* Based on the given Texture Source Index, this method will get all of the Frames using
* that source and then work out the bounds that they encompass, returning them in an object.
*
* This is useful if this Texture is, for example, a sprite sheet within an Atlas, and you
* need to know the total bounds of the sprite sheet.
*
* @method Phaser.Textures.Texture#getFrameBounds
* @since 3.80.0
*
* @param {number} [sourceIndex=0] - The index of the TextureSource to get the Frame bounds from.
*
* @return {Phaser.Types.Math.RectangleLike} An object containing the bounds of the Frames using the given Texture Source Index.
*/
getFrameBounds: function(sourceIndex) {
if (sourceIndex === void 0) {
sourceIndex = 0;
}
var frames = this.getFramesFromTextureSource(sourceIndex, true);
var baseFrame = frames[0];
var minX = baseFrame.cutX;
var minY = baseFrame.cutY;
var maxX = baseFrame.cutX + baseFrame.cutWidth;
var maxY = baseFrame.cutY + baseFrame.cutHeight;
for (var i = 1; i < frames.length; i++) {
var frame = frames[i];
if (frame.cutX < minX) {
minX = frame.cutX;
}
if (frame.cutY < minY) {
minY = frame.cutY;
}
if (frame.cutX + frame.cutWidth > maxX) {
maxX = frame.cutX + frame.cutWidth;
}
if (frame.cutY + frame.cutHeight > maxY) {
maxY = frame.cutY + frame.cutHeight;
}
}
return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
},
/**
* Returns an array with all of the names of the Frames in this Texture.
*
* Useful if you want to randomly assign a Frame to a Game Object, as you can
* pick a random element from the returned array.
*
* @method Phaser.Textures.Texture#getFrameNames
* @since 3.0.0
*
* @param {boolean} [includeBase=false] - Include the `__BASE` Frame in the output array?
*
* @return {string[]} An array of all Frame names in this Texture.
*/
getFrameNames: function(includeBase) {
if (includeBase === void 0) {
includeBase = false;
}
var out = Object.keys(this.frames);
if (!includeBase) {
var idx = out.indexOf("__BASE");
if (idx !== -1) {
out.splice(idx, 1);
}
}
return out;
},
/**
* Given a Frame name, return the source image it uses to render with.
*
* This will return the actual DOM Image or Canvas element.
*
* @method Phaser.Textures.Texture#getSourceImage
* @since 3.0.0
*
* @param {(string|number)} [name] - The string-based name, or integer based index, of the Frame to get from this Texture.
*
* @return {(HTMLImageElement|HTMLCanvasElement|Phaser.GameObjects.RenderTexture)} The DOM Image, Canvas Element or Render Texture.
*/
getSourceImage: function(name) {
if (name === void 0 || name === null || this.frameTotal === 1) {
name = "__BASE";
}
var frame = this.frames[name];
if (frame) {
return frame.source.image;
} else {
console.warn(TEXTURE_MISSING_ERROR, this.key, name);
return this.frames["__BASE"].source.image;
}
},
/**
* Given a Frame name, return the data source image it uses to render with.
* You can use this to get the normal map for an image for example.
*
* This will return the actual DOM Image.
*
* @method Phaser.Textures.Texture#getDataSourceImage
* @since 3.7.0
*
* @param {(string|number)} [name] - The string-based name, or integer based index, of the Frame to get from this Texture.
*
* @return {(HTMLImageElement|HTMLCanvasElement)} The DOM Image or Canvas Element.
*/
getDataSourceImage: function(name) {
if (name === void 0 || name === null || this.frameTotal === 1) {
name = "__BASE";
}
var frame = this.frames[name];
var idx;
if (!frame) {
console.warn(TEXTURE_MISSING_ERROR, this.key, name);
idx = this.frames["__BASE"].sourceIndex;
} else {
idx = frame.sourceIndex;
}
return this.dataSource[idx].image;
},
/**
* Adds a data source image to this Texture.
*
* An example of a data source image would be a normal map, where all of the Frames for this Texture
* equally apply to the normal map.
*
* @method Phaser.Textures.Texture#setDataSource
* @since 3.0.0
*
* @param {(HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[])} data - The source image.
*/
setDataSource: function(data) {
if (!Array.isArray(data)) {
data = [data];
}
for (var i = 0; i < data.length; i++) {
var source = this.source[i];
this.dataSource.push(new TextureSource(this, data[i], source.width, source.height));
}
},
/**
* Sets the Filter Mode for this Texture.
*
* The mode can be either Linear, the default, or Nearest.
*
* For pixel-art you should use Nearest.
*
* The mode applies to the entire Texture, not just a specific Frame of it.
*
* @method Phaser.Textures.Texture#setFilter
* @since 3.0.0
*
* @param {Phaser.Textures.FilterMode} filterMode - The Filter Mode.
*/
setFilter: function(filterMode) {
var i;
for (i = 0; i < this.source.length; i++) {
this.source[i].setFilter(filterMode);
}
for (i = 0; i < this.dataSource.length; i++) {
this.dataSource[i].setFilter(filterMode);
}
},
/**
* Destroys this Texture and releases references to its sources and frames.
*
* @method Phaser.Textures.Texture#destroy
* @since 3.0.0
*/
destroy: function() {
var i;
var source = this.source;
var dataSource = this.dataSource;
for (i = 0; i < source.length; i++) {
if (source[i]) {
source[i].destroy();
}
}
for (i = 0; i < dataSource.length; i++) {
if (dataSource[i]) {
dataSource[i].destroy();
}
}
for (var frameName in this.frames) {
var frame = this.frames[frameName];
if (frame) {
frame.destroy();
}
}
this.source = [];
this.dataSource = [];
this.frames = {};
this.manager.removeKey(this.key);
this.manager = null;
}
});
module2.exports = Texture;
}
),
/***/
17130: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CanvasPool = __webpack_require__2(27919);
var CanvasTexture = __webpack_require__2(57382);
var Class = __webpack_require__2(83419);
var Color = __webpack_require__2(40987);
var CONST = __webpack_require__2(8054);
var DynamicTexture = __webpack_require__2(81320);
var EventEmitter = __webpack_require__2(50792);
var Events = __webpack_require__2(69442);
var Frame = __webpack_require__2(4327);
var GameEvents = __webpack_require__2(8443);
var GenerateTexture = __webpack_require__2(99584);
var GetValue = __webpack_require__2(35154);
var ImageGameObject = __webpack_require__2(88571);
var IsPlainObject = __webpack_require__2(41212);
var Parser = __webpack_require__2(61309);
var Rectangle = __webpack_require__2(87841);
var Texture = __webpack_require__2(79237);
var TextureManager = new Class({
Extends: EventEmitter,
initialize: function TextureManager2(game) {
EventEmitter.call(this);
this.game = game;
this.name = "TextureManager";
this.list = {};
this._tempCanvas = CanvasPool.create2D(this);
this._tempContext = this._tempCanvas.getContext("2d", { willReadFrequently: true });
this._pending = 0;
this.stamp;
this.stampCrop = new Rectangle();
this.silentWarnings = false;
game.events.once(GameEvents.BOOT, this.boot, this);
},
/**
* The Boot Handler called by Phaser.Game when it first starts up.
*
* @method Phaser.Textures.TextureManager#boot
* @private
* @since 3.0.0
*/
boot: function() {
this._pending = 3;
this.on(Events.LOAD, this.updatePending, this);
this.on(Events.ERROR, this.updatePending, this);
var config = this.game.config;
if (config.defaultImage !== null) {
this.addBase64("__DEFAULT", config.defaultImage);
}
if (config.missingImage !== null) {
this.addBase64("__MISSING", config.missingImage);
}
if (config.whiteImage !== null) {
this.addBase64("__WHITE", config.whiteImage);
}
if (this.game.renderer && this.game.renderer.gl) {
this.addUint8Array("__NORMAL", new Uint8Array([127, 127, 255, 255]), 1, 1);
}
this.game.events.once(GameEvents.DESTROY, this.destroy, this);
this.game.events.once(GameEvents.SYSTEM_READY, function(scene) {
this.stamp = new ImageGameObject(scene).setOrigin(0);
}, this);
},
/**
* After 'onload' or 'onerror' invoked twice, emit 'ready' event.
*
* @method Phaser.Textures.TextureManager#updatePending
* @private
* @since 3.0.0
*/
updatePending: function() {
this._pending--;
if (this._pending === 0) {
this.off(Events.LOAD);
this.off(Events.ERROR);
this.emit(Events.READY);
}
},
/**
* Checks the given texture key and throws a console.warn if the key is already in use, then returns false.
*
* If you wish to avoid the console.warn then use `TextureManager.exists` instead.
*
* @method Phaser.Textures.TextureManager#checkKey
* @since 3.7.0
*
* @param {string} key - The texture key to check.
*
* @return {boolean} `true` if it's safe to use the texture key, otherwise `false`.
*/
checkKey: function(key) {
if (!key || typeof key !== "string" || this.exists(key)) {
if (!this.silentWarnings) {
console.error("Texture key already in use: " + key);
}
return false;
}
return true;
},
/**
* Removes a Texture from the Texture Manager and destroys it. This will immediately
* clear all references to it from the Texture Manager, and if it has one, destroy its
* WebGLTexture. This will emit a `removetexture` event.
*
* Note: If you have any Game Objects still using this texture they will start throwing
* errors the next time they try to render. Make sure that removing the texture is the final
* step when clearing down to avoid this.
*
* @method Phaser.Textures.TextureManager#remove
* @fires Phaser.Textures.Events#REMOVE
* @since 3.7.0
*
* @param {(string|Phaser.Textures.Texture)} key - The key of the Texture to remove, or a reference to it.
*
* @return {Phaser.Textures.TextureManager} The Texture Manager.
*/
remove: function(key) {
if (typeof key === "string") {
if (this.exists(key)) {
key = this.get(key);
} else {
if (!this.silentWarnings) {
console.warn("No texture found matching key: " + key);
}
return this;
}
}
var textureKey = key.key;
if (this.list.hasOwnProperty(textureKey)) {
key.destroy();
this.emit(Events.REMOVE, textureKey);
this.emit(Events.REMOVE_KEY + textureKey);
}
return this;
},
/**
* Removes a key from the Texture Manager but does not destroy the Texture that was using the key.
*
* @method Phaser.Textures.TextureManager#removeKey
* @since 3.17.0
*
* @param {string} key - The key to remove from the texture list.
*
* @return {Phaser.Textures.TextureManager} The Texture Manager.
*/
removeKey: function(key) {
if (this.list.hasOwnProperty(key)) {
delete this.list[key];
}
return this;
},
/**
* Adds a new Texture to the Texture Manager created from the given Base64 encoded data.
*
* It works by creating an `Image` DOM object, then setting the `src` attribute to
* the given base64 encoded data. As a result, the process is asynchronous by its nature,
* so be sure to listen for the events this method dispatches before using the texture.
*
* @method Phaser.Textures.TextureManager#addBase64
* @fires Phaser.Textures.Events#ADD
* @fires Phaser.Textures.Events#ERROR
* @fires Phaser.Textures.Events#LOAD
* @since 3.0.0
*
* @param {string} key - The unique string-based key of the Texture.
* @param {*} data - The Base64 encoded data.
*
* @return {this} This Texture Manager instance.
*/
addBase64: function(key, data) {
if (this.checkKey(key)) {
var _this = this;
var image = new Image();
image.onerror = function() {
_this.emit(Events.ERROR, key);
};
image.onload = function() {
var texture = _this.create(key, image);
Parser.Image(texture, 0);
_this.emit(Events.ADD, key, texture);
_this.emit(Events.ADD_KEY + key, texture);
_this.emit(Events.LOAD, key, texture);
};
image.src = data;
}
return this;
},
/**
* Gets an existing texture frame and converts it into a base64 encoded image and returns the base64 data.
*
* You can also provide the image type and encoder options.
*
* This will only work with bitmap based texture frames, such as those created from Texture Atlases.
* It will not work with GL Texture objects, such as Shaders, or Render Textures. For those please
* see the WebGL Snapshot function instead.
*
* @method Phaser.Textures.TextureManager#getBase64
* @since 3.12.0
*
* @param {string} key - The unique string-based key of the Texture.
* @param {(string|number)} [frame] - The string-based name, or integer based index, of the Frame to get from the Texture.
* @param {string} [type='image/png'] - A DOMString indicating the image format. The default format type is image/png.
* @param {number} [encoderOptions=0.92] - A Number between 0 and 1 indicating the image quality to use for image formats that use lossy compression such as image/jpeg and image/webp. If this argument is anything else, the default value for image quality is used. The default value is 0.92. Other arguments are ignored.
*
* @return {string} The base64 encoded data, or an empty string if the texture frame could not be found.
*/
getBase64: function(key, frame, type, encoderOptions) {
if (type === void 0) {
type = "image/png";
}
if (encoderOptions === void 0) {
encoderOptions = 0.92;
}
var data = "";
var textureFrame = this.getFrame(key, frame);
if (textureFrame && (textureFrame.source.isRenderTexture || textureFrame.source.isGLTexture)) {
if (!this.silentWarnings) {
console.warn("Cannot getBase64 from WebGL Texture");
}
} else if (textureFrame) {
var cd = textureFrame.canvasData;
var canvas = CanvasPool.create2D(this, cd.width, cd.height);
var ctx = canvas.getContext("2d", { willReadFrequently: true });
if (cd.width > 0 && cd.height > 0) {
ctx.drawImage(
textureFrame.source.image,
cd.x,
cd.y,
cd.width,
cd.height,
0,
0,
cd.width,
cd.height
);
}
data = canvas.toDataURL(type, encoderOptions);
CanvasPool.remove(canvas);
}
return data;
},
/**
* Adds a new Texture to the Texture Manager created from the given Image element.
*
* @method Phaser.Textures.TextureManager#addImage
* @fires Phaser.Textures.Events#ADD
* @since 3.0.0
*
* @param {string} key - The unique string-based key of the Texture.
* @param {HTMLImageElement} source - The source Image element.
* @param {HTMLImageElement|HTMLCanvasElement} [dataSource] - An optional data Image element.
*
* @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use.
*/
addImage: function(key, source, dataSource) {
var texture = null;
if (this.checkKey(key)) {
texture = this.create(key, source);
Parser.Image(texture, 0);
if (dataSource) {
texture.setDataSource(dataSource);
}
this.emit(Events.ADD, key, texture);
this.emit(Events.ADD_KEY + key, texture);
}
return texture;
},
/**
* Takes a WebGLTextureWrapper and creates a Phaser Texture from it, which is added to the Texture Manager using the given key.
*
* This allows you to then use the Texture as a normal texture for texture based Game Objects like Sprites.
*
* This is a WebGL only feature.
*
* Prior to Phaser 3.80.0, this method took a bare `WebGLTexture`
* as the `glTexture` parameter. You must now wrap the `WebGLTexture` in a
* `WebGLTextureWrapper` instance before passing it to this method.
*
* @method Phaser.Textures.TextureManager#addGLTexture
* @fires Phaser.Textures.Events#ADD
* @since 3.19.0
*
* @param {string} key - The unique string-based key of the Texture.
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper} glTexture - The source Render Texture.
*
* @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use.
*/
addGLTexture: function(key, glTexture) {
var texture = null;
if (this.checkKey(key)) {
var width = glTexture.width;
var height = glTexture.height;
texture = this.create(key, glTexture, width, height);
texture.add("__BASE", 0, 0, 0, width, height);
this.emit(Events.ADD, key, texture);
this.emit(Events.ADD_KEY + key, texture);
}
return texture;
},
/**
* Adds a Compressed Texture to this Texture Manager.
*
* The texture should typically have been loaded via the `CompressedTextureFile` loader,
* in order to prepare the correct data object this method requires.
*
* You can optionally also pass atlas data to this method, in which case a texture atlas
* will be generated from the given compressed texture, combined with the atlas data.
*
* @method Phaser.Textures.TextureManager#addCompressedTexture
* @fires Phaser.Textures.Events#ADD
* @since 3.60.0
*
* @param {string} key - The unique string-based key of the Texture.
* @param {Phaser.Types.Textures.CompressedTextureData} textureData - The Compressed Texture data object.
* @param {object} [atlasData] - Optional Texture Atlas data.
*
* @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use.
*/
addCompressedTexture: function(key, textureData, atlasData) {
var texture = null;
if (this.checkKey(key)) {
texture = this.create(key, textureData);
texture.add("__BASE", 0, 0, 0, textureData.width, textureData.height);
if (atlasData) {
var parse = function(texture2, sourceIndex, atlasData2) {
if (Array.isArray(atlasData2.textures) || Array.isArray(atlasData2.frames)) {
Parser.JSONArray(texture2, sourceIndex, atlasData2);
} else {
Parser.JSONHash(texture2, sourceIndex, atlasData2);
}
};
if (Array.isArray(atlasData)) {
for (var i = 0; i < atlasData.length; i++) {
parse(texture, i, atlasData[i]);
}
} else {
parse(texture, 0, atlasData);
}
}
this.emit(Events.ADD, key, texture);
this.emit(Events.ADD_KEY + key, texture);
}
return texture;
},
/**
* Adds a Render Texture to the Texture Manager using the given key.
* This allows you to then use the Render Texture as a normal texture for texture based Game Objects like Sprites.
*
* @method Phaser.Textures.TextureManager#addRenderTexture
* @fires Phaser.Textures.Events#ADD
* @since 3.12.0
*
* @param {string} key - The unique string-based key of the Texture.
* @param {Phaser.GameObjects.RenderTexture} renderTexture - The source Render Texture.
*
* @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use.
*/
addRenderTexture: function(key, renderTexture) {
var texture = null;
if (this.checkKey(key)) {
texture = this.create(key, renderTexture);
texture.add("__BASE", 0, 0, 0, renderTexture.width, renderTexture.height);
this.emit(Events.ADD, key, texture);
this.emit(Events.ADD_KEY + key, texture);
}
return texture;
},
/**
* Creates a new Texture using the given config values.
*
* Generated textures consist of a Canvas element to which the texture data is drawn.
*
* Generates a texture based on the given Create configuration object.
*
* The texture is drawn using a fixed-size indexed palette of 16 colors, where the hex value in the
* data cells map to a single color. For example, if the texture config looked like this:
*
* ```javascript
* var star = [
* '.....828.....',
* '....72227....',
* '....82228....',
* '...7222227...',
* '2222222222222',
* '8222222222228',
* '.72222222227.',
* '..787777787..',
* '..877777778..',
* '.78778887787.',
* '.27887.78872.',
* '.787.....787.'
* ];
*
* this.textures.generate('star', { data: star, pixelWidth: 4 });
* ```
*
* Then it would generate a texture that is 52 x 48 pixels in size, because each cell of the data array
* represents 1 pixel multiplied by the `pixelWidth` value. The cell values, such as `8`, maps to color
* number 8 in the palette. If a cell contains a period character `.` then it is transparent.
*
* The default palette is Arne16, but you can specify your own using the `palette` property.
*
* @method Phaser.Textures.TextureManager#generate
* @since 3.0.0
*
* @param {string} key - The unique string-based key of the Texture.
* @param {Phaser.Types.Create.GenerateTextureConfig} config - The configuration object needed to generate the texture.
*
* @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use.
*/
generate: function(key, config) {
if (this.checkKey(key)) {
var canvas = CanvasPool.create(this, 1, 1);
config.canvas = canvas;
GenerateTexture(config);
return this.addCanvas(key, canvas);
} else {
return null;
}
},
/**
* Creates a new Texture using a blank Canvas element of the size given.
*
* Canvas elements are automatically pooled and calling this method will
* extract a free canvas from the CanvasPool, or create one if none are available.
*
* @method Phaser.Textures.TextureManager#createCanvas
* @since 3.0.0
*
* @param {string} key - The unique string-based key of the Texture.
* @param {number} [width=256] - The width of the Canvas element.
* @param {number} [height=256] - The height of the Canvas element.
*
* @return {?Phaser.Textures.CanvasTexture} The Canvas Texture that was created, or `null` if the key is already in use.
*/
createCanvas: function(key, width, height) {
if (width === void 0) {
width = 256;
}
if (height === void 0) {
height = 256;
}
if (this.checkKey(key)) {
var canvas = CanvasPool.create(this, width, height, CONST.CANVAS, true);
return this.addCanvas(key, canvas);
}
return null;
},
/**
* Creates a new Canvas Texture object from an existing Canvas element
* and adds it to this Texture Manager, unless `skipCache` is true.
*
* @method Phaser.Textures.TextureManager#addCanvas
* @fires Phaser.Textures.Events#ADD
* @since 3.0.0
*
* @param {string} key - The unique string-based key of the Texture.
* @param {HTMLCanvasElement} source - The Canvas element to form the base of the new Texture.
* @param {boolean} [skipCache=false] - Skip adding this Texture into the Cache?
*
* @return {?Phaser.Textures.CanvasTexture} The Canvas Texture that was created, or `null` if the key is already in use.
*/
addCanvas: function(key, source, skipCache) {
if (skipCache === void 0) {
skipCache = false;
}
var texture = null;
if (skipCache) {
texture = new CanvasTexture(this, key, source, source.width, source.height);
} else if (this.checkKey(key)) {
texture = new CanvasTexture(this, key, source, source.width, source.height);
this.list[key] = texture;
this.emit(Events.ADD, key, texture);
this.emit(Events.ADD_KEY + key, texture);
}
return texture;
},
/**
* Creates a Dynamic Texture instance and adds itself to this Texture Manager.
*
* A Dynamic Texture is a special texture that allows you to draw textures, frames and most kind of
* Game Objects directly to it.
*
* You can take many complex objects and draw them to this one texture, which can then be used as the
* base texture for other Game Objects, such as Sprites. Should you then update this texture, all
* Game Objects using it will instantly be updated as well, reflecting the changes immediately.
*
* It's a powerful way to generate dynamic textures at run-time that are WebGL friendly and don't invoke
* expensive GPU uploads on each change.
*
* See the methods available on the `DynamicTexture` class for more details.
*
* Optionally, you can also pass a Dynamic Texture instance to this method to have
* it added to the Texture Manager.
*
* @method Phaser.Textures.TextureManager#addDynamicTexture
* @fires Phaser.Textures.Events#ADD
* @since 3.60.0
*
* @param {(string|Phaser.Textures.DynamicTexture)} key - The string-based key of this Texture. Must be unique within the Texture Manager. Or, a DynamicTexture instance.
* @param {number} [width=256] - The width of this Dynamic Texture in pixels. Defaults to 256 x 256. Ignored if an instance is passed as the key.
* @param {number} [height=256] - The height of this Dynamic Texture in pixels. Defaults to 256 x 256. Ignored if an instance is passed as the key.
*
* @return {?Phaser.Textures.DynamicTexture} The Dynamic Texture that was created, or `null` if the key is already in use.
*/
addDynamicTexture: function(key, width, height) {
var texture = null;
if (typeof key === "string" && !this.exists(key)) {
texture = new DynamicTexture(this, key, width, height);
} else {
texture = key;
key = texture.key;
}
if (this.checkKey(key)) {
this.list[key] = texture;
this.emit(Events.ADD, key, texture);
this.emit(Events.ADD_KEY + key, texture);
} else {
texture = null;
}
return texture;
},
/**
* Adds a Texture Atlas to this Texture Manager.
*
* In Phaser terminology, a Texture Atlas is a combination of an atlas image and a JSON data file,
* such as those exported by applications like Texture Packer.
*
* It can accept either JSON Array or JSON Hash formats, as exported by Texture Packer and similar software.
*
* As of Phaser 3.60 you can use this method to add a atlas data to an existing Phaser Texture.
*
* @method Phaser.Textures.TextureManager#addAtlas
* @since 3.0.0
*
* @param {string} key - The unique string-based key of the Texture.
* @param {(HTMLImageElement|HTMLImageElement[]|Phaser.Textures.Texture)} source - The source Image element/s, or a Phaser Texture.
* @param {(object|object[])} data - The Texture Atlas data/s.
* @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element.
*
* @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use.
*/
addAtlas: function(key, source, data, dataSource) {
if (Array.isArray(data.textures) || Array.isArray(data.frames)) {
return this.addAtlasJSONArray(key, source, data, dataSource);
} else {
return this.addAtlasJSONHash(key, source, data, dataSource);
}
},
/**
* Adds a Texture Atlas to this Texture Manager.
*
* In Phaser terminology, a Texture Atlas is a combination of an atlas image and a JSON data file,
* such as those exported by applications like Texture Packer.
*
* The frame data of the atlas must be stored in an Array within the JSON.
*
* This is known as a JSON Array in software such as Texture Packer.
*
* As of Phaser 3.60 you can use this method to add a atlas data to an existing Phaser Texture.
*
* @method Phaser.Textures.TextureManager#addAtlasJSONArray
* @fires Phaser.Textures.Events#ADD
* @since 3.0.0
*
* @param {string} key - The unique string-based key of the Texture.
* @param {(HTMLImageElement|HTMLImageElement[]|Phaser.Textures.Texture)} source - The source Image element/s, or a Phaser Texture.
* @param {(object|object[])} data - The Texture Atlas data/s.
* @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element.
*
* @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use.
*/
addAtlasJSONArray: function(key, source, data, dataSource) {
var texture = null;
if (source instanceof Texture) {
key = source.key;
texture = source;
} else if (this.checkKey(key)) {
texture = this.create(key, source);
}
if (texture) {
if (Array.isArray(data)) {
var singleAtlasFile = data.length === 1;
for (var i = 0; i < texture.source.length; i++) {
var atlasData = singleAtlasFile ? data[0] : data[i];
Parser.JSONArray(texture, i, atlasData);
}
} else {
Parser.JSONArray(texture, 0, data);
}
if (dataSource) {
texture.setDataSource(dataSource);
}
this.emit(Events.ADD, key, texture);
this.emit(Events.ADD_KEY + key, texture);
}
return texture;
},
/**
* Adds a Texture Atlas to this Texture Manager.
*
* In Phaser terminology, a Texture Atlas is a combination of an atlas image and a JSON data file,
* such as those exported by applications like Texture Packer.
*
* The frame data of the atlas must be stored in an Object within the JSON.
*
* This is known as a JSON Hash in software such as Texture Packer.
*
* As of Phaser 3.60 you can use this method to add a atlas data to an existing Phaser Texture.
*
* @method Phaser.Textures.TextureManager#addAtlasJSONHash
* @fires Phaser.Textures.Events#ADD
* @since 3.0.0
*
* @param {string} key - The unique string-based key of the Texture.
* @param {(HTMLImageElement|HTMLImageElement[]|Phaser.Textures.Texture)} source - The source Image element/s, or a Phaser Texture.
* @param {(object|object[])} data - The Texture Atlas data/s.
* @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element.
*
* @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use.
*/
addAtlasJSONHash: function(key, source, data, dataSource) {
var texture = null;
if (source instanceof Texture) {
key = source.key;
texture = source;
} else if (this.checkKey(key)) {
texture = this.create(key, source);
}
if (texture) {
if (Array.isArray(data)) {
for (var i = 0; i < data.length; i++) {
Parser.JSONHash(texture, i, data[i]);
}
} else {
Parser.JSONHash(texture, 0, data);
}
if (dataSource) {
texture.setDataSource(dataSource);
}
this.emit(Events.ADD, key, texture);
this.emit(Events.ADD_KEY + key, texture);
}
return texture;
},
/**
* Adds a Texture Atlas to this Texture Manager.
*
* In Phaser terminology, a Texture Atlas is a combination of an atlas image and a data file,
* such as those exported by applications like Texture Packer.
*
* The frame data of the atlas must be stored in an XML file.
*
* As of Phaser 3.60 you can use this method to add a atlas data to an existing Phaser Texture.
*
* @method Phaser.Textures.TextureManager#addAtlasXML
* @fires Phaser.Textures.Events#ADD
* @since 3.7.0
*
* @param {string} key - The unique string-based key of the Texture.
* @param {(HTMLImageElement|Phaser.Textures.Texture)} source - The source Image element, or a Phaser Texture.
* @param {object} data - The Texture Atlas XML data.
* @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element.
*
* @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use.
*/
addAtlasXML: function(key, source, data, dataSource) {
var texture = null;
if (source instanceof Texture) {
key = source.key;
texture = source;
} else if (this.checkKey(key)) {
texture = this.create(key, source);
}
if (texture) {
Parser.AtlasXML(texture, 0, data);
if (dataSource) {
texture.setDataSource(dataSource);
}
this.emit(Events.ADD, key, texture);
this.emit(Events.ADD_KEY + key, texture);
}
return texture;
},
/**
* Adds a Unity Texture Atlas to this Texture Manager.
*
* In Phaser terminology, a Texture Atlas is a combination of an atlas image and a data file,
* such as those exported by applications like Texture Packer or Unity.
*
* The frame data of the atlas must be stored in a Unity YAML file.
*
* As of Phaser 3.60 you can use this method to add a atlas data to an existing Phaser Texture.
*
* @method Phaser.Textures.TextureManager#addUnityAtlas
* @fires Phaser.Textures.Events#ADD
* @since 3.0.0
*
* @param {string} key - The unique string-based key of the Texture.
* @param {HTMLImageElement} source - The source Image element.
* @param {object} data - The Texture Atlas data.
* @param {HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]} [dataSource] - An optional data Image element.
*
* @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use.
*/
addUnityAtlas: function(key, source, data, dataSource) {
var texture = null;
if (source instanceof Texture) {
key = source.key;
texture = source;
} else if (this.checkKey(key)) {
texture = this.create(key, source);
}
if (texture) {
Parser.UnityYAML(texture, 0, data);
if (dataSource) {
texture.setDataSource(dataSource);
}
this.emit(Events.ADD, key, texture);
this.emit(Events.ADD_KEY + key, texture);
}
return texture;
},
/**
* Adds a Sprite Sheet to this Texture Manager.
*
* In Phaser terminology a Sprite Sheet is a texture containing different frames, but each frame is the exact
* same size and cannot be trimmed or rotated. This is different to a Texture Atlas, created by tools such as
* Texture Packer, and more akin with the fixed-frame exports you get from apps like Aseprite or old arcade
* games.
*
* As of Phaser 3.60 you can use this method to add a sprite sheet to an existing Phaser Texture.
*
* @method Phaser.Textures.TextureManager#addSpriteSheet
* @fires Phaser.Textures.Events#ADD
* @since 3.0.0
*
* @param {string} key - The unique string-based key of the Texture. Give an empty string if you provide a Phaser Texture as the 2nd argument.
* @param {(HTMLImageElement|Phaser.Textures.Texture)} source - The source Image element, or a Phaser Texture.
* @param {Phaser.Types.Textures.SpriteSheetConfig} config - The configuration object for this Sprite Sheet.
* @param {HTMLImageElement|HTMLCanvasElement} [dataSource] - An optional data Image element.
*
* @return {?Phaser.Textures.Texture} The Texture that was created or updated, or `null` if the key is already in use.
*/
addSpriteSheet: function(key, source, config, dataSource) {
var texture = null;
if (source instanceof Texture) {
key = source.key;
texture = source;
} else if (this.checkKey(key)) {
texture = this.create(key, source);
}
if (texture) {
var width = texture.source[0].width;
var height = texture.source[0].height;
Parser.SpriteSheet(texture, 0, 0, 0, width, height, config);
if (dataSource) {
texture.setDataSource(dataSource);
}
this.emit(Events.ADD, key, texture);
this.emit(Events.ADD_KEY + key, texture);
}
return texture;
},
/**
* Adds a Sprite Sheet to this Texture Manager, where the Sprite Sheet exists as a Frame within a Texture Atlas.
*
* In Phaser terminology a Sprite Sheet is a texture containing different frames, but each frame is the exact
* same size and cannot be trimmed or rotated.
*
* @method Phaser.Textures.TextureManager#addSpriteSheetFromAtlas
* @fires Phaser.Textures.Events#ADD
* @since 3.0.0
*
* @param {string} key - The unique string-based key of the Texture.
* @param {Phaser.Types.Textures.SpriteSheetFromAtlasConfig} config - The configuration object for this Sprite Sheet.
*
* @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use.
*/
addSpriteSheetFromAtlas: function(key, config) {
if (!this.checkKey(key)) {
return null;
}
var atlasKey = GetValue(config, "atlas", null);
var atlasFrame = GetValue(config, "frame", null);
if (!atlasKey || !atlasFrame) {
return;
}
var atlas = this.get(atlasKey);
var sheet = atlas.get(atlasFrame);
if (sheet) {
var source = sheet.source.image;
if (!source) {
source = sheet.source.glTexture;
}
var texture = this.create(key, source);
if (sheet.trimmed) {
Parser.SpriteSheetFromAtlas(texture, sheet, config);
} else {
Parser.SpriteSheet(texture, 0, sheet.cutX, sheet.cutY, sheet.cutWidth, sheet.cutHeight, config);
}
this.emit(Events.ADD, key, texture);
this.emit(Events.ADD_KEY + key, texture);
return texture;
}
},
/**
* Creates a texture from an array of colour data.
*
* This is only available in WebGL mode.
*
* If the dimensions provided are powers of two, the resulting texture
* will be automatically set to wrap by the WebGL Renderer.
*
* @method Phaser.Textures.TextureManager#addUint8Array
* @fires Phaser.Textures.Events#ADD
* @since 3.80.0
*
* @param {string} key - The unique string-based key of the Texture.
* @param {Uint8Array} data - The color data for the texture.
* @param {number} width - The width of the texture.
* @param {number} height - The height of the texture.
*
* @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use.
*/
addUint8Array: function(key, data, width, height) {
if (!this.checkKey(key) || data.length / 4 !== width * height) {
return null;
}
var texture = this.create(key, data, width, height);
texture.add("__BASE", 0, 0, 0, width, height);
this.emit(Events.ADD, key, texture);
this.emit(Events.ADD_KEY + key, texture);
return texture;
},
/**
* Creates a new Texture using the given source and dimensions.
*
* @method Phaser.Textures.TextureManager#create
* @since 3.0.0
*
* @param {string} key - The unique string-based key of the Texture.
* @param {(HTMLImageElement|HTMLCanvasElement|HTMLImageElement[]|HTMLCanvasElement[]|Phaser.Renderer.WebGL.Wrappers.WebGLTextureWrapper)} source - An array of sources that are used to create the texture. Usually Images, but can also be a Canvas.
* @param {number} [width] - The width of the Texture. This is optional and automatically derived from the source images.
* @param {number} [height] - The height of the Texture. This is optional and automatically derived from the source images.
*
* @return {?Phaser.Textures.Texture} The Texture that was created, or `null` if the key is already in use.
*/
create: function(key, source, width, height) {
var texture = null;
if (this.checkKey(key)) {
texture = new Texture(this, key, source, width, height);
this.list[key] = texture;
}
return texture;
},
/**
* Checks the given key to see if a Texture using it exists within this Texture Manager.
*
* @method Phaser.Textures.TextureManager#exists
* @since 3.0.0
*
* @param {string} key - The unique string-based key of the Texture.
*
* @return {boolean} Returns `true` if a Texture matching the given key exists in this Texture Manager.
*/
exists: function(key) {
return this.list.hasOwnProperty(key);
},
/**
* Returns a Texture from the Texture Manager that matches the given key.
*
* If the key is `undefined` it will return the `__DEFAULT` Texture.
*
* If the key is an instance of a Texture, it will return the instance.
*
* If the key is an instance of a Frame, it will return the frames parent Texture instance.
*
* Finally, if the key is given, but not found, and not a Texture or Frame instance, it will return the `__MISSING` Texture.
*
* @method Phaser.Textures.TextureManager#get
* @since 3.0.0
*
* @param {(string|Phaser.Textures.Texture|Phaser.Textures.Frame)} key - The unique string-based key of the Texture, or a Texture, or Frame instance.
*
* @return {Phaser.Textures.Texture} The Texture matching the given key.
*/
get: function(key) {
if (key === void 0) {
key = "__DEFAULT";
}
if (this.list[key]) {
return this.list[key];
} else if (key instanceof Texture) {
return key;
} else if (key instanceof Frame) {
return key.texture;
} else {
return this.list["__MISSING"];
}
},
/**
* Takes a Texture key and Frame name and returns a clone of that Frame if found.
*
* @method Phaser.Textures.TextureManager#cloneFrame
* @since 3.0.0
*
* @param {string} key - The unique string-based key of the Texture.
* @param {(string|number)} frame - The string or index of the Frame to be cloned.
*
* @return {Phaser.Textures.Frame} A Clone of the given Frame.
*/
cloneFrame: function(key, frame) {
if (this.list[key]) {
return this.list[key].get(frame).clone();
}
},
/**
* Takes a Texture key and Frame name and returns a reference to that Frame, if found.
*
* @method Phaser.Textures.TextureManager#getFrame
* @since 3.0.0
*
* @param {string} key - The unique string-based key of the Texture.
* @param {(string|number)} [frame] - The string-based name, or integer based index, of the Frame to get from the Texture.
*
* @return {Phaser.Textures.Frame} A Texture Frame object.
*/
getFrame: function(key, frame) {
if (this.list[key]) {
return this.list[key].get(frame);
}
},
/**
* Parses the 'key' parameter and returns a Texture Frame instance.
*
* It can accept the following formats:
*
* 1) A string
* 2) An array where the elements are: [ key, [frame] ]
* 3) An object with the properties: { key, [frame] }
* 4) A Texture instance - which returns the default frame from the Texture
* 5) A Frame instance - returns itself
*
* @method Phaser.Textures.TextureManager#parseFrame
* @since 3.60.0
*
* @param {(string|array|object|Phaser.Textures.Texture|Phaser.Textures.Frame)} key - The key to be parsed.
*
* @return {Phaser.Textures.Frame} A Texture Frame object, if found, or undefined if not.
*/
parseFrame: function(key) {
if (!key) {
return void 0;
} else if (typeof key === "string") {
return this.getFrame(key);
} else if (Array.isArray(key) && key.length === 2) {
return this.getFrame(key[0], key[1]);
} else if (IsPlainObject(key)) {
return this.getFrame(key.key, key.frame);
} else if (key instanceof Texture) {
return key.get();
} else if (key instanceof Frame) {
return key;
}
},
/**
* Returns an array with all of the keys of all Textures in this Texture Manager.
* The output array will exclude the `__DEFAULT`, `__MISSING`, `__WHITE`, and `__NORMAL` keys.
*
* @method Phaser.Textures.TextureManager#getTextureKeys
* @since 3.0.0
*
* @return {string[]} An array containing all of the Texture keys stored in this Texture Manager.
*/
getTextureKeys: function() {
var output = [];
for (var key in this.list) {
if (key !== "__DEFAULT" && key !== "__MISSING" && key !== "__WHITE" && key !== "__NORMAL") {
output.push(key);
}
}
return output;
},
/**
* Given a Texture and an `x` and `y` coordinate this method will return a new
* Color object that has been populated with the color and alpha values of the pixel
* at that location in the Texture.
*
* @method Phaser.Textures.TextureManager#getPixel
* @since 3.0.0
*
* @param {number} x - The x coordinate of the pixel within the Texture.
* @param {number} y - The y coordinate of the pixel within the Texture.
* @param {string} key - The unique string-based key of the Texture.
* @param {(string|number)} [frame] - The string or index of the Frame.
*
* @return {?Phaser.Display.Color} A Color object populated with the color values of the requested pixel,
* or `null` if the coordinates were out of bounds.
*/
getPixel: function(x, y, key, frame) {
var textureFrame = this.getFrame(key, frame);
if (textureFrame) {
x -= textureFrame.x;
y -= textureFrame.y;
var data = textureFrame.data.cut;
x += data.x;
y += data.y;
if (x >= data.x && x < data.r && y >= data.y && y < data.b) {
var ctx = this._tempContext;
ctx.clearRect(0, 0, 1, 1);
ctx.drawImage(textureFrame.source.image, x, y, 1, 1, 0, 0, 1, 1);
var rgb = ctx.getImageData(0, 0, 1, 1);
return new Color(rgb.data[0], rgb.data[1], rgb.data[2], rgb.data[3]);
}
}
return null;
},
/**
* Given a Texture and an `x` and `y` coordinate this method will return a value between 0 and 255
* corresponding to the alpha value of the pixel at that location in the Texture. If the coordinate
* is out of bounds it will return null.
*
* @method Phaser.Textures.TextureManager#getPixelAlpha
* @since 3.10.0
*
* @param {number} x - The x coordinate of the pixel within the Texture.
* @param {number} y - The y coordinate of the pixel within the Texture.
* @param {string} key - The unique string-based key of the Texture.
* @param {(string|number)} [frame] - The string or index of the Frame.
*
* @return {number} A value between 0 and 255, or `null` if the coordinates were out of bounds.
*/
getPixelAlpha: function(x, y, key, frame) {
var textureFrame = this.getFrame(key, frame);
if (textureFrame) {
x -= textureFrame.x;
y -= textureFrame.y;
var data = textureFrame.data.cut;
x += data.x;
y += data.y;
if (x >= data.x && x < data.r && y >= data.y && y < data.b) {
var ctx = this._tempContext;
ctx.clearRect(0, 0, 1, 1);
ctx.drawImage(textureFrame.source.image, x, y, 1, 1, 0, 0, 1, 1);
var rgb = ctx.getImageData(0, 0, 1, 1);
return rgb.data[3];
}
}
return null;
},
/**
* Sets the given Game Objects `texture` and `frame` properties so that it uses
* the Texture and Frame specified in the `key` and `frame` arguments to this method.
*
* @method Phaser.Textures.TextureManager#setTexture
* @since 3.0.0
*
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object the texture would be set on.
* @param {string} key - The unique string-based key of the Texture.
* @param {(string|number)} [frame] - The string or index of the Frame.
*
* @return {Phaser.GameObjects.GameObject} The Game Object the texture was set on.
*/
setTexture: function(gameObject, key, frame) {
if (this.list[key]) {
gameObject.texture = this.list[key];
gameObject.frame = gameObject.texture.get(frame);
}
return gameObject;
},
/**
* Changes the key being used by a Texture to the new key provided.
*
* The old key is removed, allowing it to be re-used.
*
* Game Objects are linked to Textures by a reference to the Texture object, so
* all existing references will be retained.
*
* @method Phaser.Textures.TextureManager#renameTexture
* @since 3.12.0
*
* @param {string} currentKey - The current string-based key of the Texture you wish to rename.
* @param {string} newKey - The new unique string-based key to use for the Texture.
*
* @return {boolean} `true` if the Texture key was successfully renamed, otherwise `false`.
*/
renameTexture: function(currentKey, newKey) {
var texture = this.get(currentKey);
if (texture && currentKey !== newKey) {
texture.key = newKey;
this.list[newKey] = texture;
delete this.list[currentKey];
return true;
}
return false;
},
/**
* Passes all Textures to the given callback.
*
* @method Phaser.Textures.TextureManager#each
* @since 3.0.0
*
* @param {EachTextureCallback} callback - The callback function to be sent the Textures.
* @param {object} scope - The value to use as `this` when executing the callback.
* @param {...*} [args] - Additional arguments that will be passed to the callback, after the child.
*/
each: function(callback, scope) {
var args = [null];
for (var i = 1; i < arguments.length; i++) {
args.push(arguments[i]);
}
for (var texture in this.list) {
args[0] = this.list[texture];
callback.apply(scope, args);
}
},
/**
* Resets the internal Stamp object, ready for drawing and returns it.
*
* @method Phaser.Textures.TextureManager#resetStamp
* @since 3.60.0
*
* @param {number} [alpha=1] - The alpha to use.
* @param {number} [tint=0xffffff] - WebGL only. The tint color to use.
*
* @return {Phaser.GameObjects.Image} A reference to the Stamp Game Object.
*/
resetStamp: function(alpha, tint) {
if (alpha === void 0) {
alpha = 1;
}
if (tint === void 0) {
tint = 16777215;
}
var stamp = this.stamp;
stamp.setCrop();
stamp.setPosition(0);
stamp.setAngle(0);
stamp.setScale(1);
stamp.setAlpha(alpha);
stamp.setTint(tint);
stamp.setTexture("__WHITE");
return stamp;
},
/**
* Destroys the Texture Manager and all Textures stored within it.
*
* @method Phaser.Textures.TextureManager#destroy
* @since 3.0.0
*/
destroy: function() {
for (var texture in this.list) {
this.list[texture].destroy();
}
this.list = {};
this.stamp.destroy();
this.game = null;
this.stamp = null;
CanvasPool.remove(this._tempCanvas);
}
});
module2.exports = TextureManager;
}
),
/***/
11876: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CanvasPool = __webpack_require__2(27919);
var Class = __webpack_require__2(83419);
var IsSizePowerOfTwo = __webpack_require__2(50030);
var ScaleModes = __webpack_require__2(29795);
var WebGLTextureWrapper = __webpack_require__2(82751);
var TextureSource = new Class({
initialize: function TextureSource2(texture, source, width, height, flipY) {
if (flipY === void 0) {
flipY = false;
}
var game = texture.manager.game;
this.renderer = game.renderer;
this.texture = texture;
this.source = source;
this.image = source.compressed ? null : source;
this.compressionAlgorithm = source.compressed ? source.format : null;
this.resolution = 1;
this.width = width || source.naturalWidth || source.videoWidth || source.width || 0;
this.height = height || source.naturalHeight || source.videoHeight || source.height || 0;
this.scaleMode = ScaleModes.DEFAULT;
this.isCanvas = source instanceof HTMLCanvasElement;
this.isVideo = window.hasOwnProperty("HTMLVideoElement") && source instanceof HTMLVideoElement;
this.isRenderTexture = source.type === "RenderTexture" || source.type === "DynamicTexture";
this.isGLTexture = source instanceof WebGLTextureWrapper;
this.isPowerOf2 = IsSizePowerOfTwo(this.width, this.height);
this.glTexture = null;
this.flipY = flipY;
this.init(game);
},
/**
* Creates a WebGL Texture, if required, and sets the Texture filter mode.
*
* @method Phaser.Textures.TextureSource#init
* @since 3.0.0
*
* @param {Phaser.Game} game - A reference to the Phaser Game instance.
*/
init: function(game) {
var renderer = this.renderer;
if (renderer) {
var source = this.source;
if (renderer.gl) {
var image = this.image;
var flipY = this.flipY;
var width = this.width;
var height = this.height;
var scaleMode = this.scaleMode;
if (this.isCanvas) {
this.glTexture = renderer.createCanvasTexture(image, false, flipY);
} else if (this.isVideo) {
this.glTexture = renderer.createVideoTexture(image, false, flipY);
} else if (this.isRenderTexture) {
this.glTexture = renderer.createTextureFromSource(null, width, height, scaleMode);
} else if (this.isGLTexture) {
this.glTexture = source;
} else if (this.compressionAlgorithm) {
this.glTexture = renderer.createTextureFromSource(source, void 0, void 0, scaleMode);
} else if (source instanceof Uint8Array) {
this.glTexture = renderer.createUint8ArrayTexture(source, width, height, scaleMode);
} else {
this.glTexture = renderer.createTextureFromSource(image, width, height, scaleMode);
}
if (false) {
}
} else if (this.isRenderTexture) {
this.image = source.canvas;
}
}
if (!game.config.antialias) {
this.setFilter(1);
}
},
/**
* Sets the Filter Mode for this Texture.
*
* The mode can be either Linear, the default, or Nearest.
*
* For pixel-art you should use Nearest.
*
* @method Phaser.Textures.TextureSource#setFilter
* @since 3.0.0
*
* @param {Phaser.Textures.FilterMode} filterMode - The Filter Mode.
*/
setFilter: function(filterMode) {
if (this.renderer && this.renderer.gl) {
this.renderer.setTextureFilter(this.glTexture, filterMode);
}
this.scaleMode = filterMode;
},
/**
* Sets the `UNPACK_FLIP_Y_WEBGL` flag for the WebGL Texture during texture upload.
*
* @method Phaser.Textures.TextureSource#setFlipY
* @since 3.20.0
*
* @param {boolean} [value=true] - Should the WebGL Texture be flipped on the Y axis on texture upload or not?
*/
setFlipY: function(value) {
if (value === void 0) {
value = true;
}
if (value === this.flipY) {
return this;
}
this.flipY = value;
this.update();
return this;
},
/**
* If this TextureSource is backed by a Canvas and is running under WebGL,
* it updates the WebGLTexture using the canvas data.
*
* @method Phaser.Textures.TextureSource#update
* @since 3.7.0
*/
update: function() {
var renderer = this.renderer;
var image = this.image;
var flipY = this.flipY;
var gl = renderer.gl;
if (gl && this.isCanvas) {
renderer.updateCanvasTexture(image, this.glTexture, flipY);
} else if (gl && this.isVideo) {
renderer.updateVideoTexture(image, this.glTexture, flipY);
}
},
/**
* Destroys this Texture Source and nulls the references.
*
* @method Phaser.Textures.TextureSource#destroy
* @since 3.0.0
*/
destroy: function() {
if (this.glTexture) {
this.renderer.deleteTexture(this.glTexture);
}
if (this.isCanvas) {
CanvasPool.remove(this.image);
}
this.renderer = null;
this.texture = null;
this.source = null;
this.image = null;
this.glTexture = null;
}
});
module2.exports = TextureSource;
}
),
/***/
19673: (
/***/
(module2) => {
var CONST = {
/**
* Linear filter type.
*
* @name Phaser.Textures.FilterMode.LINEAR
* @type {number}
* @const
* @since 3.0.0
*/
LINEAR: 0,
/**
* Nearest neighbor filter type.
*
* @name Phaser.Textures.FilterMode.NEAREST
* @type {number}
* @const
* @since 3.0.0
*/
NEAREST: 1
};
module2.exports = CONST;
}
),
/***/
44538: (
/***/
(module2) => {
module2.exports = "addtexture";
}
),
/***/
63486: (
/***/
(module2) => {
module2.exports = "addtexture-";
}
),
/***/
94851: (
/***/
(module2) => {
module2.exports = "onerror";
}
),
/***/
29099: (
/***/
(module2) => {
module2.exports = "onload";
}
),
/***/
8678: (
/***/
(module2) => {
module2.exports = "ready";
}
),
/***/
86415: (
/***/
(module2) => {
module2.exports = "removetexture";
}
),
/***/
30879: (
/***/
(module2) => {
module2.exports = "removetexture-";
}
),
/***/
69442: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
ADD: __webpack_require__2(44538),
ADD_KEY: __webpack_require__2(63486),
ERROR: __webpack_require__2(94851),
LOAD: __webpack_require__2(29099),
READY: __webpack_require__2(8678),
REMOVE: __webpack_require__2(86415),
REMOVE_KEY: __webpack_require__2(30879)
};
}
),
/***/
27458: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Extend = __webpack_require__2(79291);
var FilterMode = __webpack_require__2(19673);
var Textures = {
CanvasTexture: __webpack_require__2(57382),
DynamicTexture: __webpack_require__2(81320),
Events: __webpack_require__2(69442),
FilterMode,
Frame: __webpack_require__2(4327),
Parsers: __webpack_require__2(61309),
Texture: __webpack_require__2(79237),
TextureManager: __webpack_require__2(17130),
TextureSource: __webpack_require__2(11876)
};
Textures = Extend(false, Textures, FilterMode);
module2.exports = Textures;
}
),
/***/
89905: (
/***/
(module2) => {
var AtlasXML = function(texture, sourceIndex, xml) {
if (!xml.getElementsByTagName("TextureAtlas")) {
console.warn("Invalid Texture Atlas XML given");
return;
}
var source = texture.source[sourceIndex];
texture.add("__BASE", sourceIndex, 0, 0, source.width, source.height);
var frames = xml.getElementsByTagName("SubTexture");
var newFrame;
for (var i = 0; i < frames.length; i++) {
var frame = frames[i].attributes;
var name = frame.name.value;
var x = parseInt(frame.x.value, 10);
var y = parseInt(frame.y.value, 10);
var width = parseInt(frame.width.value, 10);
var height = parseInt(frame.height.value, 10);
newFrame = texture.add(name, sourceIndex, x, y, width, height);
if (frame.frameX) {
var frameX = Math.abs(parseInt(frame.frameX.value, 10));
var frameY = Math.abs(parseInt(frame.frameY.value, 10));
var frameWidth = parseInt(frame.frameWidth.value, 10);
var frameHeight = parseInt(frame.frameHeight.value, 10);
newFrame.setTrim(
width,
height,
frameX,
frameY,
frameWidth,
frameHeight
);
}
}
return texture;
};
module2.exports = AtlasXML;
}
),
/***/
72893: (
/***/
(module2) => {
var Canvas = function(texture, sourceIndex) {
var source = texture.source[sourceIndex];
texture.add("__BASE", sourceIndex, 0, 0, source.width, source.height);
return texture;
};
module2.exports = Canvas;
}
),
/***/
4832: (
/***/
(module2) => {
var Image2 = function(texture, sourceIndex) {
var source = texture.source[sourceIndex];
texture.add("__BASE", sourceIndex, 0, 0, source.width, source.height);
return texture;
};
module2.exports = Image2;
}
),
/***/
78566: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Clone = __webpack_require__2(41786);
var JSONArray = function(texture, sourceIndex, json) {
if (!json["frames"] && !json["textures"]) {
console.warn("Invalid Texture Atlas JSON Array");
return;
}
var source = texture.source[sourceIndex];
texture.add("__BASE", sourceIndex, 0, 0, source.width, source.height);
var frames = Array.isArray(json.textures) ? json.textures[sourceIndex].frames : json.frames;
var newFrame;
for (var i = 0; i < frames.length; i++) {
var src = frames[i];
newFrame = texture.add(src.filename, sourceIndex, src.frame.x, src.frame.y, src.frame.w, src.frame.h);
if (!newFrame) {
console.warn("Invalid atlas json, frame already exists: " + src.filename);
continue;
}
if (src.trimmed) {
newFrame.setTrim(
src.sourceSize.w,
src.sourceSize.h,
src.spriteSourceSize.x,
src.spriteSourceSize.y,
src.spriteSourceSize.w,
src.spriteSourceSize.h
);
}
if (src.rotated) {
newFrame.rotated = true;
newFrame.updateUVsInverted();
}
var pivot = src.anchor || src.pivot;
if (pivot) {
newFrame.customPivot = true;
newFrame.pivotX = pivot.x;
newFrame.pivotY = pivot.y;
}
if (src.scale9Borders) {
newFrame.setScale9(
src.scale9Borders.x,
src.scale9Borders.y,
src.scale9Borders.w,
src.scale9Borders.h
);
}
newFrame.customData = Clone(src);
}
for (var dataKey in json) {
if (dataKey === "frames") {
continue;
}
if (Array.isArray(json[dataKey])) {
texture.customData[dataKey] = json[dataKey].slice(0);
} else {
texture.customData[dataKey] = json[dataKey];
}
}
return texture;
};
module2.exports = JSONArray;
}
),
/***/
39711: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Clone = __webpack_require__2(41786);
var JSONHash = function(texture, sourceIndex, json) {
if (!json["frames"]) {
console.warn("Invalid Texture Atlas JSON Hash given, missing 'frames' Object");
return;
}
var source = texture.source[sourceIndex];
texture.add("__BASE", sourceIndex, 0, 0, source.width, source.height);
var frames = json.frames;
var newFrame;
for (var key in frames) {
if (!frames.hasOwnProperty(key)) {
continue;
}
var src = frames[key];
newFrame = texture.add(key, sourceIndex, src.frame.x, src.frame.y, src.frame.w, src.frame.h);
if (!newFrame) {
console.warn("Invalid atlas json, frame already exists: " + key);
continue;
}
if (src.trimmed) {
newFrame.setTrim(
src.sourceSize.w,
src.sourceSize.h,
src.spriteSourceSize.x,
src.spriteSourceSize.y,
src.spriteSourceSize.w,
src.spriteSourceSize.h
);
}
if (src.rotated) {
newFrame.rotated = true;
newFrame.updateUVsInverted();
}
var pivot = src.anchor || src.pivot;
if (pivot) {
newFrame.customPivot = true;
newFrame.pivotX = pivot.x;
newFrame.pivotY = pivot.y;
}
if (src.scale9Borders) {
newFrame.setScale9(
src.scale9Borders.x,
src.scale9Borders.y,
src.scale9Borders.w,
src.scale9Borders.h
);
}
newFrame.customData = Clone(src);
}
for (var dataKey in json) {
if (dataKey === "frames") {
continue;
}
if (Array.isArray(json[dataKey])) {
texture.customData[dataKey] = json[dataKey].slice(0);
} else {
texture.customData[dataKey] = json[dataKey];
}
}
return texture;
};
module2.exports = JSONHash;
}
),
/***/
31403: (
/***/
(module2) => {
var KTXParser = function(data) {
var idCheck = [171, 75, 84, 88, 32, 49, 49, 187, 13, 10, 26, 10];
var i;
var id = new Uint8Array(data, 0, 12);
for (i = 0; i < id.length; i++) {
if (id[i] !== idCheck[i]) {
console.warn("KTXParser - Invalid file format");
return;
}
}
var size = Uint32Array.BYTES_PER_ELEMENT;
var head = new DataView(data, 12, 13 * size);
var littleEndian = head.getUint32(0, true) === 67305985;
var glType = head.getUint32(1 * size, littleEndian);
if (glType !== 0) {
console.warn("KTXParser - Only compressed formats supported");
return;
}
var internalFormat = head.getUint32(4 * size, littleEndian);
var width = head.getUint32(6 * size, littleEndian);
var height = head.getUint32(7 * size, littleEndian);
var mipmapLevels = Math.max(1, head.getUint32(11 * size, littleEndian));
var bytesOfKeyValueData = head.getUint32(12 * size, littleEndian);
var mipmaps = new Array(mipmapLevels);
var offset = 12 + 13 * 4 + bytesOfKeyValueData;
var levelWidth = width;
var levelHeight = height;
for (i = 0; i < mipmapLevels; i++) {
var levelSize = new Int32Array(data, offset, 1)[0];
offset += 4;
mipmaps[i] = {
data: new Uint8Array(data, offset, levelSize),
width: levelWidth,
height: levelHeight
};
levelWidth = Math.max(1, levelWidth >> 1);
levelHeight = Math.max(1, levelHeight >> 1);
offset += levelSize;
}
return {
mipmaps,
width,
height,
internalFormat,
compressed: true,
generateMipmap: false
};
};
module2.exports = KTXParser;
}
),
/***/
82038: (
/***/
(module2) => {
function GetSize(width, height, x, y, dx, dy, mult) {
if (mult === void 0) {
mult = 16;
}
return Math.floor((width + x) / dx) * Math.floor((height + y) / dy) * mult;
}
function PVRTC2bppSize(width, height) {
width = Math.max(width, 16);
height = Math.max(height, 8);
return width * height / 4;
}
function PVRTC4bppSize(width, height) {
width = Math.max(width, 8);
height = Math.max(height, 8);
return width * height / 2;
}
function BPTCSize(width, height) {
return Math.ceil(width / 4) * Math.ceil(height / 4) * 16;
}
function DXTEtcSmallSize(width, height) {
return GetSize(width, height, 3, 3, 4, 4, 8);
}
function DXTEtcAstcBigSize(width, height) {
return GetSize(width, height, 3, 3, 4, 4);
}
function ATC5x4Size(width, height) {
return GetSize(width, height, 4, 3, 5, 4);
}
function ATC5x5Size(width, height) {
return GetSize(width, height, 4, 4, 5, 5);
}
function ATC6x5Size(width, height) {
return GetSize(width, height, 5, 4, 6, 5);
}
function ATC6x6Size(width, height) {
return GetSize(width, height, 5, 5, 6, 6);
}
function ATC8x5Size(width, height) {
return GetSize(width, height, 7, 4, 8, 5);
}
function ATC8x6Size(width, height) {
return GetSize(width, height, 7, 5, 8, 6);
}
function ATC8x8Size(width, height) {
return GetSize(width, height, 7, 7, 8, 8);
}
function ATC10x5Size(width, height) {
return GetSize(width, height, 9, 4, 10, 5);
}
function ATC10x6Size(width, height) {
return GetSize(width, height, 9, 5, 10, 6);
}
function ATC10x8Size(width, height) {
return GetSize(width, height, 9, 7, 10, 8);
}
function ATC10x10Size(width, height) {
return GetSize(width, height, 9, 9, 10, 10);
}
function ATC12x10Size(width, height) {
return GetSize(width, height, 11, 9, 12, 10);
}
function ATC12x12Size(width, height) {
return GetSize(width, height, 11, 11, 12, 12);
}
var FORMATS = {
0: { sizeFunc: PVRTC2bppSize, glFormat: [35841] },
1: { sizeFunc: PVRTC2bppSize, glFormat: [35843] },
2: { sizeFunc: PVRTC4bppSize, glFormat: [35840] },
3: { sizeFunc: PVRTC4bppSize, glFormat: [35842] },
6: { sizeFunc: DXTEtcSmallSize, glFormat: [36196] },
7: { sizeFunc: DXTEtcSmallSize, glFormat: [33776, 35916] },
8: { sizeFunc: DXTEtcAstcBigSize, glFormat: [33777, 35917] },
9: { sizeFunc: DXTEtcAstcBigSize, glFormat: [33778, 35918] },
11: { sizeFunc: DXTEtcAstcBigSize, glFormat: [33779, 35919] },
14: { sizeFunc: BPTCSize, glFormat: [36494, 36495] },
15: { sizeFunc: BPTCSize, glFormat: [36492, 36493] },
22: { sizeFunc: DXTEtcSmallSize, glFormat: [37492, 37493] },
23: { sizeFunc: DXTEtcAstcBigSize, glFormat: [37496, 37497] },
24: { sizeFunc: DXTEtcSmallSize, glFormat: [37494, 37495] },
25: { sizeFunc: DXTEtcSmallSize, glFormat: [37488] },
26: { sizeFunc: DXTEtcAstcBigSize, glFormat: [37490] },
27: { sizeFunc: DXTEtcAstcBigSize, glFormat: [37808, 37840] },
28: { sizeFunc: ATC5x4Size, glFormat: [37809, 37841] },
29: { sizeFunc: ATC5x5Size, glFormat: [37810, 37842] },
30: { sizeFunc: ATC6x5Size, glFormat: [37811, 37843] },
31: { sizeFunc: ATC6x6Size, glFormat: [37812, 37844] },
32: { sizeFunc: ATC8x5Size, glFormat: [37813, 37845] },
33: { sizeFunc: ATC8x6Size, glFormat: [37814, 37846] },
34: { sizeFunc: ATC8x8Size, glFormat: [37815, 37847] },
35: { sizeFunc: ATC10x5Size, glFormat: [37816, 37848] },
36: { sizeFunc: ATC10x6Size, glFormat: [37817, 37849] },
37: { sizeFunc: ATC10x8Size, glFormat: [37818, 37850] },
38: { sizeFunc: ATC10x10Size, glFormat: [37819, 37851] },
39: { sizeFunc: ATC12x10Size, glFormat: [37820, 37852] },
40: { sizeFunc: ATC12x12Size, glFormat: [37821, 37853] }
};
var PVRParser = function(data) {
var header = new Uint32Array(data, 0, 13);
var version = header[0];
var versionMatch = version === 55727696;
var pvrFormat = versionMatch ? header[2] : header[3];
var colorSpace = header[4];
var internalFormat = FORMATS[pvrFormat].glFormat[colorSpace];
var sizeFunction = FORMATS[pvrFormat].sizeFunc;
var mipmapLevels = header[11];
var width = header[7];
var height = header[6];
var dataOffset = 52 + header[12];
var image = new Uint8Array(data, dataOffset);
var mipmaps = new Array(mipmapLevels);
var offset = 0;
var levelWidth = width;
var levelHeight = height;
for (var i = 0; i < mipmapLevels; i++) {
var levelSize = sizeFunction(levelWidth, levelHeight);
mipmaps[i] = {
data: new Uint8Array(image.buffer, image.byteOffset + offset, levelSize),
width: levelWidth,
height: levelHeight
};
levelWidth = Math.max(1, levelWidth >> 1);
levelHeight = Math.max(1, levelHeight >> 1);
offset += levelSize;
}
return {
mipmaps,
width,
height,
internalFormat,
compressed: true,
generateMipmap: false
};
};
module2.exports = PVRParser;
}
),
/***/
75549: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetFastValue = __webpack_require__2(95540);
var SpriteSheet = function(texture, sourceIndex, x, y, width, height, config) {
var frameWidth = GetFastValue(config, "frameWidth", null);
var frameHeight = GetFastValue(config, "frameHeight", frameWidth);
if (frameWidth === null) {
throw new Error("TextureManager.SpriteSheet: Invalid frameWidth given.");
}
var source = texture.source[sourceIndex];
texture.add("__BASE", sourceIndex, 0, 0, source.width, source.height);
var startFrame = GetFastValue(config, "startFrame", 0);
var endFrame = GetFastValue(config, "endFrame", -1);
var margin = GetFastValue(config, "margin", 0);
var spacing = GetFastValue(config, "spacing", 0);
var row = Math.floor((width - margin + spacing) / (frameWidth + spacing));
var column = Math.floor((height - margin + spacing) / (frameHeight + spacing));
var total = row * column;
if (total === 0) {
console.warn("SpriteSheet frame dimensions will result in zero frames for texture:", texture.key);
}
if (startFrame > total || startFrame < -total) {
startFrame = 0;
}
if (startFrame < 0) {
startFrame = total + startFrame;
}
if (endFrame === -1 || endFrame > total || endFrame < startFrame) {
endFrame = total;
}
var fx = margin;
var fy = margin;
var ax = 0;
var ay = 0;
var c = 0;
for (var i = 0; i < total; i++) {
ax = 0;
ay = 0;
var w = fx + frameWidth;
var h = fy + frameHeight;
if (w > width) {
ax = w - width;
}
if (h > height) {
ay = h - height;
}
if (i >= startFrame && i <= endFrame) {
texture.add(c, sourceIndex, x + fx, y + fy, frameWidth - ax, frameHeight - ay);
c++;
}
fx += frameWidth + spacing;
if (fx + frameWidth > width) {
fx = margin;
fy += frameHeight + spacing;
}
}
return texture;
};
module2.exports = SpriteSheet;
}
),
/***/
47534: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetFastValue = __webpack_require__2(95540);
var SpriteSheetFromAtlas = function(texture, frame, config) {
var frameWidth = GetFastValue(config, "frameWidth", null);
var frameHeight = GetFastValue(config, "frameHeight", frameWidth);
if (!frameWidth) {
throw new Error("TextureManager.SpriteSheetFromAtlas: Invalid frameWidth given.");
}
var source = texture.source[0];
texture.add("__BASE", 0, 0, 0, source.width, source.height);
var startFrame = GetFastValue(config, "startFrame", 0);
var endFrame = GetFastValue(config, "endFrame", -1);
var margin = GetFastValue(config, "margin", 0);
var spacing = GetFastValue(config, "spacing", 0);
var x = frame.cutX;
var y = frame.cutY;
var cutWidth = frame.cutWidth;
var cutHeight = frame.cutHeight;
var sheetWidth = frame.realWidth;
var sheetHeight = frame.realHeight;
var row = Math.floor((sheetWidth - margin + spacing) / (frameWidth + spacing));
var column = Math.floor((sheetHeight - margin + spacing) / (frameHeight + spacing));
var total = row * column;
var leftPad = frame.x;
var leftWidth = frameWidth - leftPad;
var rightWidth = frameWidth - (sheetWidth - cutWidth - leftPad);
var topPad = frame.y;
var topHeight = frameHeight - topPad;
var bottomHeight = frameHeight - (sheetHeight - cutHeight - topPad);
if (startFrame > total || startFrame < -total) {
startFrame = 0;
}
if (startFrame < 0) {
startFrame = total + startFrame;
}
if (endFrame !== -1) {
total = startFrame + (endFrame + 1);
}
var sheetFrame;
var frameX = margin;
var frameY = margin;
var frameIndex = 0;
var sourceIndex = 0;
for (var sheetY = 0; sheetY < column; sheetY++) {
var topRow = sheetY === 0;
var bottomRow = sheetY === column - 1;
for (var sheetX = 0; sheetX < row; sheetX++) {
var leftRow = sheetX === 0;
var rightRow = sheetX === row - 1;
sheetFrame = texture.add(frameIndex, sourceIndex, x + frameX, y + frameY, frameWidth, frameHeight);
if (leftRow || topRow || rightRow || bottomRow) {
var destX = leftRow ? leftPad : 0;
var destY = topRow ? topPad : 0;
var trimWidth = 0;
var trimHeight = 0;
if (leftRow) {
trimWidth += frameWidth - leftWidth;
}
if (rightRow) {
trimWidth += frameWidth - rightWidth;
}
if (topRow) {
trimHeight += frameHeight - topHeight;
}
if (bottomRow) {
trimHeight += frameHeight - bottomHeight;
}
var destWidth = frameWidth - trimWidth;
var destHeight = frameHeight - trimHeight;
sheetFrame.cutWidth = destWidth;
sheetFrame.cutHeight = destHeight;
sheetFrame.setTrim(frameWidth, frameHeight, destX, destY, destWidth, destHeight);
}
frameX += spacing;
if (leftRow) {
frameX += leftWidth;
} else if (rightRow) {
frameX += rightWidth;
} else {
frameX += frameWidth;
}
frameIndex++;
}
frameX = margin;
frameY += spacing;
if (topRow) {
frameY += topHeight;
} else if (bottomRow) {
frameY += bottomHeight;
} else {
frameY += frameHeight;
}
}
return texture;
};
module2.exports = SpriteSheetFromAtlas;
}
),
/***/
86147: (
/***/
(module2) => {
var imageHeight = 0;
var addFrame = function(texture, sourceIndex, name, frame) {
var y = imageHeight - frame.y - frame.height;
texture.add(name, sourceIndex, frame.x, y, frame.width, frame.height);
};
var UnityYAML = function(texture, sourceIndex, yaml) {
var source = texture.source[sourceIndex];
texture.add("__BASE", sourceIndex, 0, 0, source.width, source.height);
imageHeight = source.height;
var data = yaml.split("\n");
var lineRegExp = /^[ ]*(- )*(\w+)+[: ]+(.*)/;
var prevSprite = "";
var currentSprite = "";
var rect = { x: 0, y: 0, width: 0, height: 0 };
for (var i = 0; i < data.length; i++) {
var results = data[i].match(lineRegExp);
if (!results) {
continue;
}
var isList = results[1] === "- ";
var key = results[2];
var value = results[3];
if (isList) {
if (currentSprite !== prevSprite) {
addFrame(texture, sourceIndex, currentSprite, rect);
prevSprite = currentSprite;
}
rect = { x: 0, y: 0, width: 0, height: 0 };
}
if (key === "name") {
currentSprite = value;
continue;
}
switch (key) {
case "x":
case "y":
case "width":
case "height":
rect[key] = parseInt(value, 10);
break;
}
}
if (currentSprite !== prevSprite) {
addFrame(texture, sourceIndex, currentSprite, rect);
}
return texture;
};
module2.exports = UnityYAML;
}
),
/***/
55222: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var IsSizePowerOfTwo = __webpack_require__2(50030);
var verifyCompressedTexture = function(data) {
var mipmaps = data.mipmaps;
for (var level = 1; level < mipmaps.length; level++) {
var width = mipmaps[level].width;
var height = mipmaps[level].height;
if (!IsSizePowerOfTwo(width, height)) {
console.warn("Mip level " + level + " is not a power-of-two size: " + width + "x" + height);
return false;
}
}
var checker = formatCheckers[data.internalFormat];
if (!checker) {
console.warn("No format checker found for internal format " + data.internalFormat + ". Assuming valid.");
return true;
}
return checker(data);
};
function check4x4(data) {
var mipmaps = data.mipmaps;
for (var level = 0; level < mipmaps.length; level++) {
var width = mipmaps[level].width;
var height = mipmaps[level].height;
if ((width << level) % 4 !== 0 || (height << level) % 4 !== 0) {
console.warn("BPTC, RGTC, and S3TC dimensions must be a multiple of 4 pixels, and each successive mip level must be half the size of the previous level, rounded down. Mip level " + level + " is " + width + "x" + height);
return false;
}
}
return true;
}
function checkAlways() {
return true;
}
function checkPVRTC(data) {
var mipmaps = data.mipmaps;
var baseLevel = mipmaps[0];
if (!IsSizePowerOfTwo(baseLevel.width, baseLevel.height)) {
console.warn("PVRTC base dimensions must be power of two. Base level is " + baseLevel.width + "x" + baseLevel.height);
return false;
}
return true;
}
function checkS3TCSRGB(data) {
var mipmaps = data.mipmaps;
var baseLevel = mipmaps[0];
if (baseLevel.width % 4 !== 0 || baseLevel.height % 4 !== 0) {
console.warn("S3TC SRGB base dimensions must be a multiple of 4 pixels. Base level is " + baseLevel.width + "x" + baseLevel.height + " pixels");
return false;
}
return true;
}
var formatCheckers = {
// ETC internal formats:
// COMPRESSED_R11_EAC
37488: checkAlways,
// COMPRESSED_SIGNED_R11_EAC
37489: checkAlways,
// COMPRESSED_RG11_EAC
37490: checkAlways,
// COMPRESSED_SIGNED_RG11_EAC
37491: checkAlways,
// COMPRESSED_RGB8_ETC2
37492: checkAlways,
// COMPRESSED_SRGB8_ETC2
37493: checkAlways,
// COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
37494: checkAlways,
// COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
37495: checkAlways,
// COMPRESSED_RGBA8_ETC2_EAC
37496: checkAlways,
// COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
37497: checkAlways,
// ETC1 internal formats:
// COMPRESSED_RGB_ETC1_WEBGL
36196: checkAlways,
// ATC internal formats:
// COMPRESSED_RGB_ATC_WEBGL
// COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL
// COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL
// These formats are no longer supported in WebGL.
// They have no special restrictions on size, so if they were decoded,
// they are already valid.
// We'll show a warning for no format checker found.
// ASTC internal formats:
// COMPRESSED_RGBA_ASTC_4x4_KHR
37808: checkAlways,
// COMPRESSED_RGBA_ASTC_5x4_KHR
37809: checkAlways,
// COMPRESSED_RGBA_ASTC_5x5_KHR
37810: checkAlways,
// COMPRESSED_RGBA_ASTC_6x5_KHR
37811: checkAlways,
// COMPRESSED_RGBA_ASTC_6x6_KHR
37812: checkAlways,
// COMPRESSED_RGBA_ASTC_8x5_KHR
37813: checkAlways,
// COMPRESSED_RGBA_ASTC_8x6_KHR
37814: checkAlways,
// COMPRESSED_RGBA_ASTC_8x8_KHR
37815: checkAlways,
// COMPRESSED_RGBA_ASTC_10x5_KHR
37816: checkAlways,
// COMPRESSED_RGBA_ASTC_10x6_KHR
37817: checkAlways,
// COMPRESSED_RGBA_ASTC_10x8_KHR
37818: checkAlways,
// COMPRESSED_RGBA_ASTC_10x10_KHR
37819: checkAlways,
// COMPRESSED_RGBA_ASTC_12x10_KHR
37820: checkAlways,
// COMPRESSED_RGBA_ASTC_12x12_KHR
37821: checkAlways,
// COMPRESSED_SRGB8_ALPHA8_ASTC_4X4_KHR
37840: checkAlways,
// COMPRESSED_SRGB8_ALPHA8_ASTC_5X4_KHR
37841: checkAlways,
// COMPRESSED_SRGB8_ALPHA8_ASTC_5X5_KHR
37842: checkAlways,
// COMPRESSED_SRGB8_ALPHA8_ASTC_6X5_KHR
37843: checkAlways,
// COMPRESSED_SRGB8_ALPHA8_ASTC_6X6_KHR
37844: checkAlways,
// COMPRESSED_SRGB8_ALPHA8_ASTC_8X5_KHR
37845: checkAlways,
// COMPRESSED_SRGB8_ALPHA8_ASTC_8X6_KHR
37846: checkAlways,
// COMPRESSED_SRGB8_ALPHA8_ASTC_8X8_KHR
37847: checkAlways,
// COMPRESSED_SRGB8_ALPHA8_ASTC_10X5_KHR
37848: checkAlways,
// COMPRESSED_SRGB8_ALPHA8_ASTC_10X6_KHR
37849: checkAlways,
// COMPRESSED_SRGB8_ALPHA8_ASTC_10X8_KHR
37850: checkAlways,
// COMPRESSED_SRGB8_ALPHA8_ASTC_10X10_KHR
37851: checkAlways,
// COMPRESSED_SRGB8_ALPHA8_ASTC_12X10_KHR
37852: checkAlways,
// COMPRESSED_SRGB8_ALPHA8_ASTC_12X12_KHR
37853: checkAlways,
// BPTC internal formats:
// COMPRESSED_RGBA_BPTC_UNORM_EXT
36492: check4x4,
// COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT
36493: check4x4,
// COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT
36494: check4x4,
// COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT
36495: check4x4,
// RGTC internal formats:
// COMPRESSED_RED_RGTC1
36283: check4x4,
// COMPRESSED_SIGNED_RED_RGTC1
36284: check4x4,
// COMPRESSED_RG_RGTC2
36285: check4x4,
// COMPRESSED_SIGNED_RG_RGTC2
36286: check4x4,
// PVRTC internal formats:
// COMPRESSED_RGB_PVRTC_4BPPV1_IMG
35840: checkPVRTC,
// COMPRESSED_RGB_PVRTC_2BPPV1_IMG
35841: checkPVRTC,
// COMPRESSED_RGBA_PVRTC_4BPPV1_IMG
35842: checkPVRTC,
// COMPRESSED_RGBA_PVRTC_2BPPV1_IMG
35843: checkPVRTC,
// S3TC internal formats:
// COMPRESSED_RGB_S3TC_DXT1_EXT
33776: check4x4,
// COMPRESSED_RGBA_S3TC_DXT1_EXT
33777: check4x4,
// COMPRESSED_RGBA_S3TC_DXT3_EXT
33778: check4x4,
// COMPRESSED_RGBA_S3TC_DXT5_EXT
33779: check4x4,
// S3TCSRGB internal formats:
// COMPRESSED_SRGB_S3TC_DXT1_EXT
35916: checkS3TCSRGB,
// COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
35917: checkS3TCSRGB,
// COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
35918: checkS3TCSRGB,
// COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
35919: checkS3TCSRGB
};
module2.exports = verifyCompressedTexture;
}
),
/***/
61309: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
AtlasXML: __webpack_require__2(89905),
Canvas: __webpack_require__2(72893),
Image: __webpack_require__2(4832),
JSONArray: __webpack_require__2(78566),
JSONHash: __webpack_require__2(39711),
KTXParser: __webpack_require__2(31403),
PVRParser: __webpack_require__2(82038),
SpriteSheet: __webpack_require__2(75549),
SpriteSheetFromAtlas: __webpack_require__2(47534),
UnityYAML: __webpack_require__2(86147)
};
}
),
/***/
80341: (
/***/
(module2) => {
module2.exports = {
/**
* CSV Map Type
*
* @name Phaser.Tilemaps.Formats.CSV
* @type {number}
* @since 3.0.0
*/
CSV: 0,
/**
* Tiled JSON Map Type
*
* @name Phaser.Tilemaps.Formats.TILED_JSON
* @type {number}
* @since 3.0.0
*/
TILED_JSON: 1,
/**
* 2D Array Map Type
*
* @name Phaser.Tilemaps.Formats.ARRAY_2D
* @type {number}
* @since 3.0.0
*/
ARRAY_2D: 2,
/**
* Weltmeister (Impact.js) Map Type
*
* @name Phaser.Tilemaps.Formats.WELTMEISTER
* @type {number}
* @since 3.0.0
*/
WELTMEISTER: 3
};
}
),
/***/
16536: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var ImageCollection = new Class({
initialize: function ImageCollection2(name, firstgid, width, height, margin, spacing, properties) {
if (width === void 0 || width <= 0) {
width = 32;
}
if (height === void 0 || height <= 0) {
height = 32;
}
if (margin === void 0) {
margin = 0;
}
if (spacing === void 0) {
spacing = 0;
}
this.name = name;
this.firstgid = firstgid | 0;
this.imageWidth = width | 0;
this.imageHeight = height | 0;
this.imageMargin = margin | 0;
this.imageSpacing = spacing | 0;
this.properties = properties || {};
this.images = [];
this.total = 0;
},
/**
* Returns true if and only if this image collection contains the given image index.
*
* @method Phaser.Tilemaps.ImageCollection#containsImageIndex
* @since 3.0.0
*
* @param {number} imageIndex - The image index to search for.
*
* @return {boolean} True if this Image Collection contains the given index.
*/
containsImageIndex: function(imageIndex) {
return imageIndex >= this.firstgid && imageIndex < this.firstgid + this.total;
},
/**
* Add an image to this Image Collection.
*
* @method Phaser.Tilemaps.ImageCollection#addImage
* @since 3.0.0
*
* @param {number} gid - The gid of the image in the Image Collection.
* @param {string} image - The the key of the image in the Image Collection and in the cache.
*
* @return {Phaser.Tilemaps.ImageCollection} This ImageCollection object.
*/
addImage: function(gid, image) {
this.images.push({ gid, image });
this.total++;
return this;
}
});
module2.exports = ImageCollection;
}
),
/***/
27462: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var ObjectHelper = new Class({
initialize: function ObjectHelper2(tilesets) {
this.gids = [];
if (tilesets !== void 0) {
for (var t = 0; t < tilesets.length; ++t) {
var tileset = tilesets[t];
for (var i = 0; i < tileset.total; ++i) {
this.gids[tileset.firstgid + i] = tileset;
}
}
}
this._gids = this.gids;
},
/**
* Enabled if the object helper reaches in to tilesets for data.
* Disabled if it only uses data directly on a gid object.
*
* @name Phaser.Tilemaps.ObjectHelper#enabled
* @type {boolean}
* @since 3.60.0
*/
enabled: {
get: function() {
return !!this.gids;
},
set: function(v) {
this.gids = v ? this._gids : void 0;
}
},
/**
* Gets the Tiled `type` field value from the object or the `gid` behind it.
*
* @method Phaser.Tilemaps.ObjectHelper#getTypeIncludingTile
* @since 3.60.0
*
* @param {Phaser.Types.Tilemaps.TiledObject} obj - The Tiled object to investigate.
*
* @return {?string} The `type` of the object, the tile behind the `gid` of the object, or `undefined`.
*/
getTypeIncludingTile: function(obj) {
if (obj.type !== void 0 && obj.type !== "") {
return obj.type;
}
if (!this.gids || obj.gid === void 0) {
return void 0;
}
var tileset = this.gids[obj.gid];
if (!tileset) {
return void 0;
}
var tileData = tileset.getTileData(obj.gid);
if (!tileData) {
return void 0;
}
return tileData.type;
},
/**
* Sets the sprite texture data as specified (usually in a config) or, failing that,
* as specified in the `gid` of the object being loaded (if any).
*
* This fallback will only work if the tileset was loaded as a spritesheet matching
* the geometry of sprites fed into tiled, so that, for example: "tile id #`3`"" within
* the tileset is the same as texture frame `3` from the image of the tileset.
*
* @method Phaser.Tilemaps.ObjectHelper#setTextureAndFrame
* @since 3.60.0
*
* @param {Phaser.GameObjects.GameObject} sprite - The Game Object to modify.
* @param {string|Phaser.Textures.Texture} [key] - The texture key to set (or else the `obj.gid`'s tile is used if available).
* @param {string|number|Phaser.Textures.Frame} [frame] - The frames key to set (or else the `obj.gid`'s tile is used if available).
* @param {Phaser.Types.Tilemaps.TiledObject} [obj] - The Tiled object for fallback.
*/
setTextureAndFrame: function(sprite, key, frame, obj) {
if (key === null && this.gids && obj.gid !== void 0) {
var tileset = this.gids[obj.gid];
if (tileset) {
if (key === null && tileset.image !== void 0) {
key = tileset.image.key;
}
if (frame === null) {
frame = obj.gid - tileset.firstgid;
}
if (!sprite.scene.textures.getFrame(key, frame)) {
key = null;
frame = null;
}
}
}
sprite.setTexture(key, frame);
},
/**
* Sets the `sprite.data` field from the tiled properties on the object and its tile (if any).
*
* @method Phaser.Tilemaps.ObjectHelper#setPropertiesFromTiledObject
* @since 3.60.0
*
* @param {Phaser.GameObjects.GameObject} sprite
* @param {Phaser.Types.Tilemaps.TiledObject} obj
*/
setPropertiesFromTiledObject: function(sprite, obj) {
if (this.gids !== void 0 && obj.gid !== void 0) {
var tileset = this.gids[obj.gid];
if (tileset !== void 0) {
this.setFromJSON(sprite, tileset.getTileProperties(obj.gid));
}
}
this.setFromJSON(sprite, obj.properties);
},
/**
* Sets the sprite data from the JSON object.
*
* @method Phaser.Tilemaps.ObjectHelper#setFromJSON
* @since 3.60.0
* @private
*
* @param {Phaser.GameObjects.GameObject} sprite - The object for which to populate `data`.
* @param {(Object.<string, *>|Object[])} properties - The properties to set in either JSON object format or else a list of objects with `name` and `value` fields.
*/
setFromJSON: function(sprite, properties) {
if (!properties) {
return;
}
if (Array.isArray(properties)) {
for (var i = 0; i < properties.length; i++) {
var prop = properties[i];
if (sprite[prop.name] !== void 0) {
sprite[prop.name] = prop.value;
} else {
sprite.setData(prop.name, prop.value);
}
}
return;
}
for (var key in properties) {
if (sprite[key] !== void 0) {
sprite[key] = properties[key];
} else {
sprite.setData(key, properties[key]);
}
}
}
});
module2.exports = ObjectHelper;
}
),
/***/
31989: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Formats = __webpack_require__2(80341);
var MapData = __webpack_require__2(87010);
var Parse = __webpack_require__2(46177);
var Tilemap = __webpack_require__2(49075);
var ParseToTilemap = function(scene, key, tileWidth, tileHeight, width, height, data, insertNull) {
if (tileWidth === void 0) {
tileWidth = 32;
}
if (tileHeight === void 0) {
tileHeight = 32;
}
if (width === void 0) {
width = 10;
}
if (height === void 0) {
height = 10;
}
if (insertNull === void 0) {
insertNull = false;
}
var mapData = null;
if (Array.isArray(data)) {
var name = key !== void 0 ? key : "map";
mapData = Parse(name, Formats.ARRAY_2D, data, tileWidth, tileHeight, insertNull);
} else if (key !== void 0) {
var tilemapData = scene.cache.tilemap.get(key);
if (!tilemapData) {
console.warn("No map data found for key " + key);
} else {
mapData = Parse(key, tilemapData.format, tilemapData.data, tileWidth, tileHeight, insertNull);
}
}
if (mapData === null) {
mapData = new MapData({
tileWidth,
tileHeight,
width,
height
});
}
return new Tilemap(scene, mapData);
};
module2.exports = ParseToTilemap;
}
),
/***/
23029: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Components = __webpack_require__2(31401);
var CONST = __webpack_require__2(91907);
var DeepCopy = __webpack_require__2(62644);
var Rectangle = __webpack_require__2(93232);
var Tile = new Class({
Mixins: [
Components.AlphaSingle,
Components.Flip,
Components.Visible
],
initialize: function Tile2(layer, index, x, y, width, height, baseWidth, baseHeight) {
this.layer = layer;
this.index = index;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.right;
this.bottom;
this.baseWidth = baseWidth !== void 0 ? baseWidth : width;
this.baseHeight = baseHeight !== void 0 ? baseHeight : height;
this.pixelX = 0;
this.pixelY = 0;
this.updatePixelXY();
this.properties = {};
this.rotation = 0;
this.collideLeft = false;
this.collideRight = false;
this.collideUp = false;
this.collideDown = false;
this.faceLeft = false;
this.faceRight = false;
this.faceTop = false;
this.faceBottom = false;
this.collisionCallback = void 0;
this.collisionCallbackContext = this;
this.tint = 16777215;
this.tintFill = false;
this.physics = {};
},
/**
* Check if the given x and y world coordinates are within this Tile. This does not factor in
* camera scroll, layer scale or layer position.
*
* @method Phaser.Tilemaps.Tile#containsPoint
* @since 3.0.0
*
* @param {number} x - The x coordinate to test.
* @param {number} y - The y coordinate to test.
*
* @return {boolean} True if the coordinates are within this Tile, otherwise false.
*/
containsPoint: function(x, y) {
return !(x < this.pixelX || y < this.pixelY || x > this.right || y > this.bottom);
},
/**
* Copies the tile data and properties from the given Tile to this Tile. This copies everything
* except for position and interesting face calculations.
*
* @method Phaser.Tilemaps.Tile#copy
* @since 3.0.0
*
* @param {Phaser.Tilemaps.Tile} tile - The tile to copy from.
*
* @return {this} This Tile object instance.
*/
copy: function(tile) {
this.index = tile.index;
this.alpha = tile.alpha;
this.properties = DeepCopy(tile.properties);
this.visible = tile.visible;
this.setFlip(tile.flipX, tile.flipY);
this.tint = tile.tint;
this.rotation = tile.rotation;
this.collideUp = tile.collideUp;
this.collideDown = tile.collideDown;
this.collideLeft = tile.collideLeft;
this.collideRight = tile.collideRight;
this.collisionCallback = tile.collisionCallback;
this.collisionCallbackContext = tile.collisionCallbackContext;
return this;
},
/**
* The collision group for this Tile, defined within the Tileset. This returns a reference to
* the collision group stored within the Tileset, so any modification of the returned object
* will impact all tiles that have the same index as this tile.
*
* @method Phaser.Tilemaps.Tile#getCollisionGroup
* @since 3.0.0
*
* @return {?object} The collision group for this Tile, as defined in the Tileset, or `null` if no group was defined.
*/
getCollisionGroup: function() {
return this.tileset ? this.tileset.getTileCollisionGroup(this.index) : null;
},
/**
* The tile data for this Tile, defined within the Tileset. This typically contains Tiled
* collision data, tile animations and terrain information. This returns a reference to the tile
* data stored within the Tileset, so any modification of the returned object will impact all
* tiles that have the same index as this tile.
*
* @method Phaser.Tilemaps.Tile#getTileData
* @since 3.0.0
*
* @return {?object} The tile data for this Tile, as defined in the Tileset, or `null` if no data was defined.
*/
getTileData: function() {
return this.tileset ? this.tileset.getTileData(this.index) : null;
},
/**
* Gets the world X position of the left side of the tile, factoring in the layers position,
* scale and scroll.
*
* @method Phaser.Tilemaps.Tile#getLeft
* @since 3.0.0
*
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use to perform the check.
*
* @return {number} The left (x) value of this tile.
*/
getLeft: function(camera) {
var tilemapLayer = this.tilemapLayer;
if (tilemapLayer) {
var point = tilemapLayer.tileToWorldXY(this.x, this.y, void 0, camera);
return point.x;
}
return this.x * this.baseWidth;
},
/**
* Gets the world X position of the right side of the tile, factoring in the layer's position,
* scale and scroll.
*
* @method Phaser.Tilemaps.Tile#getRight
* @since 3.0.0
*
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use to perform the check.
*
* @return {number} The right (x) value of this tile.
*/
getRight: function(camera) {
var tilemapLayer = this.tilemapLayer;
return tilemapLayer ? this.getLeft(camera) + this.width * tilemapLayer.scaleX : this.getLeft(camera) + this.width;
},
/**
* Gets the world Y position of the top side of the tile, factoring in the layer's position,
* scale and scroll.
*
* @method Phaser.Tilemaps.Tile#getTop
* @since 3.0.0
*
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use to perform the check.
*
* @return {number} The top (y) value of this tile.
*/
getTop: function(camera) {
var tilemapLayer = this.tilemapLayer;
if (tilemapLayer) {
var point = tilemapLayer.tileToWorldXY(this.x, this.y, void 0, camera);
return point.y;
}
return this.y * this.baseWidth - (this.height - this.baseHeight);
},
/**
* Gets the world Y position of the bottom side of the tile, factoring in the layer's position,
* scale and scroll.
* @method Phaser.Tilemaps.Tile#getBottom
* @since 3.0.0
*
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use to perform the check.
*
* @return {number} The bottom (y) value of this tile.
*/
getBottom: function(camera) {
var tilemapLayer = this.tilemapLayer;
return tilemapLayer ? this.getTop(camera) + this.height * tilemapLayer.scaleY : this.getTop(camera) + this.height;
},
/**
* Gets the world rectangle bounding box for the tile, factoring in the layers position,
* scale and scroll.
*
* @method Phaser.Tilemaps.Tile#getBounds
* @since 3.0.0
*
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use to perform the check.
* @param {Phaser.Geom.Rectangle} [output] - Optional Rectangle object to store the results in.
*
* @return {(Phaser.Geom.Rectangle|object)} The bounds of this Tile.
*/
getBounds: function(camera, output) {
if (output === void 0) {
output = new Rectangle();
}
output.x = this.getLeft(camera);
output.y = this.getTop(camera);
output.width = this.getRight(camera) - output.x;
output.height = this.getBottom(camera) - output.y;
return output;
},
/**
* Gets the world X position of the center of the tile, factoring in the layer's position,
* scale and scroll.
*
* @method Phaser.Tilemaps.Tile#getCenterX
* @since 3.0.0
*
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use to perform the check.
*
* @return {number} The center x position of this Tile.
*/
getCenterX: function(camera) {
return (this.getLeft(camera) + this.getRight(camera)) / 2;
},
/**
* Gets the world Y position of the center of the tile, factoring in the layer's position,
* scale and scroll.
*
* @method Phaser.Tilemaps.Tile#getCenterY
* @since 3.0.0
*
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use to perform the check.
*
* @return {number} The center y position of this Tile.
*/
getCenterY: function(camera) {
return (this.getTop(camera) + this.getBottom(camera)) / 2;
},
/**
* Check for intersection with this tile. This does not factor in camera scroll, layer scale or
* layer position.
*
* @method Phaser.Tilemaps.Tile#intersects
* @since 3.0.0
*
* @param {number} x - The x axis in pixels.
* @param {number} y - The y axis in pixels.
* @param {number} right - The right point.
* @param {number} bottom - The bottom point.
*
* @return {boolean} `true` if the Tile intersects with the given dimensions, otherwise `false`.
*/
intersects: function(x, y, right, bottom) {
return !(right <= this.pixelX || bottom <= this.pixelY || x >= this.right || y >= this.bottom);
},
/**
* Checks if the tile is interesting.
*
* @method Phaser.Tilemaps.Tile#isInteresting
* @since 3.0.0
*
* @param {boolean} collides - If true, will consider the tile interesting if it collides on any side.
* @param {boolean} faces - If true, will consider the tile interesting if it has an interesting face.
*
* @return {boolean} True if the Tile is interesting, otherwise false.
*/
isInteresting: function(collides, faces) {
if (collides && faces) {
return this.canCollide || this.hasInterestingFace;
} else if (collides) {
return this.collides;
} else if (faces) {
return this.hasInterestingFace;
}
return false;
},
/**
* Reset collision status flags.
*
* @method Phaser.Tilemaps.Tile#resetCollision
* @since 3.0.0
*
* @param {boolean} [recalculateFaces=true] - Whether or not to recalculate interesting faces for this tile and its neighbors.
*
* @return {this} This Tile object instance.
*/
resetCollision: function(recalculateFaces) {
if (recalculateFaces === void 0) {
recalculateFaces = true;
}
this.collideLeft = false;
this.collideRight = false;
this.collideUp = false;
this.collideDown = false;
this.faceTop = false;
this.faceBottom = false;
this.faceLeft = false;
this.faceRight = false;
if (recalculateFaces) {
var tilemapLayer = this.tilemapLayer;
if (tilemapLayer) {
this.tilemapLayer.calculateFacesAt(this.x, this.y);
}
}
return this;
},
/**
* Reset faces.
*
* @method Phaser.Tilemaps.Tile#resetFaces
* @since 3.0.0
*
* @return {this} This Tile object instance.
*/
resetFaces: function() {
this.faceTop = false;
this.faceBottom = false;
this.faceLeft = false;
this.faceRight = false;
return this;
},
/**
* Sets the collision flags for each side of this tile and updates the interesting faces list.
*
* @method Phaser.Tilemaps.Tile#setCollision
* @since 3.0.0
*
* @param {boolean} left - Indicating collide with any object on the left.
* @param {boolean} [right] - Indicating collide with any object on the right.
* @param {boolean} [up] - Indicating collide with any object on the top.
* @param {boolean} [down] - Indicating collide with any object on the bottom.
* @param {boolean} [recalculateFaces=true] - Whether or not to recalculate interesting faces for this tile and its neighbors.
*
* @return {this} This Tile object instance.
*/
setCollision: function(left, right, up, down, recalculateFaces) {
if (right === void 0) {
right = left;
}
if (up === void 0) {
up = left;
}
if (down === void 0) {
down = left;
}
if (recalculateFaces === void 0) {
recalculateFaces = true;
}
this.collideLeft = left;
this.collideRight = right;
this.collideUp = up;
this.collideDown = down;
this.faceLeft = left;
this.faceRight = right;
this.faceTop = up;
this.faceBottom = down;
if (recalculateFaces) {
var tilemapLayer = this.tilemapLayer;
if (tilemapLayer) {
this.tilemapLayer.calculateFacesAt(this.x, this.y);
}
}
return this;
},
/**
* Set a callback to be called when this tile is hit by an object. The callback must true for
* collision processing to take place.
*
* @method Phaser.Tilemaps.Tile#setCollisionCallback
* @since 3.0.0
*
* @param {function} callback - Callback function.
* @param {object} context - Callback will be called within this context.
*
* @return {this} This Tile object instance.
*/
setCollisionCallback: function(callback, context) {
if (callback === null) {
this.collisionCallback = void 0;
this.collisionCallbackContext = void 0;
} else {
this.collisionCallback = callback;
this.collisionCallbackContext = context;
}
return this;
},
/**
* Sets the size of the tile and updates its pixelX and pixelY.
*
* @method Phaser.Tilemaps.Tile#setSize
* @since 3.0.0
*
* @param {number} tileWidth - The width of the tile in pixels.
* @param {number} tileHeight - The height of the tile in pixels.
* @param {number} baseWidth - The base width a tile in the map (in pixels).
* @param {number} baseHeight - The base height of the tile in pixels (in pixels).
*
* @return {this} This Tile object instance.
*/
setSize: function(tileWidth, tileHeight, baseWidth, baseHeight) {
if (tileWidth !== void 0) {
this.width = tileWidth;
}
if (tileHeight !== void 0) {
this.height = tileHeight;
}
if (baseWidth !== void 0) {
this.baseWidth = baseWidth;
}
if (baseHeight !== void 0) {
this.baseHeight = baseHeight;
}
this.updatePixelXY();
return this;
},
/**
* Used internally. Updates the tiles world XY position based on the current tile size.
*
* @method Phaser.Tilemaps.Tile#updatePixelXY
* @since 3.0.0
*
* @return {this} This Tile object instance.
*/
updatePixelXY: function() {
var orientation = this.layer.orientation;
if (orientation === CONST.ORTHOGONAL) {
this.pixelX = this.x * this.baseWidth;
this.pixelY = this.y * this.baseHeight;
} else if (orientation === CONST.ISOMETRIC) {
this.pixelX = (this.x - this.y) * this.baseWidth * 0.5;
this.pixelY = (this.x + this.y) * this.baseHeight * 0.5;
} else if (orientation === CONST.STAGGERED) {
this.pixelX = this.x * this.baseWidth + this.y % 2 * (this.baseWidth / 2);
this.pixelY = this.y * (this.baseHeight / 2);
} else if (orientation === CONST.HEXAGONAL) {
var staggerAxis = this.layer.staggerAxis;
var staggerIndex = this.layer.staggerIndex;
var len = this.layer.hexSideLength;
var rowWidth;
var rowHeight;
if (staggerAxis === "y") {
rowHeight = (this.baseHeight - len) / 2 + len;
if (staggerIndex === "odd") {
this.pixelX = this.x * this.baseWidth + this.y % 2 * (this.baseWidth / 2);
} else {
this.pixelX = this.x * this.baseWidth - this.y % 2 * (this.baseWidth / 2);
}
this.pixelY = this.y * rowHeight;
} else if (staggerAxis === "x") {
rowWidth = (this.baseWidth - len) / 2 + len;
this.pixelX = this.x * rowWidth;
if (staggerIndex === "odd") {
this.pixelY = this.y * this.baseHeight + this.x % 2 * (this.baseHeight / 2);
} else {
this.pixelY = this.y * this.baseHeight - this.x % 2 * (this.baseHeight / 2);
}
}
}
this.right = this.pixelX + this.baseWidth;
this.bottom = this.pixelY + this.baseHeight;
return this;
},
/**
* Clean up memory.
*
* @method Phaser.Tilemaps.Tile#destroy
* @since 3.0.0
*/
destroy: function() {
this.collisionCallback = void 0;
this.collisionCallbackContext = void 0;
this.properties = void 0;
},
/**
* True if this tile can collide on any of its faces or has a collision callback set.
*
* @name Phaser.Tilemaps.Tile#canCollide
* @type {boolean}
* @readonly
* @since 3.0.0
*/
canCollide: {
get: function() {
return this.collideLeft || this.collideRight || this.collideUp || this.collideDown || this.collisionCallback !== void 0;
}
},
/**
* True if this tile can collide on any of its faces.
*
* @name Phaser.Tilemaps.Tile#collides
* @type {boolean}
* @readonly
* @since 3.0.0
*/
collides: {
get: function() {
return this.collideLeft || this.collideRight || this.collideUp || this.collideDown;
}
},
/**
* True if this tile has any interesting faces.
*
* @name Phaser.Tilemaps.Tile#hasInterestingFace
* @type {boolean}
* @readonly
* @since 3.0.0
*/
hasInterestingFace: {
get: function() {
return this.faceTop || this.faceBottom || this.faceLeft || this.faceRight;
}
},
/**
* The tileset that contains this Tile. This is null if accessed from a LayerData instance
* before the tile is placed in a TilemapLayer, or if the tile has an index that doesn't correspond
* to any of the maps tilesets.
*
* @name Phaser.Tilemaps.Tile#tileset
* @type {?Phaser.Tilemaps.Tileset}
* @readonly
* @since 3.0.0
*/
tileset: {
get: function() {
var tilemapLayer = this.layer.tilemapLayer;
if (tilemapLayer) {
var tileset = tilemapLayer.gidMap[this.index];
if (tileset) {
return tileset;
}
}
return null;
}
},
/**
* The tilemap layer that contains this Tile. This will only return null if accessed from a
* LayerData instance before the tile is placed within a TilemapLayer.
*
* @name Phaser.Tilemaps.Tile#tilemapLayer
* @type {?Phaser.Tilemaps.TilemapLayer}
* @readonly
* @since 3.0.0
*/
tilemapLayer: {
get: function() {
return this.layer.tilemapLayer;
}
},
/**
* The tilemap that contains this Tile. This will only return null if accessed from a LayerData
* instance before the tile is placed within a TilemapLayer.
*
* @name Phaser.Tilemaps.Tile#tilemap
* @type {?Phaser.Tilemaps.Tilemap}
* @readonly
* @since 3.0.0
*/
tilemap: {
get: function() {
var tilemapLayer = this.tilemapLayer;
return tilemapLayer ? tilemapLayer.tilemap : null;
}
}
});
module2.exports = Tile;
}
),
/***/
49075: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BuildTilesetIndex = __webpack_require__2(84101);
var Class = __webpack_require__2(83419);
var DegToRad = __webpack_require__2(39506);
var Formats = __webpack_require__2(80341);
var GetFastValue = __webpack_require__2(95540);
var LayerData = __webpack_require__2(14977);
var ObjectHelper = __webpack_require__2(27462);
var ORIENTATION = __webpack_require__2(91907);
var Rotate = __webpack_require__2(36305);
var SpliceOne = __webpack_require__2(19133);
var Sprite = __webpack_require__2(68287);
var Tile = __webpack_require__2(23029);
var TilemapComponents = __webpack_require__2(81086);
var TilemapLayer = __webpack_require__2(20442);
var Tileset = __webpack_require__2(33629);
var Tilemap = new Class({
initialize: function Tilemap2(scene, mapData) {
this.scene = scene;
this.tileWidth = mapData.tileWidth;
this.tileHeight = mapData.tileHeight;
this.width = mapData.width;
this.height = mapData.height;
this.orientation = mapData.orientation;
this.renderOrder = mapData.renderOrder;
this.format = mapData.format;
this.version = mapData.version;
this.properties = mapData.properties;
this.widthInPixels = mapData.widthInPixels;
this.heightInPixels = mapData.heightInPixels;
this.imageCollections = mapData.imageCollections;
this.images = mapData.images;
this.layers = mapData.layers;
this.tiles = mapData.tiles;
this.tilesets = mapData.tilesets;
this.objects = mapData.objects;
this.currentLayerIndex = 0;
this.hexSideLength = mapData.hexSideLength;
var orientation = this.orientation;
this._convert = {
WorldToTileXY: TilemapComponents.GetWorldToTileXYFunction(orientation),
WorldToTileX: TilemapComponents.GetWorldToTileXFunction(orientation),
WorldToTileY: TilemapComponents.GetWorldToTileYFunction(orientation),
TileToWorldXY: TilemapComponents.GetTileToWorldXYFunction(orientation),
TileToWorldX: TilemapComponents.GetTileToWorldXFunction(orientation),
TileToWorldY: TilemapComponents.GetTileToWorldYFunction(orientation),
GetTileCorners: TilemapComponents.GetTileCornersFunction(orientation)
};
},
/**
* Sets the rendering (draw) order of the tiles in this map.
*
* The default is 'right-down', meaning it will order the tiles starting from the top-left,
* drawing to the right and then moving down to the next row.
*
* The draw orders are:
*
* 0 = right-down
* 1 = left-down
* 2 = right-up
* 3 = left-up
*
* Setting the render order does not change the tiles or how they are stored in the layer,
* it purely impacts the order in which they are rendered.
*
* You can provide either an integer (0 to 3), or the string version of the order.
*
* Calling this method _after_ creating Tilemap Layers will **not** automatically
* update them to use the new render order. If you call this method after creating layers, use their
* own `setRenderOrder` methods to change them as needed.
*
* @method Phaser.Tilemaps.Tilemap#setRenderOrder
* @since 3.12.0
*
* @param {(number|string)} renderOrder - The render (draw) order value. Either an integer between 0 and 3, or a string: 'right-down', 'left-down', 'right-up' or 'left-up'.
*
* @return {this} This Tilemap object.
*/
setRenderOrder: function(renderOrder) {
var orders = ["right-down", "left-down", "right-up", "left-up"];
if (typeof renderOrder === "number") {
renderOrder = orders[renderOrder];
}
if (orders.indexOf(renderOrder) > -1) {
this.renderOrder = renderOrder;
}
return this;
},
/**
* Adds an image to the map to be used as a tileset. A single map may use multiple tilesets.
* Note that the tileset name can be found in the JSON file exported from Tiled, or in the Tiled
* editor.
*
* @method Phaser.Tilemaps.Tilemap#addTilesetImage
* @since 3.0.0
*
* @param {string} tilesetName - The name of the tileset as specified in the map data.
* @param {string} [key] - The key of the Phaser.Cache image used for this tileset. If
* `undefined` or `null` it will look for an image with a key matching the tilesetName parameter.
* @param {number} [tileWidth] - The width of the tile (in pixels) in the Tileset Image. If not
* given it will default to the map's tileWidth value, or the tileWidth specified in the Tiled
* JSON file.
* @param {number} [tileHeight] - The height of the tiles (in pixels) in the Tileset Image. If
* not given it will default to the map's tileHeight value, or the tileHeight specified in the
* Tiled JSON file.
* @param {number} [tileMargin] - The margin around the tiles in the sheet (in pixels). If not
* specified, it will default to 0 or the value specified in the Tiled JSON file.
* @param {number} [tileSpacing] - The spacing between each the tile in the sheet (in pixels).
* If not specified, it will default to 0 or the value specified in the Tiled JSON file.
* @param {number} [gid=0] - If adding multiple tilesets to a blank map, specify the starting
* GID this set will use here.
* @param {object} [tileOffset={x: 0, y: 0}] - Tile texture drawing offset.
* If not specified, it will default to {0, 0}
*
* @return {?Phaser.Tilemaps.Tileset} Returns the Tileset object that was created or updated, or null if it
* failed.
*/
addTilesetImage: function(tilesetName, key, tileWidth, tileHeight, tileMargin, tileSpacing, gid, tileOffset) {
if (tilesetName === void 0) {
return null;
}
if (key === void 0 || key === null) {
key = tilesetName;
}
var textureManager = this.scene.sys.textures;
if (!textureManager.exists(key)) {
console.warn('Texture key "%s" not found', key);
return null;
}
var texture = textureManager.get(key);
var index = this.getTilesetIndex(tilesetName);
if (index === null && this.format === Formats.TILED_JSON) {
console.warn('Tilemap has no tileset "%s". Its tilesets are %o', tilesetName, this.tilesets);
return null;
}
var tileset = this.tilesets[index];
if (tileset) {
if (tileWidth || tileHeight) {
tileset.setTileSize(tileWidth, tileHeight);
}
if (tileMargin || tileSpacing) {
tileset.setSpacing(tileMargin, tileSpacing);
}
tileset.setImage(texture);
return tileset;
}
if (tileWidth === void 0) {
tileWidth = this.tileWidth;
}
if (tileHeight === void 0) {
tileHeight = this.tileHeight;
}
if (tileMargin === void 0) {
tileMargin = 0;
}
if (tileSpacing === void 0) {
tileSpacing = 0;
}
if (gid === void 0) {
gid = 0;
}
if (tileOffset === void 0) {
tileOffset = { x: 0, y: 0 };
}
tileset = new Tileset(tilesetName, gid, tileWidth, tileHeight, tileMargin, tileSpacing, void 0, void 0, tileOffset);
tileset.setImage(texture);
this.tilesets.push(tileset);
this.tiles = BuildTilesetIndex(this);
return tileset;
},
/**
* Copies the tiles in the source rectangular area to a new destination (all specified in tile
* coordinates) within the layer. This copies all tile properties & recalculates collision
* information in the destination region.
*
* If no layer specified, the map's current layer is used. This cannot be applied to StaticTilemapLayers.
*
* @method Phaser.Tilemaps.Tilemap#copy
* @since 3.0.0
*
* @param {number} srcTileX - The x coordinate of the area to copy from, in tiles, not pixels.
* @param {number} srcTileY - The y coordinate of the area to copy from, in tiles, not pixels.
* @param {number} width - The width of the area to copy, in tiles, not pixels.
* @param {number} height - The height of the area to copy, in tiles, not pixels.
* @param {number} destTileX - The x coordinate of the area to copy to, in tiles, not pixels.
* @param {number} destTileY - The y coordinate of the area to copy to, in tiles, not pixels.
* @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid.
*/
copy: function(srcTileX, srcTileY, width, height, destTileX, destTileY, recalculateFaces, layer) {
layer = this.getLayer(layer);
if (layer !== null) {
TilemapComponents.Copy(
srcTileX,
srcTileY,
width,
height,
destTileX,
destTileY,
recalculateFaces,
layer
);
return this;
} else {
return null;
}
},
/**
* Creates a new and empty Tilemap Layer. The currently selected layer in the map is set to this new layer.
*
* Prior to v3.50.0 this method was called `createBlankDynamicLayer`.
*
* @method Phaser.Tilemaps.Tilemap#createBlankLayer
* @since 3.0.0
*
* @param {string} name - The name of this layer. Must be unique within the map.
* @param {(string|string[]|Phaser.Tilemaps.Tileset|Phaser.Tilemaps.Tileset[])} tileset - The tileset, or an array of tilesets, used to render this layer. Can be a string or a Tileset object.
* @param {number} [x=0] - The world x position where the top left of this layer will be placed.
* @param {number} [y=0] - The world y position where the top left of this layer will be placed.
* @param {number} [width] - The width of the layer in tiles. If not specified, it will default to the map's width.
* @param {number} [height] - The height of the layer in tiles. If not specified, it will default to the map's height.
* @param {number} [tileWidth] - The width of the tiles the layer uses for calculations. If not specified, it will default to the map's tileWidth.
* @param {number} [tileHeight] - The height of the tiles the layer uses for calculations. If not specified, it will default to the map's tileHeight.
*
* @return {?Phaser.Tilemaps.TilemapLayer} Returns the new layer that was created, or `null` if it failed.
*/
createBlankLayer: function(name, tileset, x, y, width, height, tileWidth, tileHeight) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (width === void 0) {
width = this.width;
}
if (height === void 0) {
height = this.height;
}
if (tileWidth === void 0) {
tileWidth = this.tileWidth;
}
if (tileHeight === void 0) {
tileHeight = this.tileHeight;
}
var index = this.getLayerIndex(name);
if (index !== null) {
console.warn("Invalid Tilemap Layer ID: " + name);
return null;
}
var layerData = new LayerData({
name,
tileWidth,
tileHeight,
width,
height,
orientation: this.orientation
});
var row;
for (var tileY = 0; tileY < height; tileY++) {
row = [];
for (var tileX = 0; tileX < width; tileX++) {
row.push(new Tile(layerData, -1, tileX, tileY, tileWidth, tileHeight, this.tileWidth, this.tileHeight));
}
layerData.data.push(row);
}
this.layers.push(layerData);
this.currentLayerIndex = this.layers.length - 1;
var layer = new TilemapLayer(this.scene, this, this.currentLayerIndex, tileset, x, y);
layer.setRenderOrder(this.renderOrder);
this.scene.sys.displayList.add(layer);
return layer;
},
/**
* Creates a new Tilemap Layer that renders the LayerData associated with the given
* `layerID`. The currently selected layer in the map is set to this new layer.
*
* The `layerID` is important. If you've created your map in Tiled then you can get this by
* looking in Tiled and looking at the layer name. Or you can open the JSON file it exports and
* look at the layers[].name value. Either way it must match.
*
* Prior to v3.50.0 this method was called `createDynamicLayer`.
*
* @method Phaser.Tilemaps.Tilemap#createLayer
* @since 3.0.0
*
* @param {(number|string)} layerID - The layer array index value, or if a string is given, the layer name from Tiled.
* @param {(string|string[]|Phaser.Tilemaps.Tileset|Phaser.Tilemaps.Tileset[])} tileset - The tileset, or an array of tilesets, used to render this layer. Can be a string or a Tileset object.
* @param {number} [x=0] - The x position to place the layer in the world. If not specified, it will default to the layer offset from Tiled or 0.
* @param {number} [y=0] - The y position to place the layer in the world. If not specified, it will default to the layer offset from Tiled or 0.
*
* @return {?Phaser.Tilemaps.TilemapLayer} Returns the new layer was created, or null if it failed.
*/
createLayer: function(layerID, tileset, x, y) {
var index = this.getLayerIndex(layerID);
if (index === null) {
console.warn("Invalid Tilemap Layer ID: " + layerID);
if (typeof layerID === "string") {
console.warn("Valid tilelayer names: %o", this.getTileLayerNames());
}
return null;
}
var layerData = this.layers[index];
if (layerData.tilemapLayer) {
console.warn("Tilemap Layer ID already exists:" + layerID);
return null;
}
this.currentLayerIndex = index;
if (x === void 0) {
x = layerData.x;
}
if (y === void 0) {
y = layerData.y;
}
var layer = new TilemapLayer(this.scene, this, index, tileset, x, y);
layer.setRenderOrder(this.renderOrder);
this.scene.sys.displayList.add(layer);
return layer;
},
/**
* This method will iterate through all of the objects defined in a Tiled Object Layer and then
* convert the matching results into Phaser Game Objects (by default, Sprites)
*
* Objects are matched on one of 4 criteria: The Object ID, the Object GID, the Object Name, or the Object Type.
*
* Within Tiled, Object IDs are unique per Object. Object GIDs, however, are shared by all objects
* using the same image. Finally, Object Names and Types are strings and the same name can be used on multiple
* Objects in Tiled, they do not have to be unique; Names are specific to Objects while Types can be inherited
* from Object GIDs using the same image.
*
* You set the configuration parameter accordingly, based on which type of criteria you wish
* to match against. For example, to convert all items on an Object Layer with a `gid` of 26:
*
* ```javascript
* createFromObjects(layerName, {
* gid: 26
* });
* ```
*
* Or, to convert objects with the name 'bonus':
*
* ```javascript
* createFromObjects(layerName, {
* name: 'bonus'
* });
* ```
*
* Or, to convert an object with a specific id:
*
* ```javascript
* createFromObjects(layerName, {
* id: 9
* });
* ```
*
* You should only specify either `id`, `gid`, `name`, `type`, or none of them. Do not add more than
* one criteria to your config. If you do not specify any criteria, then _all_ objects in the
* Object Layer will be converted.
*
* By default this method will convert Objects into {@link Phaser.GameObjects.Sprite} instances, but you can override
* this by providing your own class type:
*
* ```javascript
* createFromObjects(layerName, {
* gid: 26,
* classType: Coin
* });
* ```
*
* This will convert all Objects with a gid of 26 into your custom `Coin` class. You can pass
* any class type here, but it _must_ extend {@link Phaser.GameObjects.GameObject} as its base class.
* Your class will always be passed 1 parameter: `scene`, which is a reference to either the Scene
* specified in the config object or, if not given, the Scene to which this Tilemap belongs. The
* class must have {@link Phaser.GameObjects.Components.Transform#setPosition setPosition} and
* {@link Phaser.GameObjects.Components.Texture#setTexture setTexture} methods.
*
* This method will set the following Tiled Object properties on the new Game Object:
*
* - `flippedHorizontal` as `flipX`
* - `flippedVertical` as `flipY`
* - `height` as `displayHeight`
* - `name`
* - `rotation`
* - `visible`
* - `width` as `displayWidth`
* - `x`, adjusted for origin
* - `y`, adjusted for origin
*
* Additionally, this method will set Tiled Object custom properties
*
* - on the Game Object, if it has the same property name and a value that isn't `undefined`; or
* - on the Game Object's {@link Phaser.GameObjects.GameObject#data data store} otherwise.
*
* For example, a Tiled Object with custom properties `{ alpha: 0.5, gold: 1 }` will be created as a Game
* Object with an `alpha` value of 0.5 and a `data.values.gold` value of 1.
*
* When `useTileset` is `true` (the default), Tile Objects will inherit the texture and any tile properties
* from the tileset, and the local tile ID will be used as the texture frame. For the frame selection to work
* you need to load the tileset texture as a spritesheet so its frame names match the local tile IDs.
*
* For instance, a tileset tile
*
* ```
* { id: 3, type: 'treadmill', speed: 4 }
* ```
*
* with gid 19 and an object
*
* ```
* { id: 7, gid: 19, speed: 5, rotation: 90 }
* ```
*
* will be interpreted as
*
* ```
* { id: 7, gid: 19, speed: 5, rotation: 90, type: 'treadmill', texture: '[the tileset texture]', frame: 3 }
* ```
*
* You can suppress this behavior by setting the boolean `ignoreTileset` for each `config` that should ignore
* object gid tilesets.
*
* You can set a `container` property in the config. If given, the new Game Object will be added to
* the Container or Layer instance instead of the Scene.
*
* You can set named texture-`key` and texture-`frame` properties, which will be set on the new Game Object.
*
* Finally, you can provide an array of config objects, to convert multiple types of object in
* a single call:
*
* ```javascript
* createFromObjects(layerName, [
* {
* gid: 26,
* classType: Coin
* },
* {
* id: 9,
* classType: BossMonster
* },
* {
* name: 'lava',
* classType: LavaTile
* },
* {
* type: 'endzone',
* classType: Phaser.GameObjects.Zone
* }
* ]);
* ```
*
* The signature of this method changed significantly in v3.60.0. Prior to this, it did not take config objects.
*
* @method Phaser.Tilemaps.Tilemap#createFromObjects
* @since 3.0.0
*
* @param {string} objectLayerName - The name of the Tiled object layer to create the Game Objects from.
* @param {Phaser.Types.Tilemaps.CreateFromObjectLayerConfig|Phaser.Types.Tilemaps.CreateFromObjectLayerConfig[]} config - A CreateFromObjects configuration object, or an array of them.
* @param {boolean} [useTileset=true] - True if objects that set gids should also search the underlying tile for properties and data.
*
* @return {Phaser.GameObjects.GameObject[]} An array containing the Game Objects that were created. Empty if invalid object layer, or no matching id/gid/name was found.
*/
createFromObjects: function(objectLayerName, config, useTileset) {
if (useTileset === void 0) {
useTileset = true;
}
var results = [];
var objectLayer = this.getObjectLayer(objectLayerName);
if (!objectLayer) {
console.warn("createFromObjects: Invalid objectLayerName given: " + objectLayerName);
return results;
}
var objectHelper = new ObjectHelper(useTileset ? this.tilesets : void 0);
if (!Array.isArray(config)) {
config = [config];
}
var objects = objectLayer.objects;
for (var c = 0; c < config.length; c++) {
var singleConfig = config[c];
var id = GetFastValue(singleConfig, "id", null);
var gid = GetFastValue(singleConfig, "gid", null);
var name = GetFastValue(singleConfig, "name", null);
var type = GetFastValue(singleConfig, "type", null);
objectHelper.enabled = !GetFastValue(singleConfig, "ignoreTileset", null);
var obj;
var toConvert = [];
for (var s = 0; s < objects.length; s++) {
obj = objects[s];
if (id === null && gid === null && name === null && type === null || id !== null && obj.id === id || gid !== null && obj.gid === gid || name !== null && obj.name === name || type !== null && objectHelper.getTypeIncludingTile(obj) === type) {
toConvert.push(obj);
}
}
var classType = GetFastValue(singleConfig, "classType", Sprite);
var scene = GetFastValue(singleConfig, "scene", this.scene);
var container = GetFastValue(singleConfig, "container", null);
var texture = GetFastValue(singleConfig, "key", null);
var frame = GetFastValue(singleConfig, "frame", null);
for (var i = 0; i < toConvert.length; i++) {
obj = toConvert[i];
var sprite = new classType(scene);
sprite.setName(obj.name);
sprite.setPosition(obj.x, obj.y);
objectHelper.setTextureAndFrame(sprite, texture, frame, obj);
if (obj.width) {
sprite.displayWidth = obj.width;
}
if (obj.height) {
sprite.displayHeight = obj.height;
}
if (this.orientation === ORIENTATION.ISOMETRIC) {
var isometricRatio = this.tileWidth / this.tileHeight;
var isometricPosition = {
x: sprite.x - sprite.y,
y: (sprite.x + sprite.y) / isometricRatio
};
sprite.x = isometricPosition.x;
sprite.y = isometricPosition.y;
}
var offset = {
x: sprite.originX * obj.width,
y: (sprite.originY - (obj.gid ? 1 : 0)) * obj.height
};
if (obj.rotation) {
var angle = DegToRad(obj.rotation);
Rotate(offset, angle);
sprite.rotation = angle;
}
sprite.x += offset.x;
sprite.y += offset.y;
if (obj.flippedHorizontal !== void 0 || obj.flippedVertical !== void 0) {
sprite.setFlip(obj.flippedHorizontal, obj.flippedVertical);
}
if (!obj.visible) {
sprite.visible = false;
}
objectHelper.setPropertiesFromTiledObject(sprite, obj);
if (container) {
container.add(sprite);
} else {
scene.add.existing(sprite);
}
results.push(sprite);
}
}
return results;
},
/**
* Creates a Sprite for every tile matching the given tile indexes in the layer. You can
* optionally specify if each tile will be replaced with a new tile after the Sprite has been
* created. Set this value to -1 if you want to just remove the tile after conversion.
*
* This is useful if you want to lay down special tiles in a level that are converted to
* Sprites, but want to replace the tile itself with a floor tile or similar once converted.
*
* The following features were added in Phaser v3.80:
*
* By default, Phaser Sprites have their origin set to 0.5 x 0.5. If you don't specify a new
* origin in the spriteConfig, then it will adjust the sprite positions by half the tile size,
* to position them accurately on the map.
*
* When the Sprite is created it will copy the following properties from the tile:
*
* 'rotation', 'flipX', 'flipY', 'alpha', 'visible' and 'tint'.
*
* The spriteConfig also has a special property called `useSpriteSheet`. If this is set to
* `true` and you have loaded the tileset as a sprite sheet (not an image), then it will
* set the Sprite key and frame to match the sprite texture and tile index.
*
* @method Phaser.Tilemaps.Tilemap#createFromTiles
* @since 3.0.0
*
* @param {(number|array)} indexes - The tile index, or array of indexes, to create Sprites from.
* @param {?(number|array)} replacements - The tile index, or array of indexes, to change a converted
* tile to. Set to `null` to leave the tiles unchanged. If an array is given, it is assumed to be a
* one-to-one mapping with the indexes array.
* @param {Phaser.Types.GameObjects.Sprite.SpriteConfig} [spriteConfig] - The config object to pass into the Sprite creator (i.e. scene.make.sprite).
* @param {Phaser.Scene} [scene] - The Scene to create the Sprites within.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.GameObjects.Sprite[]} Returns an array of Tiles, or null if the layer given was invalid.
*/
createFromTiles: function(indexes, replacements, spriteConfig, scene, camera, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
return TilemapComponents.CreateFromTiles(indexes, replacements, spriteConfig, scene, camera, layer);
},
/**
* Sets the tiles in the given rectangular area (in tile coordinates) of the layer with the
* specified index. Tiles will be set to collide if the given index is a colliding index.
* Collision information in the region will be recalculated.
*
* If no layer specified, the map's current layer is used.
* This cannot be applied to StaticTilemapLayers.
*
* @method Phaser.Tilemaps.Tilemap#fill
* @since 3.0.0
*
* @param {number} index - The tile index to fill the area with.
* @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [width] - How many tiles wide from the `tileX` index the area will be.
* @param {number} [height] - How many tiles tall from the `tileY` index the area will be.
* @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid.
*/
fill: function(index, tileX, tileY, width, height, recalculateFaces, layer) {
if (recalculateFaces === void 0) {
recalculateFaces = true;
}
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
TilemapComponents.Fill(index, tileX, tileY, width, height, recalculateFaces, layer);
return this;
},
/**
* For each object in the given object layer, run the given filter callback function. Any
* objects that pass the filter test (i.e. where the callback returns true) will be returned in a
* new array. Similar to Array.prototype.Filter in vanilla JS.
*
* @method Phaser.Tilemaps.Tilemap#filterObjects
* @since 3.0.0
*
* @param {(Phaser.Tilemaps.ObjectLayer|string)} objectLayer - The name of an object layer (from Tiled) or an ObjectLayer instance.
* @param {TilemapFilterCallback} callback - The callback. Each object in the given area will be passed to this callback as the first and only parameter.
* @param {object} [context] - The context under which the callback should be run.
*
* @return {?Phaser.Types.Tilemaps.TiledObject[]} An array of object that match the search, or null if the objectLayer given was invalid.
*/
filterObjects: function(objectLayer, callback, context) {
if (typeof objectLayer === "string") {
var name = objectLayer;
objectLayer = this.getObjectLayer(objectLayer);
if (!objectLayer) {
console.warn("No object layer found with the name: " + name);
return null;
}
}
return objectLayer.objects.filter(callback, context);
},
/**
* For each tile in the given rectangular area (in tile coordinates) of the layer, run the given
* filter callback function. Any tiles that pass the filter test (i.e. where the callback returns
* true) will returned as a new array. Similar to Array.prototype.Filter in vanilla JS.
* If no layer specified, the map's current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#filterTiles
* @since 3.0.0
*
* @param {function} callback - The callback. Each tile in the given area will be passed to this
* callback as the first and only parameter. The callback should return true for tiles that pass the
* filter.
* @param {object} [context] - The context under which the callback should be run.
* @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to filter.
* @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to filter.
* @param {number} [width] - How many tiles wide from the `tileX` index the area will be.
* @param {number} [height] - How many tiles tall from the `tileY` index the area will be.
* @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tile[]} Returns an array of Tiles, or null if the layer given was invalid.
*/
filterTiles: function(callback, context, tileX, tileY, width, height, filteringOptions, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
return TilemapComponents.FilterTiles(callback, context, tileX, tileY, width, height, filteringOptions, layer);
},
/**
* Searches the entire map layer for the first tile matching the given index, then returns that Tile
* object. If no match is found, it returns null. The search starts from the top-left tile and
* continues horizontally until it hits the end of the row, then it drops down to the next column.
* If the reverse boolean is true, it scans starting from the bottom-right corner traveling up to
* the top-left.
* If no layer specified, the map's current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#findByIndex
* @since 3.0.0
*
* @param {number} index - The tile index value to search for.
* @param {number} [skip=0] - The number of times to skip a matching tile before returning.
* @param {boolean} [reverse=false] - If true it will scan the layer in reverse, starting at the bottom-right. Otherwise it scans from the top-left.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tile} Returns a Tiles, or null if the layer given was invalid.
*/
findByIndex: function(findIndex, skip, reverse, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
return TilemapComponents.FindByIndex(findIndex, skip, reverse, layer);
},
/**
* Find the first object in the given object layer that satisfies the provided testing function.
* I.e. finds the first object for which `callback` returns true. Similar to
* Array.prototype.find in vanilla JS.
*
* @method Phaser.Tilemaps.Tilemap#findObject
* @since 3.0.0
*
* @param {(Phaser.Tilemaps.ObjectLayer|string)} objectLayer - The name of an object layer (from Tiled) or an ObjectLayer instance.
* @param {TilemapFindCallback} callback - The callback. Each object in the given area will be passed to this callback as the first and only parameter.
* @param {object} [context] - The context under which the callback should be run.
*
* @return {?Phaser.Types.Tilemaps.TiledObject} An object that matches the search, or null if no object found.
*/
findObject: function(objectLayer, callback, context) {
if (typeof objectLayer === "string") {
var name = objectLayer;
objectLayer = this.getObjectLayer(objectLayer);
if (!objectLayer) {
console.warn("No object layer found with the name: " + name);
return null;
}
}
return objectLayer.objects.find(callback, context) || null;
},
/**
* Find the first tile in the given rectangular area (in tile coordinates) of the layer that
* satisfies the provided testing function. I.e. finds the first tile for which `callback` returns
* true. Similar to Array.prototype.find in vanilla JS.
* If no layer specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#findTile
* @since 3.0.0
*
* @param {FindTileCallback} callback - The callback. Each tile in the given area will be passed to this callback as the first and only parameter.
* @param {object} [context] - The context under which the callback should be run.
* @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to search.
* @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to search.
* @param {number} [width] - How many tiles wide from the `tileX` index the area will be.
* @param {number} [height] - How many tiles tall from the `tileY` index the area will be.
* @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The Tile layer to run the search on. If not provided will use the current layer.
*
* @return {?Phaser.Tilemaps.Tile} Returns a Tiles, or null if the layer given was invalid.
*/
findTile: function(callback, context, tileX, tileY, width, height, filteringOptions, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
return TilemapComponents.FindTile(callback, context, tileX, tileY, width, height, filteringOptions, layer);
},
/**
* For each tile in the given rectangular area (in tile coordinates) of the layer, run the given
* callback. Similar to Array.prototype.forEach in vanilla JS.
*
* If no layer specified, the map's current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#forEachTile
* @since 3.0.0
*
* @param {EachTileCallback} callback - The callback. Each tile in the given area will be passed to this callback as the first and only parameter.
* @param {object} [context] - The context under which the callback should be run.
* @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to search.
* @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to search.
* @param {number} [width] - How many tiles wide from the `tileX` index the area will be.
* @param {number} [height] - How many tiles tall from the `tileY` index the area will be.
* @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The Tile layer to run the search on. If not provided will use the current layer.
*
* @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid.
*/
forEachTile: function(callback, context, tileX, tileY, width, height, filteringOptions, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
TilemapComponents.ForEachTile(callback, context, tileX, tileY, width, height, filteringOptions, layer);
return this;
},
/**
* Gets the image layer index based on its name.
*
* @method Phaser.Tilemaps.Tilemap#getImageIndex
* @since 3.0.0
*
* @param {string} name - The name of the image to get.
*
* @return {number} The index of the image in this tilemap, or null if not found.
*/
getImageIndex: function(name) {
return this.getIndex(this.images, name);
},
/**
* Return a list of all valid imagelayer names loaded in this Tilemap.
*
* @method Phaser.Tilemaps.Tilemap#getImageLayerNames
* @since 3.21.0
*
* @return {string[]} Array of valid imagelayer names / IDs loaded into this Tilemap.
*/
getImageLayerNames: function() {
if (!this.images || !Array.isArray(this.images)) {
return [];
}
return this.images.map(function(image) {
return image.name;
});
},
/**
* Internally used. Returns the index of the object in one of the Tilemaps arrays whose name
* property matches the given `name`.
*
* @method Phaser.Tilemaps.Tilemap#getIndex
* @since 3.0.0
*
* @param {array} location - The Tilemap array to search.
* @param {string} name - The name of the array element to get.
*
* @return {number} The index of the element in the array, or null if not found.
*/
getIndex: function(location, name) {
for (var i = 0; i < location.length; i++) {
if (location[i].name === name) {
return i;
}
}
return null;
},
/**
* Gets the LayerData from `this.layers` that is associated with the given `layer`, or null if the layer is invalid.
*
* @method Phaser.Tilemaps.Tilemap#getLayer
* @since 3.0.0
*
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The name of the layer from Tiled, the index of the layer in the map or Tilemap Layer. If not given will default to the maps current layer index.
*
* @return {?Phaser.Tilemaps.LayerData} The corresponding `LayerData` within `this.layers`, or null.
*/
getLayer: function(layer) {
var index = this.getLayerIndex(layer);
return index !== null ? this.layers[index] : null;
},
/**
* Gets the ObjectLayer from `this.objects` that has the given `name`, or null if no ObjectLayer is found with that name.
*
* @method Phaser.Tilemaps.Tilemap#getObjectLayer
* @since 3.0.0
*
* @param {string} [name] - The name of the object layer from Tiled.
*
* @return {?Phaser.Tilemaps.ObjectLayer} The corresponding `ObjectLayer` within `this.objects`, or null.
*/
getObjectLayer: function(name) {
var index = this.getIndex(this.objects, name);
return index !== null ? this.objects[index] : null;
},
/**
* Return a list of all valid objectgroup names loaded in this Tilemap.
*
* @method Phaser.Tilemaps.Tilemap#getObjectLayerNames
* @since 3.21.0
*
* @return {string[]} Array of valid objectgroup names / IDs loaded into this Tilemap.
*/
getObjectLayerNames: function() {
if (!this.objects || !Array.isArray(this.objects)) {
return [];
}
return this.objects.map(function(object) {
return object.name;
});
},
/**
* Gets the LayerData index of the given `layer` within this.layers, or null if an invalid
* `layer` is given.
*
* @method Phaser.Tilemaps.Tilemap#getLayerIndex
* @since 3.0.0
*
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The name of the layer from Tiled, the index of the layer in the map or a Tilemap Layer. If not given will default to the map's current layer index.
*
* @return {number} The LayerData index within this.layers.
*/
getLayerIndex: function(layer) {
if (layer === void 0) {
return this.currentLayerIndex;
} else if (typeof layer === "string") {
return this.getLayerIndexByName(layer);
} else if (typeof layer === "number" && layer < this.layers.length) {
return layer;
} else if (layer instanceof TilemapLayer && layer.tilemap === this) {
return layer.layerIndex;
} else {
return null;
}
},
/**
* Gets the index of the LayerData within this.layers that has the given `name`, or null if an
* invalid `name` is given.
*
* @method Phaser.Tilemaps.Tilemap#getLayerIndexByName
* @since 3.0.0
*
* @param {string} name - The name of the layer to get.
*
* @return {number} The LayerData index within this.layers.
*/
getLayerIndexByName: function(name) {
return this.getIndex(this.layers, name);
},
/**
* Gets a tile at the given tile coordinates from the given layer.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#getTileAt
* @since 3.0.0
*
* @param {number} tileX - X position to get the tile from (given in tile units, not pixels).
* @param {number} tileY - Y position to get the tile from (given in tile units, not pixels).
* @param {boolean} [nonNull=false] - For empty tiles, return a Tile object with an index of -1 instead of null.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid.
*/
getTileAt: function(tileX, tileY, nonNull, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
return TilemapComponents.GetTileAt(tileX, tileY, nonNull, layer);
},
/**
* Gets a tile at the given world coordinates from the given layer.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#getTileAtWorldXY
* @since 3.0.0
*
* @param {number} worldX - X position to get the tile from (given in pixels)
* @param {number} worldY - Y position to get the tile from (given in pixels)
* @param {boolean} [nonNull=false] - For empty tiles, return a Tile object with an index of -1 instead of null.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid.
*/
getTileAtWorldXY: function(worldX, worldY, nonNull, camera, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
return TilemapComponents.GetTileAtWorldXY(worldX, worldY, nonNull, camera, layer);
},
/**
* Return a list of all valid tilelayer names loaded in this Tilemap.
*
* @method Phaser.Tilemaps.Tilemap#getTileLayerNames
* @since 3.21.0
*
* @return {string[]} Array of valid tilelayer names / IDs loaded into this Tilemap.
*/
getTileLayerNames: function() {
if (!this.layers || !Array.isArray(this.layers)) {
return [];
}
return this.layers.map(function(layer) {
return layer.name;
});
},
/**
* Gets the tiles in the given rectangular area (in tile coordinates) of the layer.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#getTilesWithin
* @since 3.0.0
*
* @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [width] - How many tiles wide from the `tileX` index the area will be.
* @param {number} [height] - How many tiles tall from the `tileY` index the area will be.
* @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tile[]} Returns an array of Tiles, or null if the layer given was invalid.
*/
getTilesWithin: function(tileX, tileY, width, height, filteringOptions, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
return TilemapComponents.GetTilesWithin(tileX, tileY, width, height, filteringOptions, layer);
},
/**
* Gets the tiles that overlap with the given shape in the given layer. The shape must be a Circle,
* Line, Rectangle or Triangle. The shape should be in world coordinates.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#getTilesWithinShape
* @since 3.0.0
*
* @param {(Phaser.Geom.Circle|Phaser.Geom.Line|Phaser.Geom.Rectangle|Phaser.Geom.Triangle)} shape - A shape in world (pixel) coordinates
* @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tile[]} Returns an array of Tiles, or null if the layer given was invalid.
*/
getTilesWithinShape: function(shape, filteringOptions, camera, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
return TilemapComponents.GetTilesWithinShape(shape, filteringOptions, camera, layer);
},
/**
* Gets the tiles in the given rectangular area (in world coordinates) of the layer.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#getTilesWithinWorldXY
* @since 3.0.0
*
* @param {number} worldX - The world x coordinate for the top-left of the area.
* @param {number} worldY - The world y coordinate for the top-left of the area.
* @param {number} width - The width of the area.
* @param {number} height - The height of the area.
* @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tile[]} Returns an array of Tiles, or null if the layer given was invalid.
*/
getTilesWithinWorldXY: function(worldX, worldY, width, height, filteringOptions, camera, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
return TilemapComponents.GetTilesWithinWorldXY(worldX, worldY, width, height, filteringOptions, camera, layer);
},
/**
* Gets the Tileset that has the given `name`, or null if an invalid `name` is given.
*
* @method Phaser.Tilemaps.Tilemap#getTileset
* @since 3.14.0
*
* @param {string} name - The name of the Tileset to get.
*
* @return {?Phaser.Tilemaps.Tileset} The Tileset, or `null` if no matching named tileset was found.
*/
getTileset: function(name) {
var index = this.getIndex(this.tilesets, name);
return index !== null ? this.tilesets[index] : null;
},
/**
* Gets the index of the Tileset within this.tilesets that has the given `name`, or null if an
* invalid `name` is given.
*
* @method Phaser.Tilemaps.Tilemap#getTilesetIndex
* @since 3.0.0
*
* @param {string} name - The name of the Tileset to get.
*
* @return {number} The Tileset index within this.tilesets.
*/
getTilesetIndex: function(name) {
return this.getIndex(this.tilesets, name);
},
/**
* Checks if there is a tile at the given location (in tile coordinates) in the given layer. Returns
* false if there is no tile or if the tile at that location has an index of -1.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#hasTileAt
* @since 3.0.0
*
* @param {number} tileX - The x coordinate, in tiles, not pixels.
* @param {number} tileY - The y coordinate, in tiles, not pixels.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?boolean} Returns a boolean, or null if the layer given was invalid.
*/
hasTileAt: function(tileX, tileY, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
return TilemapComponents.HasTileAt(tileX, tileY, layer);
},
/**
* Checks if there is a tile at the given location (in world coordinates) in the given layer. Returns
* false if there is no tile or if the tile at that location has an index of -1.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#hasTileAtWorldXY
* @since 3.0.0
*
* @param {number} worldX - The x coordinate, in pixels.
* @param {number} worldY - The y coordinate, in pixels.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?boolean} Returns a boolean, or null if the layer given was invalid.
*/
hasTileAtWorldXY: function(worldX, worldY, camera, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
return TilemapComponents.HasTileAtWorldXY(worldX, worldY, camera, layer);
},
/**
* The LayerData object that is currently selected in the map. You can set this property using
* any type supported by setLayer.
*
* @name Phaser.Tilemaps.Tilemap#layer
* @type {Phaser.Tilemaps.LayerData}
* @since 3.0.0
*/
layer: {
get: function() {
return this.layers[this.currentLayerIndex];
},
set: function(layer) {
this.setLayer(layer);
}
},
/**
* Puts a tile at the given tile coordinates in the specified layer. You can pass in either an index
* or a Tile object. If you pass in a Tile, all attributes will be copied over to the specified
* location. If you pass in an index, only the index at the specified location will be changed.
* Collision information will be recalculated at the specified location.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#putTileAt
* @since 3.0.0
*
* @param {(number|Phaser.Tilemaps.Tile)} tile - The index of this tile to set or a Tile object.
* @param {number} tileX - The x coordinate, in tiles, not pixels.
* @param {number} tileY - The y coordinate, in tiles, not pixels.
* @param {boolean} [recalculateFaces] - `true` if the faces data should be recalculated.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid or the coordinates were out of bounds.
*/
putTileAt: function(tile, tileX, tileY, recalculateFaces, layer) {
if (recalculateFaces === void 0) {
recalculateFaces = true;
}
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
return TilemapComponents.PutTileAt(tile, tileX, tileY, recalculateFaces, layer);
},
/**
* Puts a tile at the given world coordinates (pixels) in the specified layer. You can pass in either
* an index or a Tile object. If you pass in a Tile, all attributes will be copied over to the
* specified location. If you pass in an index, only the index at the specified location will be
* changed. Collision information will be recalculated at the specified location.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#putTileAtWorldXY
* @since 3.0.0
*
* @param {(number|Phaser.Tilemaps.Tile)} tile - The index of this tile to set or a Tile object.
* @param {number} worldX - The x coordinate, in pixels.
* @param {number} worldY - The y coordinate, in pixels.
* @param {boolean} [recalculateFaces] - `true` if the faces data should be recalculated.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid.
*/
putTileAtWorldXY: function(tile, worldX, worldY, recalculateFaces, camera, layer) {
if (recalculateFaces === void 0) {
recalculateFaces = true;
}
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
return TilemapComponents.PutTileAtWorldXY(tile, worldX, worldY, recalculateFaces, camera, layer);
},
/**
* Puts an array of tiles or a 2D array of tiles at the given tile coordinates in the specified
* layer. The array can be composed of either tile indexes or Tile objects. If you pass in a Tile,
* all attributes will be copied over to the specified location. If you pass in an index, only the
* index at the specified location will be changed. Collision information will be recalculated
* within the region tiles were changed.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#putTilesAt
* @since 3.0.0
*
* @param {(number[]|number[][]|Phaser.Tilemaps.Tile[]|Phaser.Tilemaps.Tile[][])} tile - A row (array) or grid (2D array) of Tiles or tile indexes to place.
* @param {number} tileX - The x coordinate, in tiles, not pixels.
* @param {number} tileY - The y coordinate, in tiles, not pixels.
* @param {boolean} [recalculateFaces] - `true` if the faces data should be recalculated.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid.
*/
putTilesAt: function(tilesArray, tileX, tileY, recalculateFaces, layer) {
if (recalculateFaces === void 0) {
recalculateFaces = true;
}
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
TilemapComponents.PutTilesAt(tilesArray, tileX, tileY, recalculateFaces, layer);
return this;
},
/**
* Randomizes the indexes of a rectangular region of tiles (in tile coordinates) within the
* specified layer. Each tile will receive a new index. If an array of indexes is passed in, then
* those will be used for randomly assigning new tile indexes. If an array is not provided, the
* indexes found within the region (excluding -1) will be used for randomly assigning new tile
* indexes. This method only modifies tile indexes and does not change collision information.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#randomize
* @since 3.0.0
*
* @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [width] - How many tiles wide from the `tileX` index the area will be.
* @param {number} [height] - How many tiles tall from the `tileY` index the area will be.
* @param {number[]} [indexes] - An array of indexes to randomly draw from during randomization.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid.
*/
randomize: function(tileX, tileY, width, height, indexes, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
TilemapComponents.Randomize(tileX, tileY, width, height, indexes, layer);
return this;
},
/**
* Calculates interesting faces at the given tile coordinates of the specified layer. Interesting
* faces are used internally for optimizing collisions against tiles. This method is mostly used
* internally to optimize recalculating faces when only one tile has been changed.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#calculateFacesAt
* @since 3.0.0
*
* @param {number} tileX - The x coordinate, in tiles, not pixels.
* @param {number} tileY - The y coordinate, in tiles, not pixels.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid.
*/
calculateFacesAt: function(tileX, tileY, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
TilemapComponents.CalculateFacesAt(tileX, tileY, layer);
return this;
},
/**
* Calculates interesting faces within the rectangular area specified (in tile coordinates) of the
* layer. Interesting faces are used internally for optimizing collisions against tiles. This method
* is mostly used internally.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#calculateFacesWithin
* @since 3.0.0
*
* @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [width] - How many tiles wide from the `tileX` index the area will be.
* @param {number} [height] - How many tiles tall from the `tileY` index the area will be.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid.
*/
calculateFacesWithin: function(tileX, tileY, width, height, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
TilemapComponents.CalculateFacesWithin(tileX, tileY, width, height, layer);
return this;
},
/**
* Removes the given TilemapLayer from this Tilemap without destroying it.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#removeLayer
* @since 3.17.0
*
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to be removed.
*
* @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid.
*/
removeLayer: function(layer) {
var index = this.getLayerIndex(layer);
if (index !== null) {
SpliceOne(this.layers, index);
for (var i = index; i < this.layers.length; i++) {
if (this.layers[i].tilemapLayer) {
this.layers[i].tilemapLayer.layerIndex--;
}
}
if (this.currentLayerIndex === index) {
this.currentLayerIndex = 0;
}
return this;
} else {
return null;
}
},
/**
* Destroys the given TilemapLayer and removes it from this Tilemap.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#destroyLayer
* @since 3.17.0
*
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to be destroyed.
*
* @return {?Phaser.Tilemaps.Tilemap} Returns this, or null if the layer given was invalid.
*/
destroyLayer: function(layer) {
var index = this.getLayerIndex(layer);
if (index !== null) {
layer = this.layers[index];
layer.tilemapLayer.destroy();
SpliceOne(this.layers, index);
if (this.currentLayerIndex === index) {
this.currentLayerIndex = 0;
}
return this;
} else {
return null;
}
},
/**
* Removes all Tilemap Layers from this Tilemap and calls `destroy` on each of them.
*
* @method Phaser.Tilemaps.Tilemap#removeAllLayers
* @since 3.0.0
*
* @return {this} This Tilemap object.
*/
removeAllLayers: function() {
var layers = this.layers;
for (var i = 0; i < layers.length; i++) {
if (layers[i].tilemapLayer) {
layers[i].tilemapLayer.destroy(false);
}
}
layers.length = 0;
this.currentLayerIndex = 0;
return this;
},
/**
* Removes the given Tile, or an array of Tiles, from the layer to which they belong,
* and optionally recalculates the collision information.
*
* @method Phaser.Tilemaps.Tilemap#removeTile
* @since 3.17.0
*
* @param {(Phaser.Tilemaps.Tile|Phaser.Tilemaps.Tile[])} tiles - The Tile to remove, or an array of Tiles.
* @param {number} [replaceIndex=-1] - After removing the Tile, insert a brand new Tile into its location with the given index. Leave as -1 to just remove the tile.
* @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated.
*
* @return {Phaser.Tilemaps.Tile[]} Returns an array of Tiles that were removed.
*/
removeTile: function(tiles, replaceIndex, recalculateFaces) {
if (replaceIndex === void 0) {
replaceIndex = -1;
}
if (recalculateFaces === void 0) {
recalculateFaces = true;
}
var removed = [];
if (!Array.isArray(tiles)) {
tiles = [tiles];
}
for (var i = 0; i < tiles.length; i++) {
var tile = tiles[i];
removed.push(this.removeTileAt(tile.x, tile.y, true, recalculateFaces, tile.tilemapLayer));
if (replaceIndex > -1) {
this.putTileAt(replaceIndex, tile.x, tile.y, recalculateFaces, tile.tilemapLayer);
}
}
return removed;
},
/**
* Removes the tile at the given tile coordinates in the specified layer and updates the layers collision information.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#removeTileAt
* @since 3.0.0
*
* @param {number} tileX - The x coordinate, in tiles, not pixels.
* @param {number} tileY - The y coordinate, in tiles, not pixels.
* @param {boolean} [replaceWithNull] - If `true` (the default), this will replace the tile at the specified location with null instead of a Tile with an index of -1.
* @param {boolean} [recalculateFaces] - If `true` (the default), the faces data will be recalculated.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tile} Returns the Tile that was removed, or null if the layer given was invalid.
*/
removeTileAt: function(tileX, tileY, replaceWithNull, recalculateFaces, layer) {
if (replaceWithNull === void 0) {
replaceWithNull = true;
}
if (recalculateFaces === void 0) {
recalculateFaces = true;
}
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
return TilemapComponents.RemoveTileAt(tileX, tileY, replaceWithNull, recalculateFaces, layer);
},
/**
* Removes the tile at the given world coordinates in the specified layer and updates the layers collision information.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#removeTileAtWorldXY
* @since 3.0.0
*
* @param {number} worldX - The x coordinate, in pixels.
* @param {number} worldY - The y coordinate, in pixels.
* @param {boolean} [replaceWithNull] - If `true` (the default), this will replace the tile at the specified location with null instead of a Tile with an index of -1.
* @param {boolean} [recalculateFaces] - If `true` (the default), the faces data will be recalculated.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tile} Returns a Tile, or null if the layer given was invalid.
*/
removeTileAtWorldXY: function(worldX, worldY, replaceWithNull, recalculateFaces, camera, layer) {
if (replaceWithNull === void 0) {
replaceWithNull = true;
}
if (recalculateFaces === void 0) {
recalculateFaces = true;
}
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
return TilemapComponents.RemoveTileAtWorldXY(worldX, worldY, replaceWithNull, recalculateFaces, camera, layer);
},
/**
* Draws a debug representation of the layer to the given Graphics object. This is helpful when you want to
* get a quick idea of which of your tiles are colliding and which have interesting faces. The tiles
* are drawn starting at (0, 0) in the Graphics, allowing you to place the debug representation
* wherever you want on the screen.
*
* If no layer is specified, the maps current layer is used.
*
* **Note:** This method currently only works with orthogonal tilemap layers.
*
* @method Phaser.Tilemaps.Tilemap#renderDebug
* @since 3.0.0
*
* @param {Phaser.GameObjects.Graphics} graphics - The target Graphics object to draw upon.
* @param {Phaser.Types.Tilemaps.StyleConfig} [styleConfig] - An object specifying the colors to use for the debug drawing.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid.
*/
renderDebug: function(graphics, styleConfig, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
if (this.orientation === ORIENTATION.ORTHOGONAL) {
TilemapComponents.RenderDebug(graphics, styleConfig, layer);
}
return this;
},
/**
* Draws a debug representation of all layers within this Tilemap to the given Graphics object.
*
* This is helpful when you want to get a quick idea of which of your tiles are colliding and which
* have interesting faces. The tiles are drawn starting at (0, 0) in the Graphics, allowing you to
* place the debug representation wherever you want on the screen.
*
* @method Phaser.Tilemaps.Tilemap#renderDebugFull
* @since 3.17.0
*
* @param {Phaser.GameObjects.Graphics} graphics - The target Graphics object to draw upon.
* @param {Phaser.Types.Tilemaps.StyleConfig} [styleConfig] - An object specifying the colors to use for the debug drawing.
*
* @return {this} This Tilemap instance.
*/
renderDebugFull: function(graphics, styleConfig) {
var layers = this.layers;
for (var i = 0; i < layers.length; i++) {
TilemapComponents.RenderDebug(graphics, styleConfig, layers[i]);
}
return this;
},
/**
* Scans the given rectangular area (given in tile coordinates) for tiles with an index matching
* `findIndex` and updates their index to match `newIndex`. This only modifies the index and does
* not change collision information.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#replaceByIndex
* @since 3.0.0
*
* @param {number} findIndex - The index of the tile to search for.
* @param {number} newIndex - The index of the tile to replace it with.
* @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [width] - How many tiles wide from the `tileX` index the area will be.
* @param {number} [height] - How many tiles tall from the `tileY` index the area will be.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid.
*/
replaceByIndex: function(findIndex, newIndex, tileX, tileY, width, height, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
TilemapComponents.ReplaceByIndex(findIndex, newIndex, tileX, tileY, width, height, layer);
return this;
},
/**
* Sets collision on the given tile or tiles within a layer by index. You can pass in either a
* single numeric index or an array of indexes: [2, 3, 15, 20]. The `collides` parameter controls if
* collision will be enabled (true) or disabled (false).
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#setCollision
* @since 3.0.0
*
* @param {(number|array)} indexes - Either a single tile index, or an array of tile indexes.
* @param {boolean} [collides] - If true it will enable collision. If false it will clear collision.
* @param {boolean} [recalculateFaces] - Whether or not to recalculate the tile faces after the update.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
* @param {boolean} [updateLayer=true] - If true, updates the current tiles on the layer. Set to false if no tiles have been placed for significant performance boost.
*
* @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid.
*/
setCollision: function(indexes, collides, recalculateFaces, layer, updateLayer) {
if (collides === void 0) {
collides = true;
}
if (recalculateFaces === void 0) {
recalculateFaces = true;
}
if (updateLayer === void 0) {
updateLayer = true;
}
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
TilemapComponents.SetCollision(indexes, collides, recalculateFaces, layer, updateLayer);
return this;
},
/**
* Sets collision on a range of tiles in a layer whose index is between the specified `start` and
* `stop` (inclusive). Calling this with a start value of 10 and a stop value of 14 would set
* collision for tiles 10, 11, 12, 13 and 14. The `collides` parameter controls if collision will be
* enabled (true) or disabled (false).
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#setCollisionBetween
* @since 3.0.0
*
* @param {number} start - The first index of the tile to be set for collision.
* @param {number} stop - The last index of the tile to be set for collision.
* @param {boolean} [collides] - If true it will enable collision. If false it will clear collision.
* @param {boolean} [recalculateFaces] - Whether or not to recalculate the tile faces after the update.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid.
*/
setCollisionBetween: function(start, stop, collides, recalculateFaces, layer) {
if (collides === void 0) {
collides = true;
}
if (recalculateFaces === void 0) {
recalculateFaces = true;
}
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
TilemapComponents.SetCollisionBetween(start, stop, collides, recalculateFaces, layer);
return this;
},
/**
* Sets collision on the tiles within a layer by checking tile properties. If a tile has a property
* that matches the given properties object, its collision flag will be set. The `collides`
* parameter controls if collision will be enabled (true) or disabled (false). Passing in
* `{ collides: true }` would update the collision flag on any tiles with a "collides" property that
* has a value of true. Any tile that doesn't have "collides" set to true will be ignored. You can
* also use an array of values, e.g. `{ types: ["stone", "lava", "sand" ] }`. If a tile has a
* "types" property that matches any of those values, its collision flag will be updated.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#setCollisionByProperty
* @since 3.0.0
*
* @param {object} properties - An object with tile properties and corresponding values that should be checked.
* @param {boolean} [collides] - If true it will enable collision. If false it will clear collision.
* @param {boolean} [recalculateFaces] - Whether or not to recalculate the tile faces after the update.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid.
*/
setCollisionByProperty: function(properties, collides, recalculateFaces, layer) {
if (collides === void 0) {
collides = true;
}
if (recalculateFaces === void 0) {
recalculateFaces = true;
}
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
TilemapComponents.SetCollisionByProperty(properties, collides, recalculateFaces, layer);
return this;
},
/**
* Sets collision on all tiles in the given layer, except for tiles that have an index specified in
* the given array. The `collides` parameter controls if collision will be enabled (true) or
* disabled (false). Tile indexes not currently in the layer are not affected.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#setCollisionByExclusion
* @since 3.0.0
*
* @param {number[]} indexes - An array of the tile indexes to not be counted for collision.
* @param {boolean} [collides] - If true it will enable collision. If false it will clear collision.
* @param {boolean} [recalculateFaces] - Whether or not to recalculate the tile faces after the update.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid.
*/
setCollisionByExclusion: function(indexes, collides, recalculateFaces, layer) {
if (collides === void 0) {
collides = true;
}
if (recalculateFaces === void 0) {
recalculateFaces = true;
}
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
TilemapComponents.SetCollisionByExclusion(indexes, collides, recalculateFaces, layer);
return this;
},
/**
* Sets collision on the tiles within a layer by checking each tiles collision group data
* (typically defined in Tiled within the tileset collision editor). If any objects are found within
* a tiles collision group, the tiles colliding information will be set. The `collides` parameter
* controls if collision will be enabled (true) or disabled (false).
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#setCollisionFromCollisionGroup
* @since 3.0.0
*
* @param {boolean} [collides] - If true it will enable collision. If false it will clear collision.
* @param {boolean} [recalculateFaces] - Whether or not to recalculate the tile faces after the update.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid.
*/
setCollisionFromCollisionGroup: function(collides, recalculateFaces, layer) {
if (collides === void 0) {
collides = true;
}
if (recalculateFaces === void 0) {
recalculateFaces = true;
}
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
TilemapComponents.SetCollisionFromCollisionGroup(collides, recalculateFaces, layer);
return this;
},
/**
* Sets a global collision callback for the given tile index within the layer. This will affect all
* tiles on this layer that have the same index. If a callback is already set for the tile index it
* will be replaced. Set the callback to null to remove it. If you want to set a callback for a tile
* at a specific location on the map then see `setTileLocationCallback`.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#setTileIndexCallback
* @since 3.0.0
*
* @param {(number|number[])} indexes - Either a single tile index, or an array of tile indexes to have a collision callback set for. All values should be integers.
* @param {function} callback - The callback that will be invoked when the tile is collided with.
* @param {object} callbackContext - The context under which the callback is called.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid.
*/
setTileIndexCallback: function(indexes, callback, callbackContext, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
TilemapComponents.SetTileIndexCallback(indexes, callback, callbackContext, layer);
return this;
},
/**
* Sets a collision callback for the given rectangular area (in tile coordinates) within the layer.
* If a callback is already set for the tile index it will be replaced. Set the callback to null to
* remove it.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#setTileLocationCallback
* @since 3.0.0
*
* @param {number} tileX - The left most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} tileY - The top most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} width - How many tiles wide from the `tileX` index the area will be.
* @param {number} height - How many tiles tall from the `tileY` index the area will be.
* @param {function} callback - The callback that will be invoked when the tile is collided with.
* @param {object} [callbackContext] - The context under which the callback is called.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid.
*/
setTileLocationCallback: function(tileX, tileY, width, height, callback, callbackContext, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
TilemapComponents.SetTileLocationCallback(tileX, tileY, width, height, callback, callbackContext, layer);
return this;
},
/**
* Sets the current layer to the LayerData associated with `layer`.
*
* @method Phaser.Tilemaps.Tilemap#setLayer
* @since 3.0.0
*
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The name of the layer from Tiled, the index of the layer in the map or a TilemapLayer. If not given will default to the maps current layer index.
*
* @return {this} This Tilemap object.
*/
setLayer: function(layer) {
var index = this.getLayerIndex(layer);
if (index !== null) {
this.currentLayerIndex = index;
}
return this;
},
/**
* Sets the base tile size for the map. Note: this does not necessarily match the tileWidth and
* tileHeight for all layers. This also updates the base size on all tiles across all layers.
*
* @method Phaser.Tilemaps.Tilemap#setBaseTileSize
* @since 3.0.0
*
* @param {number} tileWidth - The width of the tiles the map uses for calculations.
* @param {number} tileHeight - The height of the tiles the map uses for calculations.
*
* @return {this} This Tilemap object.
*/
setBaseTileSize: function(tileWidth, tileHeight) {
this.tileWidth = tileWidth;
this.tileHeight = tileHeight;
this.widthInPixels = this.width * tileWidth;
this.heightInPixels = this.height * tileHeight;
for (var i = 0; i < this.layers.length; i++) {
this.layers[i].baseTileWidth = tileWidth;
this.layers[i].baseTileHeight = tileHeight;
var mapData = this.layers[i].data;
var mapWidth = this.layers[i].width;
var mapHeight = this.layers[i].height;
for (var row = 0; row < mapHeight; row++) {
for (var col = 0; col < mapWidth; col++) {
var tile = mapData[row][col];
if (tile !== null) {
tile.setSize(void 0, void 0, tileWidth, tileHeight);
}
}
}
}
return this;
},
/**
* Sets the tile size for a specific `layer`. Note: this does not necessarily match the maps
* tileWidth and tileHeight for all layers. This will set the tile size for the layer and any
* tiles the layer has.
*
* @method Phaser.Tilemaps.Tilemap#setLayerTileSize
* @since 3.0.0
*
* @param {number} tileWidth - The width of the tiles (in pixels) in the layer.
* @param {number} tileHeight - The height of the tiles (in pixels) in the layer.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The name of the layer from Tiled, the index of the layer in the map or a TilemapLayer. If not given will default to the maps current layer index.
*
* @return {this} This Tilemap object.
*/
setLayerTileSize: function(tileWidth, tileHeight, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return this;
}
layer.tileWidth = tileWidth;
layer.tileHeight = tileHeight;
var mapData = layer.data;
var mapWidth = layer.width;
var mapHeight = layer.height;
for (var row = 0; row < mapHeight; row++) {
for (var col = 0; col < mapWidth; col++) {
var tile = mapData[row][col];
if (tile !== null) {
tile.setSize(tileWidth, tileHeight);
}
}
}
return this;
},
/**
* Shuffles the tiles in a rectangular region (specified in tile coordinates) within the given
* layer. It will only randomize the tiles in that area, so if they're all the same nothing will
* appear to have changed! This method only modifies tile indexes and does not change collision
* information.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#shuffle
* @since 3.0.0
*
* @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [width] - How many tiles wide from the `tileX` index the area will be.
* @param {number} [height] - How many tiles tall from the `tileY` index the area will be.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid.
*/
shuffle: function(tileX, tileY, width, height, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
TilemapComponents.Shuffle(tileX, tileY, width, height, layer);
return this;
},
/**
* Scans the given rectangular area (given in tile coordinates) for tiles with an index matching
* `indexA` and swaps then with `indexB`. This only modifies the index and does not change collision
* information.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#swapByIndex
* @since 3.0.0
*
* @param {number} tileA - First tile index.
* @param {number} tileB - Second tile index.
* @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [width] - How many tiles wide from the `tileX` index the area will be.
* @param {number} [height] - How many tiles tall from the `tileY` index the area will be.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid.
*/
swapByIndex: function(indexA, indexB, tileX, tileY, width, height, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
TilemapComponents.SwapByIndex(indexA, indexB, tileX, tileY, width, height, layer);
return this;
},
/**
* Converts from tile X coordinates (tile units) to world X coordinates (pixels), factoring in the
* layers position, scale and scroll.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#tileToWorldX
* @since 3.0.0
*
* @param {number} tileX - The x coordinate, in tiles, not pixels.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?number} Returns a number, or null if the layer given was invalid.
*/
tileToWorldX: function(tileX, camera, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
return this._convert.TileToWorldX(tileX, camera, layer);
},
/**
* Converts from tile Y coordinates (tile units) to world Y coordinates (pixels), factoring in the
* layers position, scale and scroll.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#tileToWorldY
* @since 3.0.0
*
* @param {number} tileY - The y coordinate, in tiles, not pixels.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?number} Returns a number, or null if the layer given was invalid.
*/
tileToWorldY: function(tileY, camera, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
return this._convert.TileToWorldY(tileY, camera, layer);
},
/**
* Converts from tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the
* layers position, scale and scroll. This will return a new Vector2 object or update the given
* `point` object.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#tileToWorldXY
* @since 3.0.0
*
* @param {number} tileX - The x coordinate, in tiles, not pixels.
* @param {number} tileY - The y coordinate, in tiles, not pixels.
* @param {Phaser.Math.Vector2} [vec2] - A Vector2 to store the coordinates in. If not given a new Vector2 is created.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Math.Vector2} Returns a Vector2, or null if the layer given was invalid.
*/
tileToWorldXY: function(tileX, tileY, vec2, camera, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
return this._convert.TileToWorldXY(tileX, tileY, vec2, camera, layer);
},
/**
* Returns an array of Vector2s where each entry corresponds to the corner of the requested tile.
*
* The `tileX` and `tileY` parameters are in tile coordinates, not world coordinates.
*
* The corner coordinates are in world space, having factored in TilemapLayer scale, position
* and the camera, if given.
*
* The size of the array will vary based on the orientation of the map. For example an
* orthographic map will return an array of 4 vectors, where-as a hexagonal map will,
* of course, return an array of 6 corner vectors.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#getTileCorners
* @since 3.60.0
*
* @param {number} tileX - The x coordinate, in tiles, not pixels.
* @param {number} tileY - The y coordinate, in tiles, not pixels.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Math.Vector2[]} Returns an array of Vector2s, or null if the layer given was invalid.
*/
getTileCorners: function(tileX, tileY, camera, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
return this._convert.GetTileCorners(tileX, tileY, camera, layer);
},
/**
* Randomizes the indexes of a rectangular region of tiles (in tile coordinates) within the
* specified layer. Each tile will receive a new index. New indexes are drawn from the given
* weightedIndexes array. An example weighted array:
*
* [
* { index: 6, weight: 4 }, // Probability of index 6 is 4 / 8
* { index: 7, weight: 2 }, // Probability of index 7 would be 2 / 8
* { index: 8, weight: 1.5 }, // Probability of index 8 would be 1.5 / 8
* { index: 26, weight: 0.5 } // Probability of index 27 would be 0.5 / 8
* ]
*
* The probability of any index being picked is (the indexs weight) / (sum of all weights). This
* method only modifies tile indexes and does not change collision information.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#weightedRandomize
* @since 3.0.0
*
* @param {object[]} weightedIndexes - An array of objects to randomly draw from during randomization. They should be in the form: { index: 0, weight: 4 } or { index: [0, 1], weight: 4 } if you wish to draw from multiple tile indexes.
* @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [width] - How many tiles wide from the `tileX` index the area will be.
* @param {number} [height] - How many tiles tall from the `tileY` index the area will be.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Tilemaps.Tilemap} Return this Tilemap object, or null if the layer given was invalid.
*/
weightedRandomize: function(weightedIndexes, tileX, tileY, width, height, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
TilemapComponents.WeightedRandomize(tileX, tileY, width, height, weightedIndexes, layer);
return this;
},
/**
* Converts from world X coordinates (pixels) to tile X coordinates (tile units), factoring in the
* layers position, scale and scroll.
*
* If no layer is specified, the maps current layer is used.
*
* You cannot call this method for Isometric or Hexagonal tilemaps as they require
* both `worldX` and `worldY` values to determine the correct tile, instead you
* should use the `worldToTileXY` method.
*
* @method Phaser.Tilemaps.Tilemap#worldToTileX
* @since 3.0.0
*
* @param {number} worldX - The x coordinate to be converted, in pixels, not tiles.
* @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?number} Returns a number, or null if the layer given was invalid.
*/
worldToTileX: function(worldX, snapToFloor, camera, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
return this._convert.WorldToTileX(worldX, snapToFloor, camera, layer);
},
/**
* Converts from world Y coordinates (pixels) to tile Y coordinates (tile units), factoring in the
* layers position, scale and scroll.
*
* If no layer is specified, the maps current layer is used.
*
* You cannot call this method for Isometric or Hexagonal tilemaps as they require
* both `worldX` and `worldY` values to determine the correct tile, instead you
* should use the `worldToTileXY` method.
*
* @method Phaser.Tilemaps.Tilemap#worldToTileY
* @since 3.0.0
*
* @param {number} worldY - The y coordinate to be converted, in pixels, not tiles.
* @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?number} Returns a number, or null if the layer given was invalid.
*/
worldToTileY: function(worldY, snapToFloor, camera, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
return this._convert.WorldToTileY(worldY, snapToFloor, camera, layer);
},
/**
* Converts from world XY coordinates (pixels) to tile XY coordinates (tile units), factoring in the
* layers position, scale and scroll. This will return a new Vector2 object or update the given
* `point` object.
*
* If no layer is specified, the maps current layer is used.
*
* @method Phaser.Tilemaps.Tilemap#worldToTileXY
* @since 3.0.0
*
* @param {number} worldX - The x coordinate to be converted, in pixels, not tiles.
* @param {number} worldY - The y coordinate to be converted, in pixels, not tiles.
* @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer.
* @param {Phaser.Math.Vector2} [vec2] - A Vector2 to store the coordinates in. If not given a new Vector2 is created.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values.
* @param {(string|number|Phaser.Tilemaps.TilemapLayer)} [layer] - The tile layer to use. If not given the current layer is used.
*
* @return {?Phaser.Math.Vector2} Returns a vec2, or null if the layer given was invalid.
*/
worldToTileXY: function(worldX, worldY, snapToFloor, vec2, camera, layer) {
layer = this.getLayer(layer);
if (layer === null) {
return null;
}
return this._convert.WorldToTileXY(worldX, worldY, snapToFloor, vec2, camera, layer);
},
/**
* Removes all layer data from this Tilemap and nulls the scene reference. This will destroy any
* TilemapLayers that have been created.
*
* @method Phaser.Tilemaps.Tilemap#destroy
* @since 3.0.0
*/
destroy: function() {
this.removeAllLayers();
this.tiles.length = 0;
this.tilesets.length = 0;
this.objects.length = 0;
this.scene = null;
}
});
module2.exports = Tilemap;
}
),
/***/
45939: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var GameObjectCreator = __webpack_require__2(44603);
var ParseToTilemap = __webpack_require__2(31989);
GameObjectCreator.register("tilemap", function(config) {
var c = config !== void 0 ? config : {};
return ParseToTilemap(
this.scene,
c.key,
c.tileWidth,
c.tileHeight,
c.width,
c.height,
c.data,
c.insertNull
);
});
}
),
/***/
46029: (
/***/
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__2) => {
var GameObjectFactory = __webpack_require__2(39429);
var ParseToTilemap = __webpack_require__2(31989);
GameObjectFactory.register("tilemap", function(key, tileWidth, tileHeight, width, height, data, insertNull) {
if (key === null) {
key = void 0;
}
if (tileWidth === null) {
tileWidth = void 0;
}
if (tileHeight === null) {
tileHeight = void 0;
}
if (width === null) {
width = void 0;
}
if (height === null) {
height = void 0;
}
return ParseToTilemap(this.scene, key, tileWidth, tileHeight, width, height, data, insertNull);
});
}
),
/***/
20442: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CollisionComponent = __webpack_require__2(78389);
var Components = __webpack_require__2(31401);
var GameObject = __webpack_require__2(95643);
var TilemapComponents = __webpack_require__2(81086);
var TilemapLayerRender = __webpack_require__2(19218);
var Vector2 = __webpack_require__2(26099);
var TilemapLayer = new Class({
Extends: GameObject,
Mixins: [
Components.Alpha,
Components.BlendMode,
Components.ComputedSize,
Components.Depth,
Components.Flip,
Components.GetBounds,
Components.Mask,
Components.Origin,
Components.Pipeline,
Components.PostPipeline,
Components.Transform,
Components.Visible,
Components.ScrollFactor,
CollisionComponent,
TilemapLayerRender
],
initialize: function TilemapLayer2(scene, tilemap, layerIndex, tileset, x, y) {
GameObject.call(this, scene, "TilemapLayer");
this.isTilemap = true;
this.tilemap = tilemap;
this.layerIndex = layerIndex;
this.layer = tilemap.layers[layerIndex];
this.layer.tilemapLayer = this;
this.tileset = [];
this.tilesDrawn = 0;
this.tilesTotal = this.layer.width * this.layer.height;
this.culledTiles = [];
this.skipCull = false;
this.cullPaddingX = 1;
this.cullPaddingY = 1;
this.cullCallback = TilemapComponents.GetCullTilesFunction(this.layer.orientation);
this._renderOrder = 0;
this.gidMap = [];
this.tempVec = new Vector2();
this.collisionCategory = 1;
this.collisionMask = 1;
this.setTilesets(tileset);
this.setAlpha(this.layer.alpha);
this.setPosition(x, y);
this.setOrigin(0, 0);
this.setSize(tilemap.tileWidth * this.layer.width, tilemap.tileHeight * this.layer.height);
this.initPipeline();
this.initPostPipeline(false);
},
/**
* Populates the internal `tileset` array with the Tileset references this Layer requires for rendering.
*
* @method Phaser.Tilemaps.TilemapLayer#setTilesets
* @private
* @since 3.50.0
*
* @param {(string|string[]|Phaser.Tilemaps.Tileset|Phaser.Tilemaps.Tileset[])} tileset - The tileset, or an array of tilesets, used to render this layer. Can be a string or a Tileset object.
*/
setTilesets: function(tilesets) {
var gidMap = [];
var setList = [];
var map = this.tilemap;
if (!Array.isArray(tilesets)) {
tilesets = [tilesets];
}
for (var i = 0; i < tilesets.length; i++) {
var tileset = tilesets[i];
if (typeof tileset === "string") {
tileset = map.getTileset(tileset);
}
if (tileset) {
setList.push(tileset);
var s = tileset.firstgid;
for (var t = 0; t < tileset.total; t++) {
gidMap[s + t] = tileset;
}
}
}
this.gidMap = gidMap;
this.tileset = setList;
},
/**
* Sets the rendering (draw) order of the tiles in this layer.
*
* The default is 'right-down', meaning it will order the tiles starting from the top-left,
* drawing to the right and then moving down to the next row.
*
* The draw orders are:
*
* 0 = right-down
* 1 = left-down
* 2 = right-up
* 3 = left-up
*
* Setting the render order does not change the tiles or how they are stored in the layer,
* it purely impacts the order in which they are rendered.
*
* You can provide either an integer (0 to 3), or the string version of the order.
*
* @method Phaser.Tilemaps.TilemapLayer#setRenderOrder
* @since 3.50.0
*
* @param {(number|string)} renderOrder - The render (draw) order value. Either an integer between 0 and 3, or a string: 'right-down', 'left-down', 'right-up' or 'left-up'.
*
* @return {this} This Tilemap Layer object.
*/
setRenderOrder: function(renderOrder) {
var orders = ["right-down", "left-down", "right-up", "left-up"];
if (typeof renderOrder === "string") {
renderOrder = orders.indexOf(renderOrder);
}
if (renderOrder >= 0 && renderOrder < 4) {
this._renderOrder = renderOrder;
}
return this;
},
/**
* Calculates interesting faces at the given tile coordinates of the specified layer. Interesting
* faces are used internally for optimizing collisions against tiles. This method is mostly used
* internally to optimize recalculating faces when only one tile has been changed.
*
* @method Phaser.Tilemaps.TilemapLayer#calculateFacesAt
* @since 3.50.0
*
* @param {number} tileX - The x coordinate.
* @param {number} tileY - The y coordinate.
*
* @return {this} This Tilemap Layer object.
*/
calculateFacesAt: function(tileX, tileY) {
TilemapComponents.CalculateFacesAt(tileX, tileY, this.layer);
return this;
},
/**
* Calculates interesting faces within the rectangular area specified (in tile coordinates) of the
* layer. Interesting faces are used internally for optimizing collisions against tiles. This method
* is mostly used internally.
*
* @method Phaser.Tilemaps.TilemapLayer#calculateFacesWithin
* @since 3.50.0
*
* @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [width] - How many tiles wide from the `tileX` index the area will be.
* @param {number} [height] - How many tiles tall from the `tileY` index the area will be.
*
* @return {this} This Tilemap Layer object.
*/
calculateFacesWithin: function(tileX, tileY, width, height) {
TilemapComponents.CalculateFacesWithin(tileX, tileY, width, height, this.layer);
return this;
},
/**
* Creates a Sprite for every object matching the given tile indexes in the layer. You can
* optionally specify if each tile will be replaced with a new tile after the Sprite has been
* created. This is useful if you want to lay down special tiles in a level that are converted to
* Sprites, but want to replace the tile itself with a floor tile or similar once converted.
*
* @method Phaser.Tilemaps.TilemapLayer#createFromTiles
* @since 3.50.0
*
* @param {(number|array)} indexes - The tile index, or array of indexes, to create Sprites from.
* @param {?(number|array)} replacements - The tile index, or array of indexes, to change a converted
* tile to. Set to `null` to leave the tiles unchanged. If an array is given, it is assumed to be a
* one-to-one mapping with the indexes array.
* @param {Phaser.Types.GameObjects.Sprite.SpriteConfig} [spriteConfig] - The config object to pass into the Sprite creator (i.e.
* scene.make.sprite).
* @param {Phaser.Scene} [scene] - The Scene to create the Sprites within.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when determining the world XY
*
* @return {Phaser.GameObjects.Sprite[]} An array of the Sprites that were created.
*/
createFromTiles: function(indexes, replacements, spriteConfig, scene, camera) {
return TilemapComponents.CreateFromTiles(indexes, replacements, spriteConfig, scene, camera, this.layer);
},
/**
* Returns the tiles in the given layer that are within the cameras viewport.
* This is used internally during rendering.
*
* @method Phaser.Tilemaps.TilemapLayer#cull
* @since 3.50.0
*
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to run the cull check against.
*
* @return {Phaser.Tilemaps.Tile[]} An array of Tile objects to render.
*/
cull: function(camera) {
return this.cullCallback(this.layer, camera, this.culledTiles, this._renderOrder);
},
/**
* Copies the tiles in the source rectangular area to a new destination (all specified in tile
* coordinates) within the layer. This copies all tile properties & recalculates collision
* information in the destination region.
*
* @method Phaser.Tilemaps.TilemapLayer#copy
* @since 3.50.0
*
* @param {number} srcTileX - The x coordinate of the area to copy from, in tiles, not pixels.
* @param {number} srcTileY - The y coordinate of the area to copy from, in tiles, not pixels.
* @param {number} width - The width of the area to copy, in tiles, not pixels.
* @param {number} height - The height of the area to copy, in tiles, not pixels.
* @param {number} destTileX - The x coordinate of the area to copy to, in tiles, not pixels.
* @param {number} destTileY - The y coordinate of the area to copy to, in tiles, not pixels.
* @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated.
*
* @return {this} This Tilemap Layer object.
*/
copy: function(srcTileX, srcTileY, width, height, destTileX, destTileY, recalculateFaces) {
TilemapComponents.Copy(srcTileX, srcTileY, width, height, destTileX, destTileY, recalculateFaces, this.layer);
return this;
},
/**
* Sets the tiles in the given rectangular area (in tile coordinates) of the layer with the
* specified index. Tiles will be set to collide if the given index is a colliding index.
* Collision information in the region will be recalculated.
*
* @method Phaser.Tilemaps.TilemapLayer#fill
* @since 3.50.0
*
* @param {number} index - The tile index to fill the area with.
* @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [width] - How many tiles wide from the `tileX` index the area will be.
* @param {number} [height] - How many tiles tall from the `tileY` index the area will be.
* @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated.
*
* @return {this} This Tilemap Layer object.
*/
fill: function(index, tileX, tileY, width, height, recalculateFaces) {
TilemapComponents.Fill(index, tileX, tileY, width, height, recalculateFaces, this.layer);
return this;
},
/**
* For each tile in the given rectangular area (in tile coordinates) of the layer, run the given
* filter callback function. Any tiles that pass the filter test (i.e. where the callback returns
* true) will returned as a new array. Similar to Array.prototype.Filter in vanilla JS.
*
* @method Phaser.Tilemaps.TilemapLayer#filterTiles
* @since 3.50.0
*
* @param {function} callback - The callback. Each tile in the given area will be passed to this
* callback as the first and only parameter. The callback should return true for tiles that pass the
* filter.
* @param {object} [context] - The context under which the callback should be run.
* @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to filter.
* @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to filter.
* @param {number} [width] - How many tiles wide from the `tileX` index the area will be.
* @param {number} [height] - How many tiles tall from the `tileY` index the area will be.
* @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles.
*
* @return {Phaser.Tilemaps.Tile[]} An array of Tile objects.
*/
filterTiles: function(callback, context, tileX, tileY, width, height, filteringOptions) {
return TilemapComponents.FilterTiles(callback, context, tileX, tileY, width, height, filteringOptions, this.layer);
},
/**
* Searches the entire map layer for the first tile matching the given index, then returns that Tile
* object. If no match is found, it returns null. The search starts from the top-left tile and
* continues horizontally until it hits the end of the row, then it drops down to the next column.
* If the reverse boolean is true, it scans starting from the bottom-right corner traveling up to
* the top-left.
*
* @method Phaser.Tilemaps.TilemapLayer#findByIndex
* @since 3.50.0
*
* @param {number} index - The tile index value to search for.
* @param {number} [skip=0] - The number of times to skip a matching tile before returning.
* @param {boolean} [reverse=false] - If true it will scan the layer in reverse, starting at the bottom-right. Otherwise it scans from the top-left.
*
* @return {Phaser.Tilemaps.Tile} The first matching Tile object.
*/
findByIndex: function(findIndex, skip, reverse) {
return TilemapComponents.FindByIndex(findIndex, skip, reverse, this.layer);
},
/**
* Find the first tile in the given rectangular area (in tile coordinates) of the layer that
* satisfies the provided testing function. I.e. finds the first tile for which `callback` returns
* true. Similar to Array.prototype.find in vanilla JS.
*
* @method Phaser.Tilemaps.TilemapLayer#findTile
* @since 3.50.0
*
* @param {FindTileCallback} callback - The callback. Each tile in the given area will be passed to this callback as the first and only parameter.
* @param {object} [context] - The context under which the callback should be run.
* @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to search.
* @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to search.
* @param {number} [width] - How many tiles wide from the `tileX` index the area will be.
* @param {number} [height] - How many tiles tall from the `tileY` index the area will be.
* @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles.
*
* @return {?Phaser.Tilemaps.Tile} The first Tile found at the given location.
*/
findTile: function(callback, context, tileX, tileY, width, height, filteringOptions) {
return TilemapComponents.FindTile(callback, context, tileX, tileY, width, height, filteringOptions, this.layer);
},
/**
* For each tile in the given rectangular area (in tile coordinates) of the layer, run the given
* callback. Similar to Array.prototype.forEach in vanilla JS.
*
* @method Phaser.Tilemaps.TilemapLayer#forEachTile
* @since 3.50.0
*
* @param {EachTileCallback} callback - The callback. Each tile in the given area will be passed to this callback as the first and only parameter.
* @param {object} [context] - The context, or scope, under which the callback should be run.
* @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to search.
* @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to search.
* @param {number} [width] - How many tiles wide from the `tileX` index the area will be.
* @param {number} [height] - How many tiles tall from the `tileY` index the area will be.
* @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles.
*
* @return {this} This Tilemap Layer object.
*/
forEachTile: function(callback, context, tileX, tileY, width, height, filteringOptions) {
TilemapComponents.ForEachTile(callback, context, tileX, tileY, width, height, filteringOptions, this.layer);
return this;
},
/**
* Sets an additive tint on each Tile within the given area.
*
* The tint works by taking the pixel color values from the tileset texture, and then
* multiplying it by the color value of the tint.
*
* If no area values are given then all tiles will be tinted to the given color.
*
* To remove a tint call this method with either no parameters, or by passing white `0xffffff` as the tint color.
*
* If a tile already has a tint set then calling this method will override that.
*
* @method Phaser.Tilemaps.TilemapLayer#setTint
* @webglOnly
* @since 3.60.0
*
* @param {number} [tint=0xffffff] - The tint color being applied to each tile within the region. Given as a hex value, i.e. `0xff0000` for red. Set to white (`0xffffff`) to reset the tint.
* @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to search.
* @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to search.
* @param {number} [width] - How many tiles wide from the `tileX` index the area will be.
* @param {number} [height] - How many tiles tall from the `tileY` index the area will be.
* @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles.
*
* @return {this} This Tilemap Layer object.
*/
setTint: function(tint, tileX, tileY, width, height, filteringOptions) {
if (tint === void 0) {
tint = 16777215;
}
var tintTile = function(tile) {
tile.tint = tint;
tile.tintFill = false;
};
return this.forEachTile(tintTile, this, tileX, tileY, width, height, filteringOptions);
},
/**
* Sets a fill-based tint on each Tile within the given area.
*
* Unlike an additive tint, a fill-tint literally replaces the pixel colors from the texture
* with those in the tint.
*
* If no area values are given then all tiles will be tinted to the given color.
*
* To remove a tint call this method with either no parameters, or by passing white `0xffffff` as the tint color.
*
* If a tile already has a tint set then calling this method will override that.
*
* @method Phaser.Tilemaps.TilemapLayer#setTintFill
* @webglOnly
* @since 3.70.0
*
* @param {number} [tint=0xffffff] - The tint color being applied to each tile within the region. Given as a hex value, i.e. `0xff0000` for red. Set to white (`0xffffff`) to reset the tint.
* @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area to search.
* @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area to search.
* @param {number} [width] - How many tiles wide from the `tileX` index the area will be.
* @param {number} [height] - How many tiles tall from the `tileY` index the area will be.
* @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles.
*
* @return {this} This Tilemap Layer object.
*/
setTintFill: function(tint, tileX, tileY, width, height, filteringOptions) {
if (tint === void 0) {
tint = 16777215;
}
var tintTile = function(tile) {
tile.tint = tint;
tile.tintFill = true;
};
return this.forEachTile(tintTile, this, tileX, tileY, width, height, filteringOptions);
},
/**
* Gets a tile at the given tile coordinates from the given layer.
*
* @method Phaser.Tilemaps.TilemapLayer#getTileAt
* @since 3.50.0
*
* @param {number} tileX - X position to get the tile from (given in tile units, not pixels).
* @param {number} tileY - Y position to get the tile from (given in tile units, not pixels).
* @param {boolean} [nonNull=false] - For empty tiles, return a Tile object with an index of -1 instead of null.
*
* @return {Phaser.Tilemaps.Tile} The Tile at the given coordinates or null if no tile was found or the coordinates were invalid.
*/
getTileAt: function(tileX, tileY, nonNull) {
return TilemapComponents.GetTileAt(tileX, tileY, nonNull, this.layer);
},
/**
* Gets a tile at the given world coordinates from the given layer.
*
* @method Phaser.Tilemaps.TilemapLayer#getTileAtWorldXY
* @since 3.50.0
*
* @param {number} worldX - X position to get the tile from (given in pixels)
* @param {number} worldY - Y position to get the tile from (given in pixels)
* @param {boolean} [nonNull=false] - For empty tiles, return a Tile object with an index of -1 instead of null.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values.
*
* @return {Phaser.Tilemaps.Tile} The tile at the given coordinates or null if no tile was found or the coordinates were invalid.
*/
getTileAtWorldXY: function(worldX, worldY, nonNull, camera) {
return TilemapComponents.GetTileAtWorldXY(worldX, worldY, nonNull, camera, this.layer);
},
/**
* Gets a tile at the given world coordinates from the given isometric layer.
*
* @method Phaser.Tilemaps.TilemapLayer#getIsoTileAtWorldXY
* @since 3.60.0
*
* @param {number} worldX - X position to get the tile from (given in pixels)
* @param {number} worldY - Y position to get the tile from (given in pixels)
* @param {boolean} [originTop=true] - Which is the active face of the isometric tile? The top (default, true), or the base? (false)
* @param {boolean} [nonNull=false] - For empty tiles, return a Tile object with an index of -1 instead of null.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values.
*
* @return {Phaser.Tilemaps.Tile} The tile at the given coordinates or null if no tile was found or the coordinates were invalid.
*/
getIsoTileAtWorldXY: function(worldX, worldY, originTop, nonNull, camera) {
if (originTop === void 0) {
originTop = true;
}
var point = this.tempVec;
TilemapComponents.IsometricWorldToTileXY(worldX, worldY, true, point, camera, this.layer, originTop);
return this.getTileAt(point.x, point.y, nonNull);
},
/**
* Gets the tiles in the given rectangular area (in tile coordinates) of the layer.
*
* @method Phaser.Tilemaps.TilemapLayer#getTilesWithin
* @since 3.50.0
*
* @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [width] - How many tiles wide from the `tileX` index the area will be.
* @param {number} [height] - How many tiles tall from the `tileY` index the area will be.
* @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles.
*
* @return {Phaser.Tilemaps.Tile[]} An array of Tile objects found within the area.
*/
getTilesWithin: function(tileX, tileY, width, height, filteringOptions) {
return TilemapComponents.GetTilesWithin(tileX, tileY, width, height, filteringOptions, this.layer);
},
/**
* Gets the tiles that overlap with the given shape in the given layer. The shape must be a Circle,
* Line, Rectangle or Triangle. The shape should be in world coordinates.
*
* @method Phaser.Tilemaps.TilemapLayer#getTilesWithinShape
* @since 3.50.0
*
* @param {(Phaser.Geom.Circle|Phaser.Geom.Line|Phaser.Geom.Rectangle|Phaser.Geom.Triangle)} shape - A shape in world (pixel) coordinates
* @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return.
*
* @return {Phaser.Tilemaps.Tile[]} An array of Tile objects found within the shape.
*/
getTilesWithinShape: function(shape, filteringOptions, camera) {
return TilemapComponents.GetTilesWithinShape(shape, filteringOptions, camera, this.layer);
},
/**
* Gets the tiles in the given rectangular area (in world coordinates) of the layer.
*
* @method Phaser.Tilemaps.TilemapLayer#getTilesWithinWorldXY
* @since 3.50.0
*
* @param {number} worldX - The world x coordinate for the top-left of the area.
* @param {number} worldY - The world y coordinate for the top-left of the area.
* @param {number} width - The width of the area.
* @param {number} height - The height of the area.
* @param {Phaser.Types.Tilemaps.FilteringOptions} [filteringOptions] - Optional filters to apply when getting the tiles.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return.
*
* @return {Phaser.Tilemaps.Tile[]} An array of Tile objects found within the area.
*/
getTilesWithinWorldXY: function(worldX, worldY, width, height, filteringOptions, camera) {
return TilemapComponents.GetTilesWithinWorldXY(worldX, worldY, width, height, filteringOptions, camera, this.layer);
},
/**
* Checks if there is a tile at the given location (in tile coordinates) in the given layer. Returns
* false if there is no tile or if the tile at that location has an index of -1.
*
* @method Phaser.Tilemaps.TilemapLayer#hasTileAt
* @since 3.50.0
*
* @param {number} tileX - The x coordinate, in tiles, not pixels.
* @param {number} tileY - The y coordinate, in tiles, not pixels.
*
* @return {boolean} `true` if a tile was found at the given location, otherwise `false`.
*/
hasTileAt: function(tileX, tileY) {
return TilemapComponents.HasTileAt(tileX, tileY, this.layer);
},
/**
* Checks if there is a tile at the given location (in world coordinates) in the given layer. Returns
* false if there is no tile or if the tile at that location has an index of -1.
*
* @method Phaser.Tilemaps.TilemapLayer#hasTileAtWorldXY
* @since 3.50.0
*
* @param {number} worldX - The x coordinate, in pixels.
* @param {number} worldY - The y coordinate, in pixels.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when factoring in which tiles to return.
*
* @return {boolean} `true` if a tile was found at the given location, otherwise `false`.
*/
hasTileAtWorldXY: function(worldX, worldY, camera) {
return TilemapComponents.HasTileAtWorldXY(worldX, worldY, camera, this.layer);
},
/**
* Puts a tile at the given tile coordinates in the specified layer. You can pass in either an index
* or a Tile object. If you pass in a Tile, all attributes will be copied over to the specified
* location. If you pass in an index, only the index at the specified location will be changed.
* Collision information will be recalculated at the specified location.
*
* @method Phaser.Tilemaps.TilemapLayer#putTileAt
* @since 3.50.0
*
* @param {(number|Phaser.Tilemaps.Tile)} tile - The index of this tile to set or a Tile object.
* @param {number} tileX - The x coordinate, in tiles, not pixels.
* @param {number} tileY - The y coordinate, in tiles, not pixels.
* @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated.
*
* @return {Phaser.Tilemaps.Tile} The Tile object that was inserted at the given coordinates.
*/
putTileAt: function(tile, tileX, tileY, recalculateFaces) {
return TilemapComponents.PutTileAt(tile, tileX, tileY, recalculateFaces, this.layer);
},
/**
* Puts a tile at the given world coordinates (pixels) in the specified layer. You can pass in either
* an index or a Tile object. If you pass in a Tile, all attributes will be copied over to the
* specified location. If you pass in an index, only the index at the specified location will be
* changed. Collision information will be recalculated at the specified location.
*
* @method Phaser.Tilemaps.TilemapLayer#putTileAtWorldXY
* @since 3.50.0
*
* @param {(number|Phaser.Tilemaps.Tile)} tile - The index of this tile to set or a Tile object.
* @param {number} worldX - The x coordinate, in pixels.
* @param {number} worldY - The y coordinate, in pixels.
* @param {boolean} [recalculateFaces] - `true` if the faces data should be recalculated.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values.
*
* @return {Phaser.Tilemaps.Tile} The Tile object that was inserted at the given coordinates.
*/
putTileAtWorldXY: function(tile, worldX, worldY, recalculateFaces, camera) {
return TilemapComponents.PutTileAtWorldXY(tile, worldX, worldY, recalculateFaces, camera, this.layer);
},
/**
* Puts an array of tiles or a 2D array of tiles at the given tile coordinates in the specified
* layer. The array can be composed of either tile indexes or Tile objects. If you pass in a Tile,
* all attributes will be copied over to the specified location. If you pass in an index, only the
* index at the specified location will be changed. Collision information will be recalculated
* within the region tiles were changed.
*
* @method Phaser.Tilemaps.TilemapLayer#putTilesAt
* @since 3.50.0
*
* @param {(number[]|number[][]|Phaser.Tilemaps.Tile[]|Phaser.Tilemaps.Tile[][])} tile - A row (array) or grid (2D array) of Tiles or tile indexes to place.
* @param {number} tileX - The x coordinate, in tiles, not pixels.
* @param {number} tileY - The y coordinate, in tiles, not pixels.
* @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated.
*
* @return {this} This Tilemap Layer object.
*/
putTilesAt: function(tilesArray, tileX, tileY, recalculateFaces) {
TilemapComponents.PutTilesAt(tilesArray, tileX, tileY, recalculateFaces, this.layer);
return this;
},
/**
* Randomizes the indexes of a rectangular region of tiles (in tile coordinates) within the
* specified layer. Each tile will receive a new index. If an array of indexes is passed in, then
* those will be used for randomly assigning new tile indexes. If an array is not provided, the
* indexes found within the region (excluding -1) will be used for randomly assigning new tile
* indexes. This method only modifies tile indexes and does not change collision information.
*
* @method Phaser.Tilemaps.TilemapLayer#randomize
* @since 3.50.0
*
* @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [width] - How many tiles wide from the `tileX` index the area will be.
* @param {number} [height] - How many tiles tall from the `tileY` index the area will be.
* @param {number[]} [indexes] - An array of indexes to randomly draw from during randomization.
*
* @return {this} This Tilemap Layer object.
*/
randomize: function(tileX, tileY, width, height, indexes) {
TilemapComponents.Randomize(tileX, tileY, width, height, indexes, this.layer);
return this;
},
/**
* Removes the tile at the given tile coordinates in the specified layer and updates the layers
* collision information.
*
* @method Phaser.Tilemaps.TilemapLayer#removeTileAt
* @since 3.50.0
*
* @param {number} tileX - The x coordinate, in tiles, not pixels.
* @param {number} tileY - The y coordinate, in tiles, not pixels.
* @param {boolean} [replaceWithNull=true] - If true, this will replace the tile at the specified location with null instead of a Tile with an index of -1.
* @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated.
*
* @return {Phaser.Tilemaps.Tile} A Tile object.
*/
removeTileAt: function(tileX, tileY, replaceWithNull, recalculateFaces) {
return TilemapComponents.RemoveTileAt(tileX, tileY, replaceWithNull, recalculateFaces, this.layer);
},
/**
* Removes the tile at the given world coordinates in the specified layer and updates the layers
* collision information.
*
* @method Phaser.Tilemaps.TilemapLayer#removeTileAtWorldXY
* @since 3.50.0
*
* @param {number} worldX - The x coordinate, in pixels.
* @param {number} worldY - The y coordinate, in pixels.
* @param {boolean} [replaceWithNull=true] - If true, this will replace the tile at the specified location with null instead of a Tile with an index of -1.
* @param {boolean} [recalculateFaces=true] - `true` if the faces data should be recalculated.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values.
*
* @return {Phaser.Tilemaps.Tile} The Tile object that was removed from the given location.
*/
removeTileAtWorldXY: function(worldX, worldY, replaceWithNull, recalculateFaces, camera) {
return TilemapComponents.RemoveTileAtWorldXY(worldX, worldY, replaceWithNull, recalculateFaces, camera, this.layer);
},
/**
* Draws a debug representation of the layer to the given Graphics. This is helpful when you want to
* get a quick idea of which of your tiles are colliding and which have interesting faces. The tiles
* are drawn starting at (0, 0) in the Graphics, allowing you to place the debug representation
* wherever you want on the screen.
*
* @method Phaser.Tilemaps.TilemapLayer#renderDebug
* @since 3.50.0
*
* @param {Phaser.GameObjects.Graphics} graphics - The target Graphics object to draw upon.
* @param {Phaser.Types.Tilemaps.StyleConfig} [styleConfig] - An object specifying the colors to use for the debug drawing.
*
* @return {this} This Tilemap Layer object.
*/
renderDebug: function(graphics, styleConfig) {
TilemapComponents.RenderDebug(graphics, styleConfig, this.layer);
return this;
},
/**
* Scans the given rectangular area (given in tile coordinates) for tiles with an index matching
* `findIndex` and updates their index to match `newIndex`. This only modifies the index and does
* not change collision information.
*
* @method Phaser.Tilemaps.TilemapLayer#replaceByIndex
* @since 3.50.0
*
* @param {number} findIndex - The index of the tile to search for.
* @param {number} newIndex - The index of the tile to replace it with.
* @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [width] - How many tiles wide from the `tileX` index the area will be.
* @param {number} [height] - How many tiles tall from the `tileY` index the area will be.
*
* @return {this} This Tilemap Layer object.
*/
replaceByIndex: function(findIndex, newIndex, tileX, tileY, width, height) {
TilemapComponents.ReplaceByIndex(findIndex, newIndex, tileX, tileY, width, height, this.layer);
return this;
},
/**
* You can control if the Cameras should cull tiles before rendering them or not.
*
* By default the camera will try to cull the tiles in this layer, to avoid over-drawing to the renderer.
*
* However, there are some instances when you may wish to disable this.
*
* @method Phaser.Tilemaps.TilemapLayer#setSkipCull
* @since 3.50.0
*
* @param {boolean} [value=true] - Set to `true` to stop culling tiles. Set to `false` to enable culling again.
*
* @return {this} This Tilemap Layer object.
*/
setSkipCull: function(value) {
if (value === void 0) {
value = true;
}
this.skipCull = value;
return this;
},
/**
* When a Camera culls the tiles in this layer it does so using its view into the world, building up a
* rectangle inside which the tiles must exist or they will be culled. Sometimes you may need to expand the size
* of this 'cull rectangle', especially if you plan on rotating the Camera viewing the layer. Do so
* by providing the padding values. The values given are in tiles, not pixels. So if the tile width was 32px
* and you set `paddingX` to be 4, it would add 32px x 4 to the cull rectangle (adjusted for scale)
*
* @method Phaser.Tilemaps.TilemapLayer#setCullPadding
* @since 3.50.0
*
* @param {number} [paddingX=1] - The amount of extra horizontal tiles to add to the cull check padding.
* @param {number} [paddingY=1] - The amount of extra vertical tiles to add to the cull check padding.
*
* @return {this} This Tilemap Layer object.
*/
setCullPadding: function(paddingX, paddingY) {
if (paddingX === void 0) {
paddingX = 1;
}
if (paddingY === void 0) {
paddingY = 1;
}
this.cullPaddingX = paddingX;
this.cullPaddingY = paddingY;
return this;
},
/**
* Sets collision on the given tile or tiles within a layer by index. You can pass in either a
* single numeric index or an array of indexes: [2, 3, 15, 20]. The `collides` parameter controls if
* collision will be enabled (true) or disabled (false).
*
* @method Phaser.Tilemaps.TilemapLayer#setCollision
* @since 3.50.0
*
* @param {(number|array)} indexes - Either a single tile index, or an array of tile indexes.
* @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision.
* @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update.
* @param {boolean} [updateLayer=true] - If true, updates the current tiles on the layer. Set to false if no tiles have been placed for significant performance boost.
*
* @return {this} This Tilemap Layer object.
*/
setCollision: function(indexes, collides, recalculateFaces, updateLayer) {
TilemapComponents.SetCollision(indexes, collides, recalculateFaces, this.layer, updateLayer);
return this;
},
/**
* Sets collision on a range of tiles in a layer whose index is between the specified `start` and
* `stop` (inclusive). Calling this with a start value of 10 and a stop value of 14 would set
* collision for tiles 10, 11, 12, 13 and 14. The `collides` parameter controls if collision will be
* enabled (true) or disabled (false).
*
* @method Phaser.Tilemaps.TilemapLayer#setCollisionBetween
* @since 3.50.0
*
* @param {number} start - The first index of the tile to be set for collision.
* @param {number} stop - The last index of the tile to be set for collision.
* @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision.
* @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update.
*
* @return {this} This Tilemap Layer object.
*/
setCollisionBetween: function(start, stop, collides, recalculateFaces) {
TilemapComponents.SetCollisionBetween(start, stop, collides, recalculateFaces, this.layer);
return this;
},
/**
* Sets collision on the tiles within a layer by checking tile properties. If a tile has a property
* that matches the given properties object, its collision flag will be set. The `collides`
* parameter controls if collision will be enabled (true) or disabled (false). Passing in
* `{ collides: true }` would update the collision flag on any tiles with a "collides" property that
* has a value of true. Any tile that doesn't have "collides" set to true will be ignored. You can
* also use an array of values, e.g. `{ types: ["stone", "lava", "sand" ] }`. If a tile has a
* "types" property that matches any of those values, its collision flag will be updated.
*
* @method Phaser.Tilemaps.TilemapLayer#setCollisionByProperty
* @since 3.50.0
*
* @param {object} properties - An object with tile properties and corresponding values that should be checked.
* @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision.
* @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update.
*
* @return {this} This Tilemap Layer object.
*/
setCollisionByProperty: function(properties, collides, recalculateFaces) {
TilemapComponents.SetCollisionByProperty(properties, collides, recalculateFaces, this.layer);
return this;
},
/**
* Sets collision on all tiles in the given layer, except for tiles that have an index specified in
* the given array. The `collides` parameter controls if collision will be enabled (true) or
* disabled (false). Tile indexes not currently in the layer are not affected.
*
* @method Phaser.Tilemaps.TilemapLayer#setCollisionByExclusion
* @since 3.50.0
*
* @param {number[]} indexes - An array of the tile indexes to not be counted for collision.
* @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision.
* @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update.
*
* @return {this} This Tilemap Layer object.
*/
setCollisionByExclusion: function(indexes, collides, recalculateFaces) {
TilemapComponents.SetCollisionByExclusion(indexes, collides, recalculateFaces, this.layer);
return this;
},
/**
* Sets collision on the tiles within a layer by checking each tiles collision group data
* (typically defined in Tiled within the tileset collision editor). If any objects are found within
* a tiles collision group, the tile's colliding information will be set. The `collides` parameter
* controls if collision will be enabled (true) or disabled (false).
*
* @method Phaser.Tilemaps.TilemapLayer#setCollisionFromCollisionGroup
* @since 3.50.0
*
* @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision.
* @param {boolean} [recalculateFaces=true] - Whether or not to recalculate the tile faces after the update.
*
* @return {this} This Tilemap Layer object.
*/
setCollisionFromCollisionGroup: function(collides, recalculateFaces) {
TilemapComponents.SetCollisionFromCollisionGroup(collides, recalculateFaces, this.layer);
return this;
},
/**
* Sets a global collision callback for the given tile index within the layer. This will affect all
* tiles on this layer that have the same index. If a callback is already set for the tile index it
* will be replaced. Set the callback to null to remove it. If you want to set a callback for a tile
* at a specific location on the map then see setTileLocationCallback.
*
* @method Phaser.Tilemaps.TilemapLayer#setTileIndexCallback
* @since 3.50.0
*
* @param {(number|number[])} indexes - Either a single tile index, or an array of tile indexes to have a collision callback set for.
* @param {function} callback - The callback that will be invoked when the tile is collided with.
* @param {object} callbackContext - The context under which the callback is called.
*
* @return {this} This Tilemap Layer object.
*/
setTileIndexCallback: function(indexes, callback, callbackContext) {
TilemapComponents.SetTileIndexCallback(indexes, callback, callbackContext, this.layer);
return this;
},
/**
* Sets a collision callback for the given rectangular area (in tile coordinates) within the layer.
* If a callback is already set for the tile index it will be replaced. Set the callback to null to
* remove it.
*
* @method Phaser.Tilemaps.TilemapLayer#setTileLocationCallback
* @since 3.50.0
*
* @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [width] - How many tiles wide from the `tileX` index the area will be.
* @param {number} [height] - How many tiles tall from the `tileY` index the area will be.
* @param {function} [callback] - The callback that will be invoked when the tile is collided with.
* @param {object} [callbackContext] - The context, or scope, under which the callback is invoked.
*
* @return {this} This Tilemap Layer object.
*/
setTileLocationCallback: function(tileX, tileY, width, height, callback, callbackContext) {
TilemapComponents.SetTileLocationCallback(tileX, tileY, width, height, callback, callbackContext, this.layer);
return this;
},
/**
* Shuffles the tiles in a rectangular region (specified in tile coordinates) within the given
* layer. It will only randomize the tiles in that area, so if they're all the same nothing will
* appear to have changed! This method only modifies tile indexes and does not change collision
* information.
*
* @method Phaser.Tilemaps.TilemapLayer#shuffle
* @since 3.50.0
*
* @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [width] - How many tiles wide from the `tileX` index the area will be.
* @param {number} [height] - How many tiles tall from the `tileY` index the area will be.
*
* @return {this} This Tilemap Layer object.
*/
shuffle: function(tileX, tileY, width, height) {
TilemapComponents.Shuffle(tileX, tileY, width, height, this.layer);
return this;
},
/**
* Scans the given rectangular area (given in tile coordinates) for tiles with an index matching
* `indexA` and swaps then with `indexB`. This only modifies the index and does not change collision
* information.
*
* @method Phaser.Tilemaps.TilemapLayer#swapByIndex
* @since 3.50.0
*
* @param {number} tileA - First tile index.
* @param {number} tileB - Second tile index.
* @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [width] - How many tiles wide from the `tileX` index the area will be.
* @param {number} [height] - How many tiles tall from the `tileY` index the area will be.
*
* @return {this} This Tilemap Layer object.
*/
swapByIndex: function(indexA, indexB, tileX, tileY, width, height) {
TilemapComponents.SwapByIndex(indexA, indexB, tileX, tileY, width, height, this.layer);
return this;
},
/**
* Converts from tile X coordinates (tile units) to world X coordinates (pixels), factoring in the
* layers position, scale and scroll.
*
* @method Phaser.Tilemaps.TilemapLayer#tileToWorldX
* @since 3.50.0
*
* @param {number} tileX - The x coordinate, in tiles, not pixels.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values.
*
* @return {number} The Tile X coordinate converted to pixels.
*/
tileToWorldX: function(tileX, camera) {
return this.tilemap.tileToWorldX(tileX, camera, this);
},
/**
* Converts from tile Y coordinates (tile units) to world Y coordinates (pixels), factoring in the
* layers position, scale and scroll.
*
* @method Phaser.Tilemaps.TilemapLayer#tileToWorldY
* @since 3.50.0
*
* @param {number} tileY - The y coordinate, in tiles, not pixels.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values.
*
* @return {number} The Tile Y coordinate converted to pixels.
*/
tileToWorldY: function(tileY, camera) {
return this.tilemap.tileToWorldY(tileY, camera, this);
},
/**
* Converts from tile XY coordinates (tile units) to world XY coordinates (pixels), factoring in the
* layers position, scale and scroll. This will return a new Vector2 object or update the given
* `point` object.
*
* @method Phaser.Tilemaps.TilemapLayer#tileToWorldXY
* @since 3.50.0
*
* @param {number} tileX - The x coordinate, in tiles, not pixels.
* @param {number} tileY - The y coordinate, in tiles, not pixels.
* @param {Phaser.Math.Vector2} [point] - A Vector2 to store the coordinates in. If not given a new Vector2 is created.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values.
*
* @return {Phaser.Math.Vector2} A Vector2 containing the world coordinates of the Tile.
*/
tileToWorldXY: function(tileX, tileY, point, camera) {
return this.tilemap.tileToWorldXY(tileX, tileY, point, camera, this);
},
/**
* Returns an array of Vector2s where each entry corresponds to the corner of the requested tile.
*
* The `tileX` and `tileY` parameters are in tile coordinates, not world coordinates.
*
* The corner coordinates are in world space, having factored in TilemapLayer scale, position
* and the camera, if given.
*
* The size of the array will vary based on the orientation of the map. For example an
* orthographic map will return an array of 4 vectors, where-as a hexagonal map will,
* of course, return an array of 6 corner vectors.
*
* @method Phaser.Tilemaps.TilemapLayer#getTileCorners
* @since 3.60.0
*
* @param {number} tileX - The x coordinate, in tiles, not pixels.
* @param {number} tileY - The y coordinate, in tiles, not pixels.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values.
*
* @return {?Phaser.Math.Vector2[]} Returns an array of Vector2s, or null if the layer given was invalid.
*/
getTileCorners: function(tileX, tileY, camera) {
return this.tilemap.getTileCorners(tileX, tileY, camera, this);
},
/**
* Randomizes the indexes of a rectangular region of tiles (in tile coordinates) within the
* specified layer. Each tile will receive a new index. New indexes are drawn from the given
* weightedIndexes array. An example weighted array:
*
* [
* { index: 6, weight: 4 }, // Probability of index 6 is 4 / 8
* { index: 7, weight: 2 }, // Probability of index 7 would be 2 / 8
* { index: 8, weight: 1.5 }, // Probability of index 8 would be 1.5 / 8
* { index: 26, weight: 0.5 } // Probability of index 27 would be 0.5 / 8
* ]
*
* The probability of any index being choose is (the index's weight) / (sum of all weights). This
* method only modifies tile indexes and does not change collision information.
*
* @method Phaser.Tilemaps.TilemapLayer#weightedRandomize
* @since 3.50.0
*
* @param {object[]} weightedIndexes - An array of objects to randomly draw from during randomization. They should be in the form: { index: 0, weight: 4 } or { index: [0, 1], weight: 4 } if you wish to draw from multiple tile indexes.
* @param {number} [tileX] - The left most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [tileY] - The top most tile index (in tile coordinates) to use as the origin of the area.
* @param {number} [width] - How many tiles wide from the `tileX` index the area will be.
* @param {number} [height] - How many tiles tall from the `tileY` index the area will be.
*
* @return {this} This Tilemap Layer object.
*/
weightedRandomize: function(weightedIndexes, tileX, tileY, width, height) {
TilemapComponents.WeightedRandomize(tileX, tileY, width, height, weightedIndexes, this.layer);
return this;
},
/**
* Converts from world X coordinates (pixels) to tile X coordinates (tile units), factoring in the
* layers position, scale and scroll.
*
* You cannot call this method for Isometric or Hexagonal tilemaps as they require
* both `worldX` and `worldY` values to determine the correct tile, instead you
* should use the `worldToTileXY` method.
*
* @method Phaser.Tilemaps.TilemapLayer#worldToTileX
* @since 3.50.0
*
* @param {number} worldX - The x coordinate to be converted, in pixels, not tiles.
* @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values.
*
* @return {number} The tile X coordinate based on the world value.
*/
worldToTileX: function(worldX, snapToFloor, camera) {
return this.tilemap.worldToTileX(worldX, snapToFloor, camera, this);
},
/**
* Converts from world Y coordinates (pixels) to tile Y coordinates (tile units), factoring in the
* layers position, scale and scroll.
*
* You cannot call this method for Isometric or Hexagonal tilemaps as they require
* both `worldX` and `worldY` values to determine the correct tile, instead you
* should use the `worldToTileXY` method.
*
* @method Phaser.Tilemaps.TilemapLayer#worldToTileY
* @since 3.50.0
*
* @param {number} worldY - The y coordinate to be converted, in pixels, not tiles.
* @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values.
*
* @return {number} The tile Y coordinate based on the world value.
*/
worldToTileY: function(worldY, snapToFloor, camera) {
return this.tilemap.worldToTileY(worldY, snapToFloor, camera, this);
},
/**
* Converts from world XY coordinates (pixels) to tile XY coordinates (tile units), factoring in the
* layers position, scale and scroll. This will return a new Vector2 object or update the given
* `point` object.
*
* @method Phaser.Tilemaps.TilemapLayer#worldToTileXY
* @since 3.50.0
*
* @param {number} worldX - The x coordinate to be converted, in pixels, not tiles.
* @param {number} worldY - The y coordinate to be converted, in pixels, not tiles.
* @param {boolean} [snapToFloor] - Whether or not to round the tile coordinate down to the nearest integer.
* @param {Phaser.Math.Vector2} [point] - A Vector2 to store the coordinates in. If not given a new Vector2 is created.
* @param {Phaser.Cameras.Scene2D.Camera} [camera] - The Camera to use when calculating the tile index from the world values.
*
* @return {Phaser.Math.Vector2} A Vector2 containing the tile coordinates of the world values.
*/
worldToTileXY: function(worldX, worldY, snapToFloor, point, camera) {
return this.tilemap.worldToTileXY(worldX, worldY, snapToFloor, point, camera, this);
},
/**
* Destroys this TilemapLayer and removes its link to the associated LayerData.
*
* @method Phaser.Tilemaps.TilemapLayer#destroy
* @since 3.50.0
*
* @param {boolean} [removeFromTilemap=true] - Remove this layer from the parent Tilemap?
*/
destroy: function(removeFromTilemap) {
if (removeFromTilemap === void 0) {
removeFromTilemap = true;
}
if (!this.tilemap) {
return;
}
if (this.layer.tilemapLayer === this) {
this.layer.tilemapLayer = void 0;
}
if (removeFromTilemap) {
this.tilemap.removeLayer(this);
}
this.tilemap = void 0;
this.layer = void 0;
this.culledTiles.length = 0;
this.cullCallback = null;
this.gidMap = [];
this.tileset = [];
GameObject.prototype.destroy.call(this);
}
});
module2.exports = TilemapLayer;
}
),
/***/
16153: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var TransformMatrix = __webpack_require__2(61340);
var tempMatrix1 = new TransformMatrix();
var tempMatrix2 = new TransformMatrix();
var tempMatrix3 = new TransformMatrix();
var TilemapLayerCanvasRenderer = function(renderer, src, camera, parentMatrix) {
var renderTiles = src.cull(camera);
var tileCount = renderTiles.length;
var alpha = camera.alpha * src.alpha;
if (tileCount === 0 || alpha <= 0) {
return;
}
var camMatrix = tempMatrix1;
var layerMatrix = tempMatrix2;
var calcMatrix = tempMatrix3;
layerMatrix.applyITRS(src.x, src.y, src.rotation, src.scaleX, src.scaleY);
camMatrix.copyFrom(camera.matrix);
var ctx = renderer.currentContext;
var gidMap = src.gidMap;
ctx.save();
if (parentMatrix) {
camMatrix.multiplyWithOffset(parentMatrix, -camera.scrollX * src.scrollFactorX, -camera.scrollY * src.scrollFactorY);
layerMatrix.e = src.x;
layerMatrix.f = src.y;
camMatrix.multiply(layerMatrix, calcMatrix);
calcMatrix.copyToContext(ctx);
} else {
layerMatrix.e -= camera.scrollX * src.scrollFactorX;
layerMatrix.f -= camera.scrollY * src.scrollFactorY;
layerMatrix.copyToContext(ctx);
}
if (!renderer.antialias || src.scaleX > 1 || src.scaleY > 1) {
ctx.imageSmoothingEnabled = false;
}
for (var i = 0; i < tileCount; i++) {
var tile = renderTiles[i];
var tileset = gidMap[tile.index];
if (!tileset) {
continue;
}
var image = tileset.image.getSourceImage();
var tileTexCoords = tileset.getTileTextureCoordinates(tile.index);
var tileWidth = tileset.tileWidth;
var tileHeight = tileset.tileHeight;
if (tileTexCoords === null || tileWidth === 0 || tileHeight === 0) {
continue;
}
var halfWidth = tileWidth * 0.5;
var halfHeight = tileHeight * 0.5;
tileTexCoords.x += tileset.tileOffset.x;
tileTexCoords.y += tileset.tileOffset.y;
ctx.save();
ctx.translate(tile.pixelX + halfWidth, tile.pixelY + halfHeight);
if (tile.rotation !== 0) {
ctx.rotate(tile.rotation);
}
if (tile.flipX || tile.flipY) {
ctx.scale(tile.flipX ? -1 : 1, tile.flipY ? -1 : 1);
}
ctx.globalAlpha = alpha * tile.alpha;
ctx.drawImage(
image,
tileTexCoords.x,
tileTexCoords.y,
tileWidth,
tileHeight,
-halfWidth,
-halfHeight,
tileWidth,
tileHeight
);
ctx.restore();
}
ctx.restore();
};
module2.exports = TilemapLayerCanvasRenderer;
}
),
/***/
19218: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var NOOP = __webpack_require__2(29747);
var renderWebGL = NOOP;
var renderCanvas = NOOP;
if (true) {
renderWebGL = __webpack_require__2(99558);
}
if (true) {
renderCanvas = __webpack_require__2(16153);
}
module2.exports = {
renderWebGL,
renderCanvas
};
}
),
/***/
99558: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Utils = __webpack_require__2(70554);
var TilemapLayerWebGLRenderer = function(renderer, src, camera) {
var renderTiles = src.cull(camera);
var tileCount = renderTiles.length;
var alpha = camera.alpha * src.alpha;
if (tileCount === 0 || alpha <= 0) {
return;
}
var gidMap = src.gidMap;
var pipeline = renderer.pipelines.set(src.pipeline, src);
var getTint = Utils.getTintAppendFloatAlpha;
var scrollFactorX = src.scrollFactorX;
var scrollFactorY = src.scrollFactorY;
var x = src.x;
var y = src.y;
var sx = src.scaleX;
var sy = src.scaleY;
renderer.pipelines.preBatch(src);
for (var i = 0; i < tileCount; i++) {
var tile = renderTiles[i];
var tileset = gidMap[tile.index];
if (!tileset) {
continue;
}
var tileTexCoords = tileset.getTileTextureCoordinates(tile.index);
var tileWidth = tileset.tileWidth;
var tileHeight = tileset.tileHeight;
if (!tileTexCoords || tileWidth === 0 || tileHeight === 0) {
continue;
}
var halfWidth = tileWidth * 0.5;
var halfHeight = tileHeight * 0.5;
var texture = tileset.glTexture;
var textureUnit = pipeline.setTexture2D(texture, src);
var frameWidth = tileWidth;
var frameHeight = tileHeight;
var frameX = tileTexCoords.x;
var frameY = tileTexCoords.y;
var tOffsetX = tileset.tileOffset.x;
var tOffsetY = tileset.tileOffset.y;
var tint = getTint(tile.tint, alpha * tile.alpha);
pipeline.batchTexture(
src,
texture,
texture.width,
texture.height,
x + tile.pixelX * sx + (halfWidth * sx - tOffsetX),
y + tile.pixelY * sy + (halfHeight * sy - tOffsetY),
tileWidth,
tileHeight,
sx,
sy,
tile.rotation,
tile.flipX,
tile.flipY,
scrollFactorX,
scrollFactorY,
halfWidth,
halfHeight,
frameX,
frameY,
frameWidth,
frameHeight,
tint,
tint,
tint,
tint,
tile.tintFill,
0,
0,
camera,
null,
true,
textureUnit,
true
);
}
renderer.pipelines.postBatch(src);
};
module2.exports = TilemapLayerWebGLRenderer;
}
),
/***/
33629: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Vector2 = __webpack_require__2(26099);
var Tileset = new Class({
initialize: function Tileset2(name, firstgid, tileWidth, tileHeight, tileMargin, tileSpacing, tileProperties, tileData, tileOffset) {
if (tileWidth === void 0 || tileWidth <= 0) {
tileWidth = 32;
}
if (tileHeight === void 0 || tileHeight <= 0) {
tileHeight = 32;
}
if (tileMargin === void 0) {
tileMargin = 0;
}
if (tileSpacing === void 0) {
tileSpacing = 0;
}
if (tileProperties === void 0) {
tileProperties = {};
}
if (tileData === void 0) {
tileData = {};
}
this.name = name;
this.firstgid = firstgid;
this.tileWidth = tileWidth;
this.tileHeight = tileHeight;
this.tileMargin = tileMargin;
this.tileSpacing = tileSpacing;
this.tileProperties = tileProperties;
this.tileData = tileData;
this.tileOffset = new Vector2();
if (tileOffset !== void 0) {
this.tileOffset.set(tileOffset.x, tileOffset.y);
}
this.image = null;
this.glTexture = null;
this.rows = 0;
this.columns = 0;
this.total = 0;
this.texCoordinates = [];
},
/**
* Get a tiles properties that are stored in the Tileset. Returns null if tile index is not
* contained in this Tileset. This is typically defined in Tiled under the Tileset editor.
*
* @method Phaser.Tilemaps.Tileset#getTileProperties
* @since 3.0.0
*
* @param {number} tileIndex - The unique id of the tile across all tilesets in the map.
*
* @return {?(object|undefined)}
*/
getTileProperties: function(tileIndex) {
if (!this.containsTileIndex(tileIndex)) {
return null;
}
return this.tileProperties[tileIndex - this.firstgid];
},
/**
* Get a tile's data that is stored in the Tileset. Returns null if tile index is not contained
* in this Tileset. This is typically defined in Tiled and will contain both Tileset collision
* info and terrain mapping.
*
* @method Phaser.Tilemaps.Tileset#getTileData
* @since 3.0.0
*
* @param {number} tileIndex - The unique id of the tile across all tilesets in the map.
*
* @return {?object|undefined}
*/
getTileData: function(tileIndex) {
if (!this.containsTileIndex(tileIndex)) {
return null;
}
return this.tileData[tileIndex - this.firstgid];
},
/**
* Get a tile's collision group that is stored in the Tileset. Returns null if tile index is not
* contained in this Tileset. This is typically defined within Tiled's tileset collision editor.
*
* @method Phaser.Tilemaps.Tileset#getTileCollisionGroup
* @since 3.0.0
*
* @param {number} tileIndex - The unique id of the tile across all tilesets in the map.
*
* @return {?object}
*/
getTileCollisionGroup: function(tileIndex) {
var data = this.getTileData(tileIndex);
return data && data.objectgroup ? data.objectgroup : null;
},
/**
* Returns true if and only if this Tileset contains the given tile index.
*
* @method Phaser.Tilemaps.Tileset#containsTileIndex
* @since 3.0.0
*
* @param {number} tileIndex - The unique id of the tile across all tilesets in the map.
*
* @return {boolean}
*/
containsTileIndex: function(tileIndex) {
return tileIndex >= this.firstgid && tileIndex < this.firstgid + this.total;
},
/**
* Returns the texture coordinates (UV in pixels) in the Tileset image for the given tile index.
* Returns null if tile index is not contained in this Tileset.
*
* @method Phaser.Tilemaps.Tileset#getTileTextureCoordinates
* @since 3.0.0
*
* @param {number} tileIndex - The unique id of the tile across all tilesets in the map.
*
* @return {?object} Object in the form { x, y } representing the top-left UV coordinate
* within the Tileset image.
*/
getTileTextureCoordinates: function(tileIndex) {
if (!this.containsTileIndex(tileIndex)) {
return null;
}
return this.texCoordinates[tileIndex - this.firstgid];
},
/**
* Sets the image associated with this Tileset and updates the tile data (rows, columns, etc.).
*
* @method Phaser.Tilemaps.Tileset#setImage
* @since 3.0.0
*
* @param {Phaser.Textures.Texture} texture - The image that contains the tiles.
*
* @return {Phaser.Tilemaps.Tileset} This Tileset object.
*/
setImage: function(texture) {
this.image = texture;
var frame = texture.get();
var bounds = texture.getFrameBounds();
this.glTexture = frame.source.glTexture;
if (frame.width > bounds.width || frame.height > bounds.height) {
this.updateTileData(frame.width, frame.height);
} else {
this.updateTileData(bounds.width, bounds.height, bounds.x, bounds.y);
}
return this;
},
/**
* Sets the tile width & height and updates the tile data (rows, columns, etc.).
*
* @method Phaser.Tilemaps.Tileset#setTileSize
* @since 3.0.0
*
* @param {number} [tileWidth] - The width of a tile in pixels.
* @param {number} [tileHeight] - The height of a tile in pixels.
*
* @return {Phaser.Tilemaps.Tileset} This Tileset object.
*/
setTileSize: function(tileWidth, tileHeight) {
if (tileWidth !== void 0) {
this.tileWidth = tileWidth;
}
if (tileHeight !== void 0) {
this.tileHeight = tileHeight;
}
if (this.image) {
this.updateTileData(this.image.source[0].width, this.image.source[0].height);
}
return this;
},
/**
* Sets the tile margin and spacing and updates the tile data (rows, columns, etc.).
*
* @method Phaser.Tilemaps.Tileset#setSpacing
* @since 3.0.0
*
* @param {number} [margin] - The margin around the tiles in the sheet (in pixels).
* @param {number} [spacing] - The spacing between the tiles in the sheet (in pixels).
*
* @return {Phaser.Tilemaps.Tileset} This Tileset object.
*/
setSpacing: function(margin, spacing) {
if (margin !== void 0) {
this.tileMargin = margin;
}
if (spacing !== void 0) {
this.tileSpacing = spacing;
}
if (this.image) {
this.updateTileData(this.image.source[0].width, this.image.source[0].height);
}
return this;
},
/**
* Updates tile texture coordinates and tileset data.
*
* @method Phaser.Tilemaps.Tileset#updateTileData
* @since 3.0.0
*
* @param {number} imageWidth - The (expected) width of the image to slice.
* @param {number} imageHeight - The (expected) height of the image to slice.
* @param {number} [offsetX=0] - The x offset in the source texture where the tileset starts.
* @param {number} [offsetY=0] - The y offset in the source texture where the tileset starts.
*
* @return {Phaser.Tilemaps.Tileset} This Tileset object.
*/
updateTileData: function(imageWidth, imageHeight, offsetX, offsetY) {
if (offsetX === void 0) {
offsetX = 0;
}
if (offsetY === void 0) {
offsetY = 0;
}
var rowCount = (imageHeight - this.tileMargin * 2 + this.tileSpacing) / (this.tileHeight + this.tileSpacing);
var colCount = (imageWidth - this.tileMargin * 2 + this.tileSpacing) / (this.tileWidth + this.tileSpacing);
if (rowCount % 1 !== 0 || colCount % 1 !== 0) {
console.warn("Image tile area not tile size multiple in: " + this.name);
}
rowCount = Math.floor(rowCount);
colCount = Math.floor(colCount);
this.rows = rowCount;
this.columns = colCount;
this.total = rowCount * colCount;
this.texCoordinates.length = 0;
var tx = this.tileMargin + offsetX;
var ty = this.tileMargin + offsetY;
for (var y = 0; y < this.rows; y++) {
for (var x = 0; x < this.columns; x++) {
this.texCoordinates.push({ x: tx, y: ty });
tx += this.tileWidth + this.tileSpacing;
}
tx = this.tileMargin + offsetX;
ty += this.tileHeight + this.tileSpacing;
}
return this;
}
});
module2.exports = Tileset;
}
),
/***/
72023: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetTileAt = __webpack_require__2(7423);
var CalculateFacesAt = function(tileX, tileY, layer) {
var tile = GetTileAt(tileX, tileY, true, layer);
var above = GetTileAt(tileX, tileY - 1, true, layer);
var below = GetTileAt(tileX, tileY + 1, true, layer);
var left = GetTileAt(tileX - 1, tileY, true, layer);
var right = GetTileAt(tileX + 1, tileY, true, layer);
var tileCollides = tile && tile.collides;
if (tileCollides) {
tile.faceTop = true;
tile.faceBottom = true;
tile.faceLeft = true;
tile.faceRight = true;
}
if (above && above.collides) {
if (tileCollides) {
tile.faceTop = false;
}
above.faceBottom = !tileCollides;
}
if (below && below.collides) {
if (tileCollides) {
tile.faceBottom = false;
}
below.faceTop = !tileCollides;
}
if (left && left.collides) {
if (tileCollides) {
tile.faceLeft = false;
}
left.faceRight = !tileCollides;
}
if (right && right.collides) {
if (tileCollides) {
tile.faceRight = false;
}
right.faceLeft = !tileCollides;
}
if (tile && !tile.collides) {
tile.resetFaces();
}
return tile;
};
module2.exports = CalculateFacesAt;
}
),
/***/
42573: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetTileAt = __webpack_require__2(7423);
var GetTilesWithin = __webpack_require__2(7386);
var CalculateFacesWithin = function(tileX, tileY, width, height, layer) {
var above = null;
var below = null;
var left = null;
var right = null;
var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer);
for (var i = 0; i < tiles.length; i++) {
var tile = tiles[i];
if (tile) {
if (tile.collides) {
above = GetTileAt(tile.x, tile.y - 1, true, layer);
below = GetTileAt(tile.x, tile.y + 1, true, layer);
left = GetTileAt(tile.x - 1, tile.y, true, layer);
right = GetTileAt(tile.x + 1, tile.y, true, layer);
tile.faceTop = above && above.collides ? false : true;
tile.faceBottom = below && below.collides ? false : true;
tile.faceLeft = left && left.collides ? false : true;
tile.faceRight = right && right.collides ? false : true;
} else {
tile.resetFaces();
}
}
}
};
module2.exports = CalculateFacesWithin;
}
),
/***/
33528: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Vector2 = __webpack_require__2(26099);
var point = new Vector2();
var CheckIsoBounds = function(tileX, tileY, layer, camera) {
var tilemapLayer = layer.tilemapLayer;
var cullPaddingX = tilemapLayer.cullPaddingX;
var cullPaddingY = tilemapLayer.cullPaddingY;
var pos = tilemapLayer.tilemap.tileToWorldXY(tileX, tileY, point, camera, tilemapLayer);
return pos.x > camera.worldView.x + tilemapLayer.scaleX * layer.tileWidth * (-cullPaddingX - 0.5) && pos.x < camera.worldView.right + tilemapLayer.scaleX * layer.tileWidth * (cullPaddingX - 0.5) && pos.y > camera.worldView.y + tilemapLayer.scaleY * layer.tileHeight * (-cullPaddingY - 1) && pos.y < camera.worldView.bottom + tilemapLayer.scaleY * layer.tileHeight * (cullPaddingY - 0.5);
};
module2.exports = CheckIsoBounds;
}
),
/***/
1785: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CalculateFacesWithin = __webpack_require__2(42573);
var GetTilesWithin = __webpack_require__2(7386);
var IsInLayerBounds = __webpack_require__2(62991);
var Tile = __webpack_require__2(23029);
var Copy = function(srcTileX, srcTileY, width, height, destTileX, destTileY, recalculateFaces, layer) {
if (recalculateFaces === void 0) {
recalculateFaces = true;
}
var srcTiles = GetTilesWithin(srcTileX, srcTileY, width, height, null, layer);
var copyTiles = [];
srcTiles.forEach(function(tile) {
var newTile = new Tile(
tile.layer,
tile.index,
tile.x,
tile.y,
tile.width,
tile.height,
tile.baseWidth,
tile.baseHeight
);
newTile.copy(tile);
copyTiles.push(newTile);
});
var offsetX = destTileX - srcTileX;
var offsetY = destTileY - srcTileY;
for (var i = 0; i < copyTiles.length; i++) {
var copy = copyTiles[i];
var tileX = copy.x + offsetX;
var tileY = copy.y + offsetY;
if (IsInLayerBounds(tileX, tileY, layer)) {
if (layer.data[tileY][tileX]) {
copy.x = tileX;
copy.y = tileY;
copy.updatePixelXY();
layer.data[tileY][tileX] = copy;
}
}
}
if (recalculateFaces) {
CalculateFacesWithin(destTileX - 1, destTileY - 1, width + 2, height + 2, layer);
}
srcTiles.length = 0;
copyTiles.length = 0;
};
module2.exports = Copy;
}
),
/***/
78419: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var DeepCopy = __webpack_require__2(62644);
var GetTilesWithin = __webpack_require__2(7386);
var ReplaceByIndex = __webpack_require__2(27987);
var CreateFromTiles = function(indexes, replacements, spriteConfig, scene, camera, layer) {
if (!spriteConfig) {
spriteConfig = {};
}
if (!Array.isArray(indexes)) {
indexes = [indexes];
}
var tilemapLayer = layer.tilemapLayer;
if (!scene) {
scene = tilemapLayer.scene;
}
if (!camera) {
camera = scene.cameras.main;
}
var layerWidth = layer.width;
var layerHeight = layer.height;
var tiles = GetTilesWithin(0, 0, layerWidth, layerHeight, null, layer);
var sprites = [];
var i;
var mergeExtras = function(config2, tile2, properties) {
for (var i2 = 0; i2 < properties.length; i2++) {
var property = properties[i2];
if (!config2.hasOwnProperty(property)) {
config2[property] = tile2[property];
}
}
};
for (i = 0; i < tiles.length; i++) {
var tile = tiles[i];
var config = DeepCopy(spriteConfig);
if (indexes.indexOf(tile.index) !== -1) {
var point = tilemapLayer.tileToWorldXY(tile.x, tile.y, void 0, camera, layer);
config.x = point.x;
config.y = point.y;
mergeExtras(config, tile, ["rotation", "flipX", "flipY", "alpha", "visible", "tint"]);
if (!config.hasOwnProperty("origin")) {
config.x += tile.width * 0.5;
config.y += tile.height * 0.5;
}
if (config.hasOwnProperty("useSpriteSheet")) {
config.key = tile.tileset.image;
config.frame = tile.index - 1;
}
sprites.push(scene.make.sprite(config));
}
}
if (Array.isArray(replacements)) {
for (i = 0; i < indexes.length; i++) {
ReplaceByIndex(indexes[i], replacements[i], 0, 0, layerWidth, layerHeight, layer);
}
} else if (replacements !== null) {
for (i = 0; i < indexes.length; i++) {
ReplaceByIndex(indexes[i], replacements, 0, 0, layerWidth, layerHeight, layer);
}
}
return sprites;
};
module2.exports = CreateFromTiles;
}
),
/***/
19545: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Rectangle = __webpack_require__2(87841);
var SnapCeil = __webpack_require__2(63448);
var SnapFloor = __webpack_require__2(56583);
var bounds = new Rectangle();
var CullBounds = function(layer, camera) {
var tilemap = layer.tilemapLayer.tilemap;
var tilemapLayer = layer.tilemapLayer;
var tileW = Math.floor(tilemap.tileWidth * tilemapLayer.scaleX);
var tileH = Math.floor(tilemap.tileHeight * tilemapLayer.scaleY);
var boundsLeft = SnapFloor(camera.worldView.x - tilemapLayer.x, tileW, 0, true) - tilemapLayer.cullPaddingX;
var boundsRight = SnapCeil(camera.worldView.right - tilemapLayer.x, tileW, 0, true) + tilemapLayer.cullPaddingX;
var boundsTop = SnapFloor(camera.worldView.y - tilemapLayer.y, tileH, 0, true) - tilemapLayer.cullPaddingY;
var boundsBottom = SnapCeil(camera.worldView.bottom - tilemapLayer.y, tileH, 0, true) + tilemapLayer.cullPaddingY;
return bounds.setTo(
boundsLeft,
boundsTop,
boundsRight - boundsLeft,
boundsBottom - boundsTop
);
};
module2.exports = CullBounds;
}
),
/***/
30003: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CullBounds = __webpack_require__2(19545);
var RunCull = __webpack_require__2(32483);
var CullTiles = function(layer, camera, outputArray, renderOrder) {
if (outputArray === void 0) {
outputArray = [];
}
if (renderOrder === void 0) {
renderOrder = 0;
}
outputArray.length = 0;
var tilemapLayer = layer.tilemapLayer;
var bounds = CullBounds(layer, camera);
if (tilemapLayer.skipCull || tilemapLayer.scrollFactorX !== 1 || tilemapLayer.scrollFactorY !== 1) {
bounds.left = 0;
bounds.right = layer.width;
bounds.top = 0;
bounds.bottom = layer.height;
}
RunCull(layer, bounds, renderOrder, outputArray);
return outputArray;
};
module2.exports = CullTiles;
}
),
/***/
35137: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetTilesWithin = __webpack_require__2(7386);
var CalculateFacesWithin = __webpack_require__2(42573);
var SetTileCollision = __webpack_require__2(20576);
var Fill = function(index, tileX, tileY, width, height, recalculateFaces, layer) {
var doesIndexCollide = layer.collideIndexes.indexOf(index) !== -1;
var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer);
for (var i = 0; i < tiles.length; i++) {
tiles[i].index = index;
SetTileCollision(tiles[i], doesIndexCollide);
}
if (recalculateFaces) {
CalculateFacesWithin(tileX - 1, tileY - 1, width + 2, height + 2, layer);
}
};
module2.exports = Fill;
}
),
/***/
40253: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetTilesWithin = __webpack_require__2(7386);
var FilterTiles = function(callback, context, tileX, tileY, width, height, filteringOptions, layer) {
var tiles = GetTilesWithin(tileX, tileY, width, height, filteringOptions, layer);
return tiles.filter(callback, context);
};
module2.exports = FilterTiles;
}
),
/***/
52692: (
/***/
(module2) => {
var FindByIndex = function(findIndex, skip, reverse, layer) {
if (skip === void 0) {
skip = 0;
}
if (reverse === void 0) {
reverse = false;
}
var count = 0;
var tx;
var ty;
var tile;
if (reverse) {
for (ty = layer.height - 1; ty >= 0; ty--) {
for (tx = layer.width - 1; tx >= 0; tx--) {
tile = layer.data[ty][tx];
if (tile && tile.index === findIndex) {
if (count === skip) {
return tile;
} else {
count += 1;
}
}
}
}
} else {
for (ty = 0; ty < layer.height; ty++) {
for (tx = 0; tx < layer.width; tx++) {
tile = layer.data[ty][tx];
if (tile && tile.index === findIndex) {
if (count === skip) {
return tile;
} else {
count += 1;
}
}
}
}
}
return null;
};
module2.exports = FindByIndex;
}
),
/***/
66151: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetTilesWithin = __webpack_require__2(7386);
var FindTile = function(callback, context, tileX, tileY, width, height, filteringOptions, layer) {
var tiles = GetTilesWithin(tileX, tileY, width, height, filteringOptions, layer);
return tiles.find(callback, context) || null;
};
module2.exports = FindTile;
}
),
/***/
97560: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetTilesWithin = __webpack_require__2(7386);
var ForEachTile = function(callback, context, tileX, tileY, width, height, filteringOptions, layer) {
var tiles = GetTilesWithin(tileX, tileY, width, height, filteringOptions, layer);
tiles.forEach(callback, context);
};
module2.exports = ForEachTile;
}
),
/***/
43305: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(91907);
var CullTiles = __webpack_require__2(30003);
var HexagonalCullTiles = __webpack_require__2(9474);
var IsometricCullTiles = __webpack_require__2(14018);
var NOOP = __webpack_require__2(29747);
var StaggeredCullTiles = __webpack_require__2(54503);
var GetCullTilesFunction = function(orientation) {
if (orientation === CONST.ORTHOGONAL) {
return CullTiles;
} else if (orientation === CONST.HEXAGONAL) {
return HexagonalCullTiles;
} else if (orientation === CONST.STAGGERED) {
return StaggeredCullTiles;
} else if (orientation === CONST.ISOMETRIC) {
return IsometricCullTiles;
} else {
return NOOP;
}
};
module2.exports = GetCullTilesFunction;
}
),
/***/
7423: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var IsInLayerBounds = __webpack_require__2(62991);
var GetTileAt = function(tileX, tileY, nonNull, layer) {
if (IsInLayerBounds(tileX, tileY, layer)) {
var tile = layer.data[tileY][tileX] || null;
if (!tile) {
return null;
} else if (tile.index === -1) {
return nonNull ? tile : null;
} else {
return tile;
}
} else {
return null;
}
};
module2.exports = GetTileAt;
}
),
/***/
60540: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetTileAt = __webpack_require__2(7423);
var Vector2 = __webpack_require__2(26099);
var point = new Vector2();
var GetTileAtWorldXY = function(worldX, worldY, nonNull, camera, layer) {
layer.tilemapLayer.worldToTileXY(worldX, worldY, true, point, camera);
return GetTileAt(point.x, point.y, nonNull, layer);
};
module2.exports = GetTileAtWorldXY;
}
),
/***/
55826: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Vector2 = __webpack_require__2(26099);
var GetTileCorners = function(tileX, tileY, camera, layer) {
var tileWidth = layer.baseTileWidth;
var tileHeight = layer.baseTileHeight;
var tilemapLayer = layer.tilemapLayer;
var worldX = 0;
var worldY = 0;
if (tilemapLayer) {
if (!camera) {
camera = tilemapLayer.scene.cameras.main;
}
worldX = tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX);
worldY = tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY);
tileWidth *= tilemapLayer.scaleX;
tileHeight *= tilemapLayer.scaleY;
}
var x = worldX + tileX * tileWidth;
var y = worldY + tileY * tileHeight;
return [
new Vector2(x, y),
new Vector2(x + tileWidth, y),
new Vector2(x + tileWidth, y + tileHeight),
new Vector2(x, y + tileHeight)
];
};
module2.exports = GetTileCorners;
}
),
/***/
11758: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(91907);
var HexagonalGetTileCorners = __webpack_require__2(27229);
var NOOP = __webpack_require__2(29747);
var GetTileCorners = __webpack_require__2(55826);
var GetTileCornersFunction = function(orientation) {
if (orientation === CONST.ORTHOGONAL) {
return GetTileCorners;
} else if (orientation === CONST.ISOMETRIC) {
return NOOP;
} else if (orientation === CONST.HEXAGONAL) {
return HexagonalGetTileCorners;
} else if (orientation === CONST.STAGGERED) {
return NOOP;
} else {
return NOOP;
}
};
module2.exports = GetTileCornersFunction;
}
),
/***/
39167: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(91907);
var NOOP = __webpack_require__2(29747);
var TileToWorldX = __webpack_require__2(97281);
var GetTileToWorldXFunction = function(orientation) {
if (orientation === CONST.ORTHOGONAL) {
return TileToWorldX;
} else {
return NOOP;
}
};
module2.exports = GetTileToWorldXFunction;
}
),
/***/
62e3: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(91907);
var HexagonalTileToWorldXY = __webpack_require__2(19951);
var IsometricTileToWorldXY = __webpack_require__2(14127);
var NOOP = __webpack_require__2(29747);
var StaggeredTileToWorldXY = __webpack_require__2(97202);
var TileToWorldXY = __webpack_require__2(70326);
var GetTileToWorldXYFunction = function(orientation) {
if (orientation === CONST.ORTHOGONAL) {
return TileToWorldXY;
} else if (orientation === CONST.ISOMETRIC) {
return IsometricTileToWorldXY;
} else if (orientation === CONST.HEXAGONAL) {
return HexagonalTileToWorldXY;
} else if (orientation === CONST.STAGGERED) {
return StaggeredTileToWorldXY;
} else {
return NOOP;
}
};
module2.exports = GetTileToWorldXYFunction;
}
),
/***/
5984: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(91907);
var NOOP = __webpack_require__2(29747);
var StaggeredTileToWorldY = __webpack_require__2(28054);
var TileToWorldY = __webpack_require__2(29650);
var GetTileToWorldYFunction = function(orientation) {
if (orientation === CONST.ORTHOGONAL) {
return TileToWorldY;
} else if (orientation === CONST.STAGGERED) {
return StaggeredTileToWorldY;
} else {
return NOOP;
}
};
module2.exports = GetTileToWorldYFunction;
}
),
/***/
7386: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetFastValue = __webpack_require__2(95540);
var GetTilesWithin = function(tileX, tileY, width, height, filteringOptions, layer) {
if (tileX === void 0) {
tileX = 0;
}
if (tileY === void 0) {
tileY = 0;
}
if (width === void 0) {
width = layer.width;
}
if (height === void 0) {
height = layer.height;
}
if (!filteringOptions) {
filteringOptions = {};
}
var isNotEmpty = GetFastValue(filteringOptions, "isNotEmpty", false);
var isColliding = GetFastValue(filteringOptions, "isColliding", false);
var hasInterestingFace = GetFastValue(filteringOptions, "hasInterestingFace", false);
if (tileX < 0) {
width += tileX;
tileX = 0;
}
if (tileY < 0) {
height += tileY;
tileY = 0;
}
if (tileX + width > layer.width) {
width = Math.max(layer.width - tileX, 0);
}
if (tileY + height > layer.height) {
height = Math.max(layer.height - tileY, 0);
}
var results = [];
for (var ty = tileY; ty < tileY + height; ty++) {
for (var tx = tileX; tx < tileX + width; tx++) {
var tile = layer.data[ty][tx];
if (tile !== null) {
if (isNotEmpty && tile.index === -1) {
continue;
}
if (isColliding && !tile.collides) {
continue;
}
if (hasInterestingFace && !tile.hasInterestingFace) {
continue;
}
results.push(tile);
}
}
}
return results;
};
module2.exports = GetTilesWithin;
}
),
/***/
91141: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Geom = __webpack_require__2(55738);
var GetTilesWithin = __webpack_require__2(7386);
var Intersects = __webpack_require__2(91865);
var NOOP = __webpack_require__2(29747);
var Vector2 = __webpack_require__2(26099);
var TriangleToRectangle = function(triangle, rect) {
return Intersects.RectangleToTriangle(rect, triangle);
};
var point = new Vector2();
var pointStart = new Vector2();
var pointEnd = new Vector2();
var GetTilesWithinShape = function(shape, filteringOptions, camera, layer) {
if (shape === void 0) {
return [];
}
var intersectTest = NOOP;
if (shape instanceof Geom.Circle) {
intersectTest = Intersects.CircleToRectangle;
} else if (shape instanceof Geom.Rectangle) {
intersectTest = Intersects.RectangleToRectangle;
} else if (shape instanceof Geom.Triangle) {
intersectTest = TriangleToRectangle;
} else if (shape instanceof Geom.Line) {
intersectTest = Intersects.LineToRectangle;
}
layer.tilemapLayer.worldToTileXY(shape.left, shape.top, true, pointStart, camera);
var xStart = pointStart.x;
var yStart = pointStart.y;
layer.tilemapLayer.worldToTileXY(shape.right, shape.bottom, false, pointEnd, camera);
var xEnd = Math.ceil(pointEnd.x);
var yEnd = Math.ceil(pointEnd.y);
var width = Math.max(xEnd - xStart, 1);
var height = Math.max(yEnd - yStart, 1);
var tiles = GetTilesWithin(xStart, yStart, width, height, filteringOptions, layer);
var tileWidth = layer.tileWidth;
var tileHeight = layer.tileHeight;
if (layer.tilemapLayer) {
tileWidth *= layer.tilemapLayer.scaleX;
tileHeight *= layer.tilemapLayer.scaleY;
}
var results = [];
var tileRect = new Geom.Rectangle(0, 0, tileWidth, tileHeight);
for (var i = 0; i < tiles.length; i++) {
var tile = tiles[i];
layer.tilemapLayer.tileToWorldXY(tile.x, tile.y, point, camera);
tileRect.x = point.x;
tileRect.y = point.y;
if (intersectTest(shape, tileRect)) {
results.push(tile);
}
}
return results;
};
module2.exports = GetTilesWithinShape;
}
),
/***/
96523: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetTilesWithin = __webpack_require__2(7386);
var Vector2 = __webpack_require__2(26099);
var pointStart = new Vector2();
var pointEnd = new Vector2();
var GetTilesWithinWorldXY = function(worldX, worldY, width, height, filteringOptions, camera, layer) {
var worldToTileXY = layer.tilemapLayer.tilemap._convert.WorldToTileXY;
worldToTileXY(worldX, worldY, true, pointStart, camera, layer);
var xStart = pointStart.x;
var yStart = pointStart.y;
worldToTileXY(worldX + width, worldY + height, false, pointEnd, camera, layer);
var xEnd = Math.ceil(pointEnd.x);
var yEnd = Math.ceil(pointEnd.y);
return GetTilesWithin(xStart, yStart, xEnd - xStart, yEnd - yStart, filteringOptions, layer);
};
module2.exports = GetTilesWithinWorldXY;
}
),
/***/
96113: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(91907);
var NULL = __webpack_require__2(20242);
var WorldToTileX = __webpack_require__2(10095);
var GetWorldToTileXFunction = function(orientation) {
if (orientation === CONST.ORTHOGONAL) {
return WorldToTileX;
} else {
return NULL;
}
};
module2.exports = GetWorldToTileXFunction;
}
),
/***/
16926: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(91907);
var HexagonalWorldToTileXY = __webpack_require__2(86625);
var IsometricWorldToTileXY = __webpack_require__2(96897);
var NOOP = __webpack_require__2(29747);
var StaggeredWorldToTileXY = __webpack_require__2(15108);
var WorldToTileXY = __webpack_require__2(85896);
var GetWorldToTileXYFunction = function(orientation) {
if (orientation === CONST.ORTHOGONAL) {
return WorldToTileXY;
} else if (orientation === CONST.ISOMETRIC) {
return IsometricWorldToTileXY;
} else if (orientation === CONST.HEXAGONAL) {
return HexagonalWorldToTileXY;
} else if (orientation === CONST.STAGGERED) {
return StaggeredWorldToTileXY;
} else {
return NOOP;
}
};
module2.exports = GetWorldToTileXYFunction;
}
),
/***/
55762: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(91907);
var NULL = __webpack_require__2(20242);
var StaggeredWorldToTileY = __webpack_require__2(51900);
var WorldToTileY = __webpack_require__2(63288);
var GetWorldToTileYFunction = function(orientation) {
if (orientation === CONST.ORTHOGONAL) {
return WorldToTileY;
} else if (orientation === CONST.STAGGERED) {
return StaggeredWorldToTileY;
} else {
return NULL;
}
};
module2.exports = GetWorldToTileYFunction;
}
),
/***/
45091: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var IsInLayerBounds = __webpack_require__2(62991);
var HasTileAt = function(tileX, tileY, layer) {
if (IsInLayerBounds(tileX, tileY, layer)) {
var tile = layer.data[tileY][tileX];
return tile !== null && tile.index > -1;
} else {
return false;
}
};
module2.exports = HasTileAt;
}
),
/***/
24152: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var HasTileAt = __webpack_require__2(45091);
var Vector2 = __webpack_require__2(26099);
var point = new Vector2();
var HasTileAtWorldXY = function(worldX, worldY, camera, layer) {
layer.tilemapLayer.worldToTileXY(worldX, worldY, true, point, camera);
var tileX = point.x;
var tileY = point.y;
return HasTileAt(tileX, tileY, layer);
};
module2.exports = HasTileAtWorldXY;
}
),
/***/
90454: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var SnapCeil = __webpack_require__2(63448);
var SnapFloor = __webpack_require__2(56583);
var HexagonalCullBounds = function(layer, camera) {
var tilemap = layer.tilemapLayer.tilemap;
var tilemapLayer = layer.tilemapLayer;
var tileW = Math.floor(tilemap.tileWidth * tilemapLayer.scaleX);
var tileH = Math.floor(tilemap.tileHeight * tilemapLayer.scaleY);
var len = layer.hexSideLength;
var boundsLeft;
var boundsRight;
var boundsTop;
var boundsBottom;
if (layer.staggerAxis === "y") {
var rowH = (tileH - len) / 2 + len;
boundsLeft = SnapFloor(camera.worldView.x - tilemapLayer.x, tileW, 0, true) - tilemapLayer.cullPaddingX;
boundsRight = SnapCeil(camera.worldView.right - tilemapLayer.x, tileW, 0, true) + tilemapLayer.cullPaddingX;
boundsTop = SnapFloor(camera.worldView.y - tilemapLayer.y, rowH, 0, true) - tilemapLayer.cullPaddingY;
boundsBottom = SnapCeil(camera.worldView.bottom - tilemapLayer.y, rowH, 0, true) + tilemapLayer.cullPaddingY;
} else {
var rowW = (tileW - len) / 2 + len;
boundsLeft = SnapFloor(camera.worldView.x - tilemapLayer.x, rowW, 0, true) - tilemapLayer.cullPaddingX;
boundsRight = SnapCeil(camera.worldView.right - tilemapLayer.x, rowW, 0, true) + tilemapLayer.cullPaddingX;
boundsTop = SnapFloor(camera.worldView.y - tilemapLayer.y, tileH, 0, true) - tilemapLayer.cullPaddingY;
boundsBottom = SnapCeil(camera.worldView.bottom - tilemapLayer.y, tileH, 0, true) + tilemapLayer.cullPaddingY;
}
return {
left: boundsLeft,
right: boundsRight,
top: boundsTop,
bottom: boundsBottom
};
};
module2.exports = HexagonalCullBounds;
}
),
/***/
9474: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CullBounds = __webpack_require__2(90454);
var RunCull = __webpack_require__2(32483);
var HexagonalCullTiles = function(layer, camera, outputArray, renderOrder) {
if (outputArray === void 0) {
outputArray = [];
}
if (renderOrder === void 0) {
renderOrder = 0;
}
outputArray.length = 0;
var tilemapLayer = layer.tilemapLayer;
var bounds = CullBounds(layer, camera);
if (tilemapLayer.skipCull && tilemapLayer.scrollFactorX === 1 && tilemapLayer.scrollFactorY === 1) {
bounds.left = 0;
bounds.right = layer.width;
bounds.top = 0;
bounds.bottom = layer.height;
}
RunCull(layer, bounds, renderOrder, outputArray);
return outputArray;
};
module2.exports = HexagonalCullTiles;
}
),
/***/
27229: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var HexagonalTileToWorldXY = __webpack_require__2(19951);
var Vector2 = __webpack_require__2(26099);
var tempVec = new Vector2();
var HexagonalGetTileCorners = function(tileX, tileY, camera, layer) {
var tileWidth = layer.baseTileWidth;
var tileHeight = layer.baseTileHeight;
var tilemapLayer = layer.tilemapLayer;
if (tilemapLayer) {
tileWidth *= tilemapLayer.scaleX;
tileHeight *= tilemapLayer.scaleY;
}
var center = HexagonalTileToWorldXY(tileX, tileY, tempVec, camera, layer);
var corners = [];
var b0 = 0.5773502691896257;
var hexWidth;
var hexHeight;
if (layer.staggerAxis === "y") {
hexWidth = b0 * tileWidth;
hexHeight = tileHeight / 2;
} else {
hexWidth = tileWidth / 2;
hexHeight = b0 * tileHeight;
}
for (var i = 0; i < 6; i++) {
var angle = 2 * Math.PI * (0.5 - i) / 6;
corners.push(new Vector2(center.x + hexWidth * Math.cos(angle), center.y + hexHeight * Math.sin(angle)));
}
return corners;
};
module2.exports = HexagonalGetTileCorners;
}
),
/***/
19951: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Vector2 = __webpack_require__2(26099);
var HexagonalTileToWorldXY = function(tileX, tileY, point, camera, layer) {
if (!point) {
point = new Vector2();
}
var tileWidth = layer.baseTileWidth;
var tileHeight = layer.baseTileHeight;
var tilemapLayer = layer.tilemapLayer;
var worldX = 0;
var worldY = 0;
if (tilemapLayer) {
if (!camera) {
camera = tilemapLayer.scene.cameras.main;
}
worldX = tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX);
worldY = tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY);
tileWidth *= tilemapLayer.scaleX;
tileHeight *= tilemapLayer.scaleY;
}
var tileWidthHalf = tileWidth / 2;
var tileHeightHalf = tileHeight / 2;
var x;
var y;
var staggerAxis = layer.staggerAxis;
var staggerIndex = layer.staggerIndex;
if (staggerAxis === "y") {
x = worldX + tileWidth * tileX + tileWidth;
y = worldY + 1.5 * tileY * tileHeightHalf + tileHeightHalf;
if (tileY % 2 === 0) {
if (staggerIndex === "odd") {
x -= tileWidthHalf;
} else {
x += tileWidthHalf;
}
}
} else if (staggerAxis === "x" && staggerIndex === "odd") {
x = worldX + 1.5 * tileX * tileWidthHalf + tileWidthHalf;
y = worldY + tileHeight * tileX + tileHeight;
if (tileX % 2 === 0) {
if (staggerIndex === "odd") {
y -= tileHeightHalf;
} else {
y += tileHeightHalf;
}
}
}
return point.set(x, y);
};
module2.exports = HexagonalTileToWorldXY;
}
),
/***/
86625: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Vector2 = __webpack_require__2(26099);
var HexagonalWorldToTileXY = function(worldX, worldY, snapToFloor, point, camera, layer) {
if (!point) {
point = new Vector2();
}
var tileWidth = layer.baseTileWidth;
var tileHeight = layer.baseTileHeight;
var tilemapLayer = layer.tilemapLayer;
if (tilemapLayer) {
if (!camera) {
camera = tilemapLayer.scene.cameras.main;
}
worldX = worldX - (tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX));
worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY));
tileWidth *= tilemapLayer.scaleX;
tileHeight *= tilemapLayer.scaleY;
}
var b0 = 0.5773502691896257;
var b1 = -0.3333333333333333;
var b2 = 0;
var b3 = 0.6666666666666666;
var tileWidthHalf = tileWidth / 2;
var tileHeightHalf = tileHeight / 2;
var px;
var py;
var q;
var r;
var s;
if (layer.staggerAxis === "y") {
px = (worldX - tileWidthHalf) / (b0 * tileWidth);
py = (worldY - tileHeightHalf) / tileHeightHalf;
q = b0 * px + b1 * py;
r = b2 * px + b3 * py;
} else {
px = (worldX - tileWidthHalf) / tileWidthHalf;
py = (worldY - tileHeightHalf) / (b0 * tileHeight);
q = b1 * px + b0 * py;
r = b3 * px + b2 * py;
}
s = -q - r;
var qi = Math.round(q);
var ri = Math.round(r);
var si = Math.round(s);
var qDiff = Math.abs(qi - q);
var rDiff = Math.abs(ri - r);
var sDiff = Math.abs(si - s);
if (qDiff > rDiff && qDiff > sDiff) {
qi = -ri - si;
} else if (rDiff > sDiff) {
ri = -qi - si;
}
var x;
var y = ri;
if (layer.staggerIndex === "odd") {
x = y % 2 === 0 ? ri / 2 + qi : ri / 2 + qi - 0.5;
} else {
x = y % 2 === 0 ? ri / 2 + qi : ri / 2 + qi + 0.5;
}
return point.set(x, y);
};
module2.exports = HexagonalWorldToTileXY;
}
),
/***/
62991: (
/***/
(module2) => {
var IsInLayerBounds = function(tileX, tileY, layer) {
return tileX >= 0 && tileX < layer.width && tileY >= 0 && tileY < layer.height;
};
module2.exports = IsInLayerBounds;
}
),
/***/
14018: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CheckIsoBounds = __webpack_require__2(33528);
var IsometricCullTiles = function(layer, camera, outputArray, renderOrder) {
if (outputArray === void 0) {
outputArray = [];
}
if (renderOrder === void 0) {
renderOrder = 0;
}
outputArray.length = 0;
var tilemapLayer = layer.tilemapLayer;
var mapData = layer.data;
var mapWidth = layer.width;
var mapHeight = layer.height;
var skipCull = tilemapLayer.skipCull;
var drawLeft = 0;
var drawRight = mapWidth;
var drawTop = 0;
var drawBottom = mapHeight;
var x;
var y;
var tile;
if (renderOrder === 0) {
for (y = drawTop; y < drawBottom; y++) {
for (x = drawLeft; x < drawRight; x++) {
tile = mapData[y][x];
if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) {
continue;
}
if (!skipCull && !CheckIsoBounds(x, y, layer, camera)) {
continue;
}
outputArray.push(tile);
}
}
} else if (renderOrder === 1) {
for (y = drawTop; y < drawBottom; y++) {
for (x = drawRight; x >= drawLeft; x--) {
tile = mapData[y][x];
if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) {
continue;
}
if (!skipCull && !CheckIsoBounds(x, y, layer, camera)) {
continue;
}
outputArray.push(tile);
}
}
} else if (renderOrder === 2) {
for (y = drawBottom; y >= drawTop; y--) {
for (x = drawLeft; x < drawRight; x++) {
tile = mapData[y][x];
if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) {
continue;
}
if (!skipCull && !CheckIsoBounds(x, y, layer, camera)) {
continue;
}
outputArray.push(tile);
}
}
} else if (renderOrder === 3) {
for (y = drawBottom; y >= drawTop; y--) {
for (x = drawRight; x >= drawLeft; x--) {
tile = mapData[y][x];
if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) {
continue;
}
if (!skipCull && !CheckIsoBounds(x, y, layer, camera)) {
continue;
}
outputArray.push(tile);
}
}
}
tilemapLayer.tilesDrawn = outputArray.length;
tilemapLayer.tilesTotal = mapWidth * mapHeight;
return outputArray;
};
module2.exports = IsometricCullTiles;
}
),
/***/
14127: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Vector2 = __webpack_require__2(26099);
var IsometricTileToWorldXY = function(tileX, tileY, point, camera, layer) {
if (!point) {
point = new Vector2();
}
var tileWidth = layer.baseTileWidth;
var tileHeight = layer.baseTileHeight;
var tilemapLayer = layer.tilemapLayer;
var layerWorldX = 0;
var layerWorldY = 0;
if (tilemapLayer) {
if (!camera) {
camera = tilemapLayer.scene.cameras.main;
}
layerWorldX = tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX);
tileWidth *= tilemapLayer.scaleX;
layerWorldY = tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY);
tileHeight *= tilemapLayer.scaleY;
}
var x = layerWorldX + (tileX - tileY) * (tileWidth / 2);
var y = layerWorldY + (tileX + tileY) * (tileHeight / 2);
return point.set(x, y);
};
module2.exports = IsometricTileToWorldXY;
}
),
/***/
96897: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Vector2 = __webpack_require__2(26099);
var IsometricWorldToTileXY = function(worldX, worldY, snapToFloor, point, camera, layer, originTop) {
if (!point) {
point = new Vector2();
}
var tileWidth = layer.baseTileWidth;
var tileHeight = layer.baseTileHeight;
var tilemapLayer = layer.tilemapLayer;
if (tilemapLayer) {
if (!camera) {
camera = tilemapLayer.scene.cameras.main;
}
worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY));
tileHeight *= tilemapLayer.scaleY;
worldX = worldX - (tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX));
tileWidth *= tilemapLayer.scaleX;
}
var tileWidthHalf = tileWidth / 2;
var tileHeightHalf = tileHeight / 2;
worldX = worldX - tileWidthHalf;
if (!originTop) {
worldY = worldY - tileHeight;
}
var x = 0.5 * (worldX / tileWidthHalf + worldY / tileHeightHalf);
var y = 0.5 * (-worldX / tileWidthHalf + worldY / tileHeightHalf);
if (snapToFloor) {
x = Math.floor(x);
y = Math.floor(y);
}
return point.set(x, y);
};
module2.exports = IsometricWorldToTileXY;
}
),
/***/
71558: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Tile = __webpack_require__2(23029);
var IsInLayerBounds = __webpack_require__2(62991);
var CalculateFacesAt = __webpack_require__2(72023);
var SetTileCollision = __webpack_require__2(20576);
var PutTileAt = function(tile, tileX, tileY, recalculateFaces, layer) {
if (recalculateFaces === void 0) {
recalculateFaces = true;
}
if (!IsInLayerBounds(tileX, tileY, layer)) {
return null;
}
var index;
var oldTile = layer.data[tileY][tileX];
var oldTileCollides = oldTile && oldTile.collides;
if (tile instanceof Tile) {
if (layer.data[tileY][tileX] === null) {
layer.data[tileY][tileX] = new Tile(layer, tile.index, tileX, tileY, layer.tileWidth, layer.tileHeight);
}
layer.data[tileY][tileX].copy(tile);
} else {
index = tile;
if (layer.data[tileY][tileX] === null) {
layer.data[tileY][tileX] = new Tile(layer, index, tileX, tileY, layer.tileWidth, layer.tileHeight);
} else {
layer.data[tileY][tileX].index = index;
}
}
var newTile = layer.data[tileY][tileX];
var collides = layer.collideIndexes.indexOf(newTile.index) !== -1;
index = tile instanceof Tile ? tile.index : tile;
if (index === -1) {
newTile.width = layer.tileWidth;
newTile.height = layer.tileHeight;
} else {
var tilemap = layer.tilemapLayer.tilemap;
var tiles = tilemap.tiles;
var sid = tiles[index][2];
var set = tilemap.tilesets[sid];
newTile.width = set.tileWidth;
newTile.height = set.tileHeight;
}
SetTileCollision(newTile, collides);
if (recalculateFaces && oldTileCollides !== newTile.collides) {
CalculateFacesAt(tileX, tileY, layer);
}
return newTile;
};
module2.exports = PutTileAt;
}
),
/***/
26303: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var PutTileAt = __webpack_require__2(71558);
var Vector2 = __webpack_require__2(26099);
var point = new Vector2();
var PutTileAtWorldXY = function(tile, worldX, worldY, recalculateFaces, camera, layer) {
layer.tilemapLayer.worldToTileXY(worldX, worldY, true, point, camera, layer);
return PutTileAt(tile, point.x, point.y, recalculateFaces, layer);
};
module2.exports = PutTileAtWorldXY;
}
),
/***/
14051: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CalculateFacesWithin = __webpack_require__2(42573);
var PutTileAt = __webpack_require__2(71558);
var PutTilesAt = function(tilesArray, tileX, tileY, recalculateFaces, layer) {
if (recalculateFaces === void 0) {
recalculateFaces = true;
}
if (!Array.isArray(tilesArray)) {
return null;
}
if (!Array.isArray(tilesArray[0])) {
tilesArray = [tilesArray];
}
var height = tilesArray.length;
var width = tilesArray[0].length;
for (var ty = 0; ty < height; ty++) {
for (var tx = 0; tx < width; tx++) {
var tile = tilesArray[ty][tx];
PutTileAt(tile, tileX + tx, tileY + ty, false, layer);
}
}
if (recalculateFaces) {
CalculateFacesWithin(tileX - 1, tileY - 1, width + 2, height + 2, layer);
}
};
module2.exports = PutTilesAt;
}
),
/***/
77389: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetTilesWithin = __webpack_require__2(7386);
var GetRandom = __webpack_require__2(26546);
var Randomize = function(tileX, tileY, width, height, indexes, layer) {
var i;
var tiles = GetTilesWithin(tileX, tileY, width, height, {}, layer);
if (!indexes) {
indexes = [];
for (i = 0; i < tiles.length; i++) {
if (indexes.indexOf(tiles[i].index) === -1) {
indexes.push(tiles[i].index);
}
}
}
for (i = 0; i < tiles.length; i++) {
tiles[i].index = GetRandom(indexes);
}
};
module2.exports = Randomize;
}
),
/***/
63557: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Tile = __webpack_require__2(23029);
var IsInLayerBounds = __webpack_require__2(62991);
var CalculateFacesAt = __webpack_require__2(72023);
var RemoveTileAt = function(tileX, tileY, replaceWithNull, recalculateFaces, layer) {
if (replaceWithNull === void 0) {
replaceWithNull = true;
}
if (recalculateFaces === void 0) {
recalculateFaces = true;
}
if (!IsInLayerBounds(tileX, tileY, layer)) {
return null;
}
var tile = layer.data[tileY][tileX];
if (!tile) {
return null;
} else {
layer.data[tileY][tileX] = replaceWithNull ? null : new Tile(layer, -1, tileX, tileY, layer.tileWidth, layer.tileHeight);
}
if (recalculateFaces && tile && tile.collides) {
CalculateFacesAt(tileX, tileY, layer);
}
return tile;
};
module2.exports = RemoveTileAt;
}
),
/***/
94178: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var RemoveTileAt = __webpack_require__2(63557);
var Vector2 = __webpack_require__2(26099);
var point = new Vector2();
var RemoveTileAtWorldXY = function(worldX, worldY, replaceWithNull, recalculateFaces, camera, layer) {
layer.tilemapLayer.worldToTileXY(worldX, worldY, true, point, camera, layer);
return RemoveTileAt(point.x, point.y, replaceWithNull, recalculateFaces, layer);
};
module2.exports = RemoveTileAtWorldXY;
}
),
/***/
15533: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetTilesWithin = __webpack_require__2(7386);
var Color = __webpack_require__2(3956);
var defaultTileColor = new Color(105, 210, 231, 150);
var defaultCollidingTileColor = new Color(243, 134, 48, 200);
var defaultFaceColor = new Color(40, 39, 37, 150);
var RenderDebug = function(graphics, styleConfig, layer) {
if (styleConfig === void 0) {
styleConfig = {};
}
var tileColor = styleConfig.tileColor !== void 0 ? styleConfig.tileColor : defaultTileColor;
var collidingTileColor = styleConfig.collidingTileColor !== void 0 ? styleConfig.collidingTileColor : defaultCollidingTileColor;
var faceColor = styleConfig.faceColor !== void 0 ? styleConfig.faceColor : defaultFaceColor;
var tiles = GetTilesWithin(0, 0, layer.width, layer.height, null, layer);
graphics.translateCanvas(layer.tilemapLayer.x, layer.tilemapLayer.y);
graphics.scaleCanvas(layer.tilemapLayer.scaleX, layer.tilemapLayer.scaleY);
for (var i = 0; i < tiles.length; i++) {
var tile = tiles[i];
var tw = tile.width;
var th = tile.height;
var x = tile.pixelX;
var y = tile.pixelY;
var color = tile.collides ? collidingTileColor : tileColor;
if (color !== null) {
graphics.fillStyle(color.color, color.alpha / 255);
graphics.fillRect(x, y, tw, th);
}
x += 1;
y += 1;
tw -= 2;
th -= 2;
if (faceColor !== null) {
graphics.lineStyle(1, faceColor.color, faceColor.alpha / 255);
if (tile.faceTop) {
graphics.lineBetween(x, y, x + tw, y);
}
if (tile.faceRight) {
graphics.lineBetween(x + tw, y, x + tw, y + th);
}
if (tile.faceBottom) {
graphics.lineBetween(x, y + th, x + tw, y + th);
}
if (tile.faceLeft) {
graphics.lineBetween(x, y, x, y + th);
}
}
}
};
module2.exports = RenderDebug;
}
),
/***/
27987: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetTilesWithin = __webpack_require__2(7386);
var ReplaceByIndex = function(findIndex, newIndex, tileX, tileY, width, height, layer) {
var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer);
for (var i = 0; i < tiles.length; i++) {
if (tiles[i] && tiles[i].index === findIndex) {
tiles[i].index = newIndex;
}
}
};
module2.exports = ReplaceByIndex;
}
),
/***/
32483: (
/***/
(module2) => {
var RunCull = function(layer, bounds, renderOrder, outputArray) {
var mapData = layer.data;
var mapWidth = layer.width;
var mapHeight = layer.height;
var tilemapLayer = layer.tilemapLayer;
var drawLeft = Math.max(0, bounds.left);
var drawRight = Math.min(mapWidth, bounds.right);
var drawTop = Math.max(0, bounds.top);
var drawBottom = Math.min(mapHeight, bounds.bottom);
var x;
var y;
var tile;
if (renderOrder === 0) {
for (y = drawTop; y < drawBottom; y++) {
for (x = drawLeft; mapData[y] && x < drawRight; x++) {
tile = mapData[y][x];
if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) {
continue;
}
outputArray.push(tile);
}
}
} else if (renderOrder === 1) {
for (y = drawTop; y < drawBottom; y++) {
for (x = drawRight; mapData[y] && x >= drawLeft; x--) {
tile = mapData[y][x];
if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) {
continue;
}
outputArray.push(tile);
}
}
} else if (renderOrder === 2) {
for (y = drawBottom; y >= drawTop; y--) {
for (x = drawLeft; mapData[y] && x < drawRight; x++) {
tile = mapData[y][x];
if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) {
continue;
}
outputArray.push(tile);
}
}
} else if (renderOrder === 3) {
for (y = drawBottom; y >= drawTop; y--) {
for (x = drawRight; mapData[y] && x >= drawLeft; x--) {
tile = mapData[y][x];
if (!tile || tile.index === -1 || !tile.visible || tile.alpha === 0) {
continue;
}
outputArray.push(tile);
}
}
}
tilemapLayer.tilesDrawn = outputArray.length;
tilemapLayer.tilesTotal = mapWidth * mapHeight;
return outputArray;
};
module2.exports = RunCull;
}
),
/***/
57068: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var SetTileCollision = __webpack_require__2(20576);
var CalculateFacesWithin = __webpack_require__2(42573);
var SetLayerCollisionIndex = __webpack_require__2(9589);
var SetCollision = function(indexes, collides, recalculateFaces, layer, updateLayer) {
if (collides === void 0) {
collides = true;
}
if (recalculateFaces === void 0) {
recalculateFaces = true;
}
if (updateLayer === void 0) {
updateLayer = true;
}
if (!Array.isArray(indexes)) {
indexes = [indexes];
}
for (var i = 0; i < indexes.length; i++) {
SetLayerCollisionIndex(indexes[i], collides, layer);
}
if (updateLayer) {
for (var ty = 0; ty < layer.height; ty++) {
for (var tx = 0; tx < layer.width; tx++) {
var tile = layer.data[ty][tx];
if (tile && indexes.indexOf(tile.index) !== -1) {
SetTileCollision(tile, collides);
}
}
}
}
if (recalculateFaces) {
CalculateFacesWithin(0, 0, layer.width, layer.height, layer);
}
};
module2.exports = SetCollision;
}
),
/***/
37266: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var SetTileCollision = __webpack_require__2(20576);
var CalculateFacesWithin = __webpack_require__2(42573);
var SetLayerCollisionIndex = __webpack_require__2(9589);
var SetCollisionBetween = function(start, stop, collides, recalculateFaces, layer, updateLayer) {
if (collides === void 0) {
collides = true;
}
if (recalculateFaces === void 0) {
recalculateFaces = true;
}
if (updateLayer === void 0) {
updateLayer = true;
}
if (start > stop) {
return;
}
for (var index = start; index <= stop; index++) {
SetLayerCollisionIndex(index, collides, layer);
}
if (updateLayer) {
for (var ty = 0; ty < layer.height; ty++) {
for (var tx = 0; tx < layer.width; tx++) {
var tile = layer.data[ty][tx];
if (tile) {
if (tile.index >= start && tile.index <= stop) {
SetTileCollision(tile, collides);
}
}
}
}
}
if (recalculateFaces) {
CalculateFacesWithin(0, 0, layer.width, layer.height, layer);
}
};
module2.exports = SetCollisionBetween;
}
),
/***/
75661: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var SetTileCollision = __webpack_require__2(20576);
var CalculateFacesWithin = __webpack_require__2(42573);
var SetLayerCollisionIndex = __webpack_require__2(9589);
var SetCollisionByExclusion = function(indexes, collides, recalculateFaces, layer) {
if (collides === void 0) {
collides = true;
}
if (recalculateFaces === void 0) {
recalculateFaces = true;
}
if (!Array.isArray(indexes)) {
indexes = [indexes];
}
for (var ty = 0; ty < layer.height; ty++) {
for (var tx = 0; tx < layer.width; tx++) {
var tile = layer.data[ty][tx];
if (tile && indexes.indexOf(tile.index) === -1) {
SetTileCollision(tile, collides);
SetLayerCollisionIndex(tile.index, collides, layer);
}
}
}
if (recalculateFaces) {
CalculateFacesWithin(0, 0, layer.width, layer.height, layer);
}
};
module2.exports = SetCollisionByExclusion;
}
),
/***/
64740: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var SetTileCollision = __webpack_require__2(20576);
var CalculateFacesWithin = __webpack_require__2(42573);
var HasValue = __webpack_require__2(97022);
var SetCollisionByProperty = function(properties, collides, recalculateFaces, layer) {
if (collides === void 0) {
collides = true;
}
if (recalculateFaces === void 0) {
recalculateFaces = true;
}
for (var ty = 0; ty < layer.height; ty++) {
for (var tx = 0; tx < layer.width; tx++) {
var tile = layer.data[ty][tx];
if (!tile) {
continue;
}
for (var property in properties) {
if (!HasValue(tile.properties, property)) {
continue;
}
var values = properties[property];
if (!Array.isArray(values)) {
values = [values];
}
for (var i = 0; i < values.length; i++) {
if (tile.properties[property] === values[i]) {
SetTileCollision(tile, collides);
}
}
}
}
}
if (recalculateFaces) {
CalculateFacesWithin(0, 0, layer.width, layer.height, layer);
}
};
module2.exports = SetCollisionByProperty;
}
),
/***/
63307: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var SetTileCollision = __webpack_require__2(20576);
var CalculateFacesWithin = __webpack_require__2(42573);
var SetCollisionFromCollisionGroup = function(collides, recalculateFaces, layer) {
if (collides === void 0) {
collides = true;
}
if (recalculateFaces === void 0) {
recalculateFaces = true;
}
for (var ty = 0; ty < layer.height; ty++) {
for (var tx = 0; tx < layer.width; tx++) {
var tile = layer.data[ty][tx];
if (!tile) {
continue;
}
var collisionGroup = tile.getCollisionGroup();
if (collisionGroup && collisionGroup.objects && collisionGroup.objects.length > 0) {
SetTileCollision(tile, collides);
}
}
}
if (recalculateFaces) {
CalculateFacesWithin(0, 0, layer.width, layer.height, layer);
}
};
module2.exports = SetCollisionFromCollisionGroup;
}
),
/***/
9589: (
/***/
(module2) => {
var SetLayerCollisionIndex = function(tileIndex, collides, layer) {
var loc = layer.collideIndexes.indexOf(tileIndex);
if (collides && loc === -1) {
layer.collideIndexes.push(tileIndex);
} else if (!collides && loc !== -1) {
layer.collideIndexes.splice(loc, 1);
}
};
module2.exports = SetLayerCollisionIndex;
}
),
/***/
20576: (
/***/
(module2) => {
var SetTileCollision = function(tile, collides) {
if (collides) {
tile.setCollision(true, true, true, true, false);
} else {
tile.resetCollision(false);
}
};
module2.exports = SetTileCollision;
}
),
/***/
79583: (
/***/
(module2) => {
var SetTileIndexCallback = function(indexes, callback, callbackContext, layer) {
if (typeof indexes === "number") {
layer.callbacks[indexes] = callback !== null ? { callback, callbackContext } : void 0;
} else {
for (var i = 0, len = indexes.length; i < len; i++) {
layer.callbacks[indexes[i]] = callback !== null ? { callback, callbackContext } : void 0;
}
}
};
module2.exports = SetTileIndexCallback;
}
),
/***/
93254: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetTilesWithin = __webpack_require__2(7386);
var SetTileLocationCallback = function(tileX, tileY, width, height, callback, callbackContext, layer) {
var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer);
for (var i = 0; i < tiles.length; i++) {
tiles[i].setCollisionCallback(callback, callbackContext);
}
};
module2.exports = SetTileLocationCallback;
}
),
/***/
32903: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetTilesWithin = __webpack_require__2(7386);
var ShuffleArray = __webpack_require__2(33680);
var Shuffle = function(tileX, tileY, width, height, layer) {
var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer);
var indexes = tiles.map(function(tile) {
return tile.index;
});
ShuffleArray(indexes);
for (var i = 0; i < tiles.length; i++) {
tiles[i].index = indexes[i];
}
};
module2.exports = Shuffle;
}
),
/***/
61325: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var SnapCeil = __webpack_require__2(63448);
var SnapFloor = __webpack_require__2(56583);
var StaggeredCullBounds = function(layer, camera) {
var tilemap = layer.tilemapLayer.tilemap;
var tilemapLayer = layer.tilemapLayer;
var tileW = Math.floor(tilemap.tileWidth * tilemapLayer.scaleX);
var tileH = Math.floor(tilemap.tileHeight * tilemapLayer.scaleY);
var boundsLeft = SnapFloor(camera.worldView.x - tilemapLayer.x, tileW, 0, true) - tilemapLayer.cullPaddingX;
var boundsRight = SnapCeil(camera.worldView.right - tilemapLayer.x, tileW, 0, true) + tilemapLayer.cullPaddingX;
var boundsTop = SnapFloor(camera.worldView.y - tilemapLayer.y, tileH / 2, 0, true) - tilemapLayer.cullPaddingY;
var boundsBottom = SnapCeil(camera.worldView.bottom - tilemapLayer.y, tileH / 2, 0, true) + tilemapLayer.cullPaddingY;
return {
left: boundsLeft,
right: boundsRight,
top: boundsTop,
bottom: boundsBottom
};
};
module2.exports = StaggeredCullBounds;
}
),
/***/
54503: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CullBounds = __webpack_require__2(61325);
var RunCull = __webpack_require__2(32483);
var StaggeredCullTiles = function(layer, camera, outputArray, renderOrder) {
if (outputArray === void 0) {
outputArray = [];
}
if (renderOrder === void 0) {
renderOrder = 0;
}
outputArray.length = 0;
var tilemapLayer = layer.tilemapLayer;
var bounds = CullBounds(layer, camera);
if (tilemapLayer.skipCull && tilemapLayer.scrollFactorX === 1 && tilemapLayer.scrollFactorY === 1) {
bounds.left = 0;
bounds.right = layer.width;
bounds.top = 0;
bounds.bottom = layer.height;
}
RunCull(layer, bounds, renderOrder, outputArray);
return outputArray;
};
module2.exports = StaggeredCullTiles;
}
),
/***/
97202: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Vector2 = __webpack_require__2(26099);
var StaggeredTileToWorldXY = function(tileX, tileY, point, camera, layer) {
if (!point) {
point = new Vector2();
}
var tileWidth = layer.baseTileWidth;
var tileHeight = layer.baseTileHeight;
var tilemapLayer = layer.tilemapLayer;
var layerWorldX = 0;
var layerWorldY = 0;
if (tilemapLayer) {
if (!camera) {
camera = tilemapLayer.scene.cameras.main;
}
layerWorldX = tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX);
tileWidth *= tilemapLayer.scaleX;
layerWorldY = tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY);
tileHeight *= tilemapLayer.scaleY;
}
var x = layerWorldX + tileX * tileWidth + tileY % 2 * (tileWidth / 2);
var y = layerWorldY + tileY * (tileHeight / 2);
return point.set(x, y);
};
module2.exports = StaggeredTileToWorldXY;
}
),
/***/
28054: (
/***/
(module2) => {
var StaggeredTileToWorldY = function(tileY, camera, layer) {
var tileHeight = layer.baseTileHeight;
var tilemapLayer = layer.tilemapLayer;
var layerWorldY = 0;
if (tilemapLayer) {
if (camera === void 0) {
camera = tilemapLayer.scene.cameras.main;
}
layerWorldY = tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY);
tileHeight *= tilemapLayer.scaleY;
}
return layerWorldY + tileY * (tileHeight / 2) + tileHeight;
};
module2.exports = StaggeredTileToWorldY;
}
),
/***/
15108: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Vector2 = __webpack_require__2(26099);
var StaggeredWorldToTileXY = function(worldX, worldY, snapToFloor, point, camera, layer) {
if (!point) {
point = new Vector2();
}
var tileWidth = layer.baseTileWidth;
var tileHeight = layer.baseTileHeight;
var tilemapLayer = layer.tilemapLayer;
if (tilemapLayer) {
if (!camera) {
camera = tilemapLayer.scene.cameras.main;
}
worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY));
tileHeight *= tilemapLayer.scaleY;
worldX = worldX - (tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX));
tileWidth *= tilemapLayer.scaleX;
}
var y = snapToFloor ? Math.floor(worldY / (tileHeight / 2)) : worldY / (tileHeight / 2);
var x = snapToFloor ? Math.floor((worldX + y % 2 * 0.5 * tileWidth) / tileWidth) : (worldX + y % 2 * 0.5 * tileWidth) / tileWidth;
return point.set(x, y);
};
module2.exports = StaggeredWorldToTileXY;
}
),
/***/
51900: (
/***/
(module2) => {
var StaggeredWorldToTileY = function(worldY, snapToFloor, camera, layer) {
var tileHeight = layer.baseTileHeight;
var tilemapLayer = layer.tilemapLayer;
if (tilemapLayer) {
if (!camera) {
camera = tilemapLayer.scene.cameras.main;
}
worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY));
tileHeight *= tilemapLayer.scaleY;
}
return snapToFloor ? Math.floor(worldY / (tileHeight / 2)) : worldY / (tileHeight / 2);
};
module2.exports = StaggeredWorldToTileY;
}
),
/***/
86560: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetTilesWithin = __webpack_require__2(7386);
var SwapByIndex = function(indexA, indexB, tileX, tileY, width, height, layer) {
var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer);
for (var i = 0; i < tiles.length; i++) {
if (tiles[i]) {
if (tiles[i].index === indexA) {
tiles[i].index = indexB;
} else if (tiles[i].index === indexB) {
tiles[i].index = indexA;
}
}
}
};
module2.exports = SwapByIndex;
}
),
/***/
97281: (
/***/
(module2) => {
var TileToWorldX = function(tileX, camera, layer) {
var tileWidth = layer.baseTileWidth;
var tilemapLayer = layer.tilemapLayer;
var layerWorldX = 0;
if (tilemapLayer) {
if (!camera) {
camera = tilemapLayer.scene.cameras.main;
}
layerWorldX = tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX);
tileWidth *= tilemapLayer.scaleX;
}
return layerWorldX + tileX * tileWidth;
};
module2.exports = TileToWorldX;
}
),
/***/
70326: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var TileToWorldX = __webpack_require__2(97281);
var TileToWorldY = __webpack_require__2(29650);
var Vector2 = __webpack_require__2(26099);
var TileToWorldXY = function(tileX, tileY, point, camera, layer) {
if (!point) {
point = new Vector2(0, 0);
}
point.x = TileToWorldX(tileX, camera, layer);
point.y = TileToWorldY(tileY, camera, layer);
return point;
};
module2.exports = TileToWorldXY;
}
),
/***/
29650: (
/***/
(module2) => {
var TileToWorldY = function(tileY, camera, layer) {
var tileHeight = layer.baseTileHeight;
var tilemapLayer = layer.tilemapLayer;
var layerWorldY = 0;
if (tilemapLayer) {
if (!camera) {
camera = tilemapLayer.scene.cameras.main;
}
layerWorldY = tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY);
tileHeight *= tilemapLayer.scaleY;
}
return layerWorldY + tileY * tileHeight;
};
module2.exports = TileToWorldY;
}
),
/***/
77366: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetTilesWithin = __webpack_require__2(7386);
var MATH = __webpack_require__2(75508);
var WeightedRandomize = function(tileX, tileY, width, height, weightedIndexes, layer) {
if (!weightedIndexes) {
return;
}
var i;
var tiles = GetTilesWithin(tileX, tileY, width, height, null, layer);
var weightTotal = 0;
for (i = 0; i < weightedIndexes.length; i++) {
weightTotal += weightedIndexes[i].weight;
}
if (weightTotal <= 0) {
return;
}
for (i = 0; i < tiles.length; i++) {
var rand = MATH.RND.frac() * weightTotal;
var sum = 0;
var randomIndex = -1;
for (var j = 0; j < weightedIndexes.length; j++) {
sum += weightedIndexes[j].weight;
if (rand <= sum) {
var chosen = weightedIndexes[j].index;
randomIndex = Array.isArray(chosen) ? chosen[Math.floor(MATH.RND.frac() * chosen.length)] : chosen;
break;
}
}
tiles[i].index = randomIndex;
}
};
module2.exports = WeightedRandomize;
}
),
/***/
10095: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var WorldToTileXY = __webpack_require__2(85896);
var Vector2 = __webpack_require__2(26099);
var tempVec = new Vector2();
var WorldToTileX = function(worldX, snapToFloor, camera, layer) {
WorldToTileXY(worldX, 0, snapToFloor, tempVec, camera, layer);
return tempVec.x;
};
module2.exports = WorldToTileX;
}
),
/***/
85896: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Vector2 = __webpack_require__2(26099);
var WorldToTileXY = function(worldX, worldY, snapToFloor, point, camera, layer) {
if (snapToFloor === void 0) {
snapToFloor = true;
}
if (!point) {
point = new Vector2();
}
var tileWidth = layer.baseTileWidth;
var tileHeight = layer.baseTileHeight;
var tilemapLayer = layer.tilemapLayer;
if (tilemapLayer) {
if (!camera) {
camera = tilemapLayer.scene.cameras.main;
}
worldX = worldX - (tilemapLayer.x + camera.scrollX * (1 - tilemapLayer.scrollFactorX));
worldY = worldY - (tilemapLayer.y + camera.scrollY * (1 - tilemapLayer.scrollFactorY));
tileWidth *= tilemapLayer.scaleX;
tileHeight *= tilemapLayer.scaleY;
}
var x = worldX / tileWidth;
var y = worldY / tileHeight;
if (snapToFloor) {
x = Math.floor(x);
y = Math.floor(y);
}
return point.set(x, y);
};
module2.exports = WorldToTileXY;
}
),
/***/
63288: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var WorldToTileXY = __webpack_require__2(85896);
var Vector2 = __webpack_require__2(26099);
var tempVec = new Vector2();
var WorldToTileY = function(worldY, snapToFloor, camera, layer) {
WorldToTileXY(0, worldY, snapToFloor, tempVec, camera, layer);
return tempVec.y;
};
module2.exports = WorldToTileY;
}
),
/***/
81086: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
CalculateFacesAt: __webpack_require__2(72023),
CalculateFacesWithin: __webpack_require__2(42573),
CheckIsoBounds: __webpack_require__2(33528),
Copy: __webpack_require__2(1785),
CreateFromTiles: __webpack_require__2(78419),
CullBounds: __webpack_require__2(19545),
CullTiles: __webpack_require__2(30003),
Fill: __webpack_require__2(35137),
FilterTiles: __webpack_require__2(40253),
FindByIndex: __webpack_require__2(52692),
FindTile: __webpack_require__2(66151),
ForEachTile: __webpack_require__2(97560),
GetCullTilesFunction: __webpack_require__2(43305),
GetTileAt: __webpack_require__2(7423),
GetTileAtWorldXY: __webpack_require__2(60540),
GetTileCorners: __webpack_require__2(55826),
GetTileCornersFunction: __webpack_require__2(11758),
GetTilesWithin: __webpack_require__2(7386),
GetTilesWithinShape: __webpack_require__2(91141),
GetTilesWithinWorldXY: __webpack_require__2(96523),
GetTileToWorldXFunction: __webpack_require__2(39167),
GetTileToWorldXYFunction: __webpack_require__2(62e3),
GetTileToWorldYFunction: __webpack_require__2(5984),
GetWorldToTileXFunction: __webpack_require__2(96113),
GetWorldToTileXYFunction: __webpack_require__2(16926),
GetWorldToTileYFunction: __webpack_require__2(55762),
HasTileAt: __webpack_require__2(45091),
HasTileAtWorldXY: __webpack_require__2(24152),
HexagonalCullBounds: __webpack_require__2(90454),
HexagonalCullTiles: __webpack_require__2(9474),
HexagonalGetTileCorners: __webpack_require__2(27229),
HexagonalTileToWorldXY: __webpack_require__2(19951),
HexagonalWorldToTileXY: __webpack_require__2(86625),
IsInLayerBounds: __webpack_require__2(62991),
IsometricCullTiles: __webpack_require__2(14018),
IsometricTileToWorldXY: __webpack_require__2(14127),
IsometricWorldToTileXY: __webpack_require__2(96897),
PutTileAt: __webpack_require__2(71558),
PutTileAtWorldXY: __webpack_require__2(26303),
PutTilesAt: __webpack_require__2(14051),
Randomize: __webpack_require__2(77389),
RemoveTileAt: __webpack_require__2(63557),
RemoveTileAtWorldXY: __webpack_require__2(94178),
RenderDebug: __webpack_require__2(15533),
ReplaceByIndex: __webpack_require__2(27987),
RunCull: __webpack_require__2(32483),
SetCollision: __webpack_require__2(57068),
SetCollisionBetween: __webpack_require__2(37266),
SetCollisionByExclusion: __webpack_require__2(75661),
SetCollisionByProperty: __webpack_require__2(64740),
SetCollisionFromCollisionGroup: __webpack_require__2(63307),
SetLayerCollisionIndex: __webpack_require__2(9589),
SetTileCollision: __webpack_require__2(20576),
SetTileIndexCallback: __webpack_require__2(79583),
SetTileLocationCallback: __webpack_require__2(93254),
Shuffle: __webpack_require__2(32903),
StaggeredCullBounds: __webpack_require__2(61325),
StaggeredCullTiles: __webpack_require__2(54503),
StaggeredTileToWorldXY: __webpack_require__2(97202),
StaggeredTileToWorldY: __webpack_require__2(28054),
StaggeredWorldToTileXY: __webpack_require__2(15108),
StaggeredWorldToTileY: __webpack_require__2(51900),
SwapByIndex: __webpack_require__2(86560),
TileToWorldX: __webpack_require__2(97281),
TileToWorldXY: __webpack_require__2(70326),
TileToWorldY: __webpack_require__2(29650),
WeightedRandomize: __webpack_require__2(77366),
WorldToTileX: __webpack_require__2(10095),
WorldToTileXY: __webpack_require__2(85896),
WorldToTileY: __webpack_require__2(63288)
};
}
),
/***/
91907: (
/***/
(module2) => {
module2.exports = {
/**
* Orthogonal Tilemap orientation constant.
*
* @name Phaser.Tilemaps.Orientation.ORTHOGONAL
* @type {number}
* @const
* @since 3.50.0
*/
ORTHOGONAL: 0,
/**
* Isometric Tilemap orientation constant.
*
* @name Phaser.Tilemaps.Orientation.ISOMETRIC
* @type {number}
* @const
* @since 3.50.0
*/
ISOMETRIC: 1,
/**
* Staggered Tilemap orientation constant.
*
* @name Phaser.Tilemaps.Orientation.STAGGERED
* @type {number}
* @const
* @since 3.50.0
*/
STAGGERED: 2,
/**
* Hexagonal Tilemap orientation constant.
*
* @name Phaser.Tilemaps.Orientation.HEXAGONAL
* @type {number}
* @const
* @since 3.50.0
*/
HEXAGONAL: 3
};
}
),
/***/
21829: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = {
ORIENTATION: __webpack_require__2(91907)
};
module2.exports = CONST;
}
),
/***/
62501: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Extend = __webpack_require__2(79291);
var CONST = __webpack_require__2(21829);
var Tilemaps = {
Components: __webpack_require__2(81086),
Parsers: __webpack_require__2(57442),
Formats: __webpack_require__2(80341),
ImageCollection: __webpack_require__2(16536),
ParseToTilemap: __webpack_require__2(31989),
Tile: __webpack_require__2(23029),
Tilemap: __webpack_require__2(49075),
TilemapCreator: __webpack_require__2(45939),
TilemapFactory: __webpack_require__2(46029),
Tileset: __webpack_require__2(33629),
TilemapLayer: __webpack_require__2(20442),
Orientation: __webpack_require__2(91907),
LayerData: __webpack_require__2(14977),
MapData: __webpack_require__2(87010),
ObjectLayer: __webpack_require__2(48700)
};
Tilemaps = Extend(false, Tilemaps, CONST.ORIENTATION);
module2.exports = Tilemaps;
}
),
/***/
14977: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(91907);
var GetFastValue = __webpack_require__2(95540);
var LayerData = new Class({
initialize: function LayerData2(config) {
if (config === void 0) {
config = {};
}
this.name = GetFastValue(config, "name", "layer");
this.id = GetFastValue(config, "id", 0);
this.x = GetFastValue(config, "x", 0);
this.y = GetFastValue(config, "y", 0);
this.width = GetFastValue(config, "width", 0);
this.height = GetFastValue(config, "height", 0);
this.tileWidth = GetFastValue(config, "tileWidth", 0);
this.tileHeight = GetFastValue(config, "tileHeight", 0);
this.baseTileWidth = GetFastValue(config, "baseTileWidth", this.tileWidth);
this.baseTileHeight = GetFastValue(config, "baseTileHeight", this.tileHeight);
this.orientation = GetFastValue(config, "orientation", CONST.ORTHOGONAL);
this.widthInPixels = GetFastValue(config, "widthInPixels", this.width * this.baseTileWidth);
this.heightInPixels = GetFastValue(config, "heightInPixels", this.height * this.baseTileHeight);
this.alpha = GetFastValue(config, "alpha", 1);
this.visible = GetFastValue(config, "visible", true);
this.properties = GetFastValue(config, "properties", []);
this.indexes = GetFastValue(config, "indexes", []);
this.collideIndexes = GetFastValue(config, "collideIndexes", []);
this.callbacks = GetFastValue(config, "callbacks", []);
this.bodies = GetFastValue(config, "bodies", []);
this.data = GetFastValue(config, "data", []);
this.tilemapLayer = GetFastValue(config, "tilemapLayer", null);
this.hexSideLength = GetFastValue(config, "hexSideLength", 0);
this.staggerAxis = GetFastValue(config, "staggerAxis", "y");
this.staggerIndex = GetFastValue(config, "staggerIndex", "odd");
}
});
module2.exports = LayerData;
}
),
/***/
87010: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var CONST = __webpack_require__2(91907);
var GetFastValue = __webpack_require__2(95540);
var MapData = new Class({
initialize: function MapData2(config) {
if (config === void 0) {
config = {};
}
this.name = GetFastValue(config, "name", "map");
this.width = GetFastValue(config, "width", 0);
this.height = GetFastValue(config, "height", 0);
this.infinite = GetFastValue(config, "infinite", false);
this.tileWidth = GetFastValue(config, "tileWidth", 0);
this.tileHeight = GetFastValue(config, "tileHeight", 0);
this.widthInPixels = GetFastValue(config, "widthInPixels", this.width * this.tileWidth);
this.heightInPixels = GetFastValue(config, "heightInPixels", this.height * this.tileHeight);
this.format = GetFastValue(config, "format", null);
this.orientation = GetFastValue(config, "orientation", CONST.ORTHOGONAL);
this.renderOrder = GetFastValue(config, "renderOrder", "right-down");
this.version = GetFastValue(config, "version", "1");
this.properties = GetFastValue(config, "properties", {});
this.layers = GetFastValue(config, "layers", []);
this.images = GetFastValue(config, "images", []);
this.objects = GetFastValue(config, "objects", []);
if (!Array.isArray(this.objects)) {
this.objects = [];
}
this.collision = GetFastValue(config, "collision", {});
this.tilesets = GetFastValue(config, "tilesets", []);
this.imageCollections = GetFastValue(config, "imageCollections", []);
this.tiles = GetFastValue(config, "tiles", []);
this.hexSideLength = GetFastValue(config, "hexSideLength", 0);
this.staggerAxis = GetFastValue(config, "staggerAxis", "y");
this.staggerIndex = GetFastValue(config, "staggerIndex", "odd");
}
});
module2.exports = MapData;
}
),
/***/
48700: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var GetFastValue = __webpack_require__2(95540);
var ObjectLayer = new Class({
initialize: function ObjectLayer2(config) {
if (config === void 0) {
config = {};
}
this.name = GetFastValue(config, "name", "object layer");
this.id = GetFastValue(config, "id", 0);
this.opacity = GetFastValue(config, "opacity", 1);
this.properties = GetFastValue(config, "properties", {});
this.propertyTypes = GetFastValue(config, "propertytypes", {});
this.type = GetFastValue(config, "type", "objectgroup");
this.visible = GetFastValue(config, "visible", true);
this.objects = GetFastValue(config, "objects", []);
if (!Array.isArray(this.objects)) {
this.objects = [];
}
}
});
module2.exports = ObjectLayer;
}
),
/***/
6641: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CONST = __webpack_require__2(91907);
var FromOrientationString = function(orientation) {
orientation = orientation.toLowerCase();
if (orientation === "isometric") {
return CONST.ISOMETRIC;
} else if (orientation === "staggered") {
return CONST.STAGGERED;
} else if (orientation === "hexagonal") {
return CONST.HEXAGONAL;
} else {
return CONST.ORTHOGONAL;
}
};
module2.exports = FromOrientationString;
}
),
/***/
46177: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Formats = __webpack_require__2(80341);
var Parse2DArray = __webpack_require__2(2342);
var ParseCSV = __webpack_require__2(82593);
var ParseJSONTiled = __webpack_require__2(46594);
var ParseWeltmeister = __webpack_require__2(87021);
var Parse = function(name, mapFormat, data, tileWidth, tileHeight, insertNull) {
var newMap;
switch (mapFormat) {
case Formats.ARRAY_2D:
newMap = Parse2DArray(name, data, tileWidth, tileHeight, insertNull);
break;
case Formats.CSV:
newMap = ParseCSV(name, data, tileWidth, tileHeight, insertNull);
break;
case Formats.TILED_JSON:
newMap = ParseJSONTiled(name, data, insertNull);
break;
case Formats.WELTMEISTER:
newMap = ParseWeltmeister(name, data, insertNull);
break;
default:
console.warn("Unrecognized tilemap data format: " + mapFormat);
newMap = null;
}
return newMap;
};
module2.exports = Parse;
}
),
/***/
2342: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Formats = __webpack_require__2(80341);
var LayerData = __webpack_require__2(14977);
var MapData = __webpack_require__2(87010);
var Tile = __webpack_require__2(23029);
var Parse2DArray = function(name, data, tileWidth, tileHeight, insertNull) {
var layerData = new LayerData({
tileWidth,
tileHeight
});
var mapData = new MapData({
name,
tileWidth,
tileHeight,
format: Formats.ARRAY_2D,
layers: [layerData]
});
var tiles = [];
var height = data.length;
var width = 0;
for (var y = 0; y < data.length; y++) {
tiles[y] = [];
var row = data[y];
for (var x = 0; x < row.length; x++) {
var tileIndex = parseInt(row[x], 10);
if (isNaN(tileIndex) || tileIndex === -1) {
tiles[y][x] = insertNull ? null : new Tile(layerData, -1, x, y, tileWidth, tileHeight);
} else {
tiles[y][x] = new Tile(layerData, tileIndex, x, y, tileWidth, tileHeight);
}
}
if (width === 0) {
width = row.length;
}
}
mapData.width = layerData.width = width;
mapData.height = layerData.height = height;
mapData.widthInPixels = layerData.widthInPixels = width * tileWidth;
mapData.heightInPixels = layerData.heightInPixels = height * tileHeight;
layerData.data = tiles;
return mapData;
};
module2.exports = Parse2DArray;
}
),
/***/
82593: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Formats = __webpack_require__2(80341);
var Parse2DArray = __webpack_require__2(2342);
var ParseCSV = function(name, data, tileWidth, tileHeight, insertNull) {
var array2D = data.trim().split("\n").map(function(row) {
return row.split(",");
});
var map = Parse2DArray(name, array2D, tileWidth, tileHeight, insertNull);
map.format = Formats.CSV;
return map;
};
module2.exports = ParseCSV;
}
),
/***/
6656: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var LayerData = __webpack_require__2(14977);
var Tile = __webpack_require__2(23029);
var ParseTileLayers = function(json, insertNull) {
var tileLayers = [];
for (var i = 0; i < json.layer.length; i++) {
var layer = json.layer[i];
var layerData = new LayerData({
name: layer.name,
width: layer.width,
height: layer.height,
tileWidth: layer.tilesize,
tileHeight: layer.tilesize,
visible: layer.visible === 1
});
var row = [];
var tileGrid = [];
for (var y = 0; y < layer.data.length; y++) {
for (var x = 0; x < layer.data[y].length; x++) {
var index = layer.data[y][x] - 1;
var tile;
if (index > -1) {
tile = new Tile(layerData, index, x, y, layer.tilesize, layer.tilesize);
} else {
tile = insertNull ? null : new Tile(layerData, -1, x, y, layer.tilesize, layer.tilesize);
}
row.push(tile);
}
tileGrid.push(row);
row = [];
}
layerData.data = tileGrid;
tileLayers.push(layerData);
}
return tileLayers;
};
module2.exports = ParseTileLayers;
}
),
/***/
96483: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Tileset = __webpack_require__2(33629);
var ParseTilesets = function(json) {
var tilesets = [];
var tilesetsNames = [];
for (var i = 0; i < json.layer.length; i++) {
var layer = json.layer[i];
var tilesetName = layer.tilesetName;
if (tilesetName !== "" && tilesetsNames.indexOf(tilesetName) === -1) {
tilesetsNames.push(tilesetName);
tilesets.push(new Tileset(tilesetName, 0, layer.tilesize, layer.tilesize, 0, 0));
}
}
return tilesets;
};
module2.exports = ParseTilesets;
}
),
/***/
87021: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Formats = __webpack_require__2(80341);
var MapData = __webpack_require__2(87010);
var ParseTileLayers = __webpack_require__2(6656);
var ParseTilesets = __webpack_require__2(96483);
var ParseWeltmeister = function(name, json, insertNull) {
if (json.layer.length === 0) {
console.warn("No layers found in the Weltmeister map: " + name);
return null;
}
var width = 0;
var height = 0;
for (var i = 0; i < json.layer.length; i++) {
if (json.layer[i].width > width) {
width = json.layer[i].width;
}
if (json.layer[i].height > height) {
height = json.layer[i].height;
}
}
var mapData = new MapData({
width,
height,
name,
tileWidth: json.layer[0].tilesize,
tileHeight: json.layer[0].tilesize,
format: Formats.WELTMEISTER
});
mapData.layers = ParseTileLayers(json, insertNull);
mapData.tilesets = ParseTilesets(json);
return mapData;
};
module2.exports = ParseWeltmeister;
}
),
/***/
52833: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
ParseTileLayers: __webpack_require__2(6656),
ParseTilesets: __webpack_require__2(96483),
ParseWeltmeister: __webpack_require__2(87021)
};
}
),
/***/
57442: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
FromOrientationString: __webpack_require__2(6641),
Parse: __webpack_require__2(46177),
Parse2DArray: __webpack_require__2(2342),
ParseCSV: __webpack_require__2(82593),
Impact: __webpack_require__2(52833),
Tiled: __webpack_require__2(96761)
};
}
),
/***/
51233: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Extend = __webpack_require__2(79291);
var AssignTileProperties = function(mapData) {
var layerData;
var tile;
var sid;
var set;
var row;
for (var i = 0; i < mapData.layers.length; i++) {
layerData = mapData.layers[i];
set = null;
for (var j = 0; j < layerData.data.length; j++) {
row = layerData.data[j];
for (var k = 0; k < row.length; k++) {
tile = row[k];
if (tile === null || tile.index < 0) {
continue;
}
sid = mapData.tiles[tile.index][2];
set = mapData.tilesets[sid];
tile.width = set.tileWidth;
tile.height = set.tileHeight;
if (set.tileProperties && set.tileProperties[tile.index - set.firstgid]) {
tile.properties = Extend(
tile.properties,
set.tileProperties[tile.index - set.firstgid]
);
}
}
}
}
};
module2.exports = AssignTileProperties;
}
),
/***/
41868: (
/***/
(module2) => {
var Base64Decode = function(data) {
var binaryString = window.atob(data);
var len = binaryString.length;
var bytes = new Array(len / 4);
for (var i = 0; i < len; i += 4) {
bytes[i / 4] = (binaryString.charCodeAt(i) | binaryString.charCodeAt(i + 1) << 8 | binaryString.charCodeAt(i + 2) << 16 | binaryString.charCodeAt(i + 3) << 24) >>> 0;
}
return bytes;
};
module2.exports = Base64Decode;
}
),
/***/
84101: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Tileset = __webpack_require__2(33629);
var BuildTilesetIndex = function(mapData) {
var i;
var set;
var tiles = [];
for (i = 0; i < mapData.imageCollections.length; i++) {
var collection = mapData.imageCollections[i];
var images = collection.images;
for (var j = 0; j < images.length; j++) {
var image = images[j];
set = new Tileset(image.image, image.gid, collection.imageWidth, collection.imageHeight, 0, 0);
set.updateTileData(collection.imageWidth, collection.imageHeight);
mapData.tilesets.push(set);
}
}
for (i = 0; i < mapData.tilesets.length; i++) {
set = mapData.tilesets[i];
var x = set.tileMargin;
var y = set.tileMargin;
var count = 0;
var countX = 0;
var countY = 0;
for (var t = set.firstgid; t < set.firstgid + set.total; t++) {
tiles[t] = [x, y, i];
x += set.tileWidth + set.tileSpacing;
count++;
if (count === set.total) {
break;
}
countX++;
if (countX === set.columns) {
x = set.tileMargin;
y += set.tileHeight + set.tileSpacing;
countX = 0;
countY++;
if (countY === set.rows) {
break;
}
}
}
}
return tiles;
};
module2.exports = BuildTilesetIndex;
}
),
/***/
79677: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetFastValue = __webpack_require__2(95540);
var CreateGroupLayer = function(json, group, parentState) {
if (!group) {
return {
i: 0,
// Current layer array iterator
layers: json.layers,
// Current array of layers
// Values inherited from parent group
name: "",
opacity: 1,
visible: true,
x: 0,
y: 0
};
}
var layerX = group.x + GetFastValue(group, "startx", 0) * json.tilewidth + GetFastValue(group, "offsetx", 0);
var layerY = group.y + GetFastValue(group, "starty", 0) * json.tileheight + GetFastValue(group, "offsety", 0);
return {
i: 0,
layers: group.layers,
name: parentState.name + group.name + "/",
opacity: parentState.opacity * group.opacity,
visible: parentState.visible && group.visible,
x: parentState.x + layerX,
y: parentState.y + layerY
};
};
module2.exports = CreateGroupLayer;
}
),
/***/
29920: (
/***/
(module2) => {
var FLIPPED_HORIZONTAL = 2147483648;
var FLIPPED_VERTICAL = 1073741824;
var FLIPPED_ANTI_DIAGONAL = 536870912;
var ParseGID = function(gid) {
var flippedHorizontal = Boolean(gid & FLIPPED_HORIZONTAL);
var flippedVertical = Boolean(gid & FLIPPED_VERTICAL);
var flippedAntiDiagonal = Boolean(gid & FLIPPED_ANTI_DIAGONAL);
gid = gid & ~(FLIPPED_HORIZONTAL | FLIPPED_VERTICAL | FLIPPED_ANTI_DIAGONAL);
var rotation = 0;
var flipped = false;
if (flippedHorizontal && flippedVertical && flippedAntiDiagonal) {
rotation = Math.PI / 2;
flipped = true;
} else if (flippedHorizontal && flippedVertical && !flippedAntiDiagonal) {
rotation = Math.PI;
flipped = false;
} else if (flippedHorizontal && !flippedVertical && flippedAntiDiagonal) {
rotation = Math.PI / 2;
flipped = false;
} else if (flippedHorizontal && !flippedVertical && !flippedAntiDiagonal) {
rotation = 0;
flipped = true;
} else if (!flippedHorizontal && flippedVertical && flippedAntiDiagonal) {
rotation = 3 * Math.PI / 2;
flipped = false;
} else if (!flippedHorizontal && flippedVertical && !flippedAntiDiagonal) {
rotation = Math.PI;
flipped = true;
} else if (!flippedHorizontal && !flippedVertical && flippedAntiDiagonal) {
rotation = 3 * Math.PI / 2;
flipped = true;
} else if (!flippedHorizontal && !flippedVertical && !flippedAntiDiagonal) {
rotation = 0;
flipped = false;
}
return {
gid,
flippedHorizontal,
flippedVertical,
flippedAntiDiagonal,
rotation,
flipped
};
};
module2.exports = ParseGID;
}
),
/***/
12635: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetFastValue = __webpack_require__2(95540);
var CreateGroupLayer = __webpack_require__2(79677);
var ParseImageLayers = function(json) {
var images = [];
var groupStack = [];
var curGroupState = CreateGroupLayer(json);
while (curGroupState.i < curGroupState.layers.length || groupStack.length > 0) {
if (curGroupState.i >= curGroupState.layers.length) {
if (groupStack.length < 1) {
console.warn(
"TilemapParser.parseTiledJSON - Invalid layer group hierarchy"
);
break;
}
curGroupState = groupStack.pop();
continue;
}
var curi = curGroupState.layers[curGroupState.i];
curGroupState.i++;
if (curi.type !== "imagelayer") {
if (curi.type === "group") {
var nextGroupState = CreateGroupLayer(json, curi, curGroupState);
groupStack.push(curGroupState);
curGroupState = nextGroupState;
}
continue;
}
var layerOffsetX = GetFastValue(curi, "offsetx", 0) + GetFastValue(curi, "startx", 0);
var layerOffsetY = GetFastValue(curi, "offsety", 0) + GetFastValue(curi, "starty", 0);
images.push({
name: curGroupState.name + curi.name,
image: curi.image,
x: curGroupState.x + layerOffsetX + curi.x,
y: curGroupState.y + layerOffsetY + curi.y,
alpha: curGroupState.opacity * curi.opacity,
visible: curGroupState.visible && curi.visible,
properties: GetFastValue(curi, "properties", {})
});
}
return images;
};
module2.exports = ParseImageLayers;
}
),
/***/
46594: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var AssignTileProperties = __webpack_require__2(51233);
var BuildTilesetIndex = __webpack_require__2(84101);
var CONST = __webpack_require__2(91907);
var DeepCopy = __webpack_require__2(62644);
var Formats = __webpack_require__2(80341);
var FromOrientationString = __webpack_require__2(6641);
var MapData = __webpack_require__2(87010);
var ParseImageLayers = __webpack_require__2(12635);
var ParseObjectLayers = __webpack_require__2(22611);
var ParseTileLayers = __webpack_require__2(28200);
var ParseTilesets = __webpack_require__2(24619);
var ParseJSONTiled = function(name, source, insertNull) {
var json = DeepCopy(source);
var mapData = new MapData({
width: json.width,
height: json.height,
name,
tileWidth: json.tilewidth,
tileHeight: json.tileheight,
orientation: FromOrientationString(json.orientation),
format: Formats.TILED_JSON,
version: json.version,
properties: json.properties,
renderOrder: json.renderorder,
infinite: json.infinite
});
if (mapData.orientation === CONST.HEXAGONAL) {
mapData.hexSideLength = json.hexsidelength;
mapData.staggerAxis = json.staggeraxis;
mapData.staggerIndex = json.staggerindex;
}
mapData.layers = ParseTileLayers(json, insertNull);
mapData.images = ParseImageLayers(json);
var sets = ParseTilesets(json);
mapData.tilesets = sets.tilesets;
mapData.imageCollections = sets.imageCollections;
mapData.objects = ParseObjectLayers(json);
mapData.tiles = BuildTilesetIndex(mapData);
AssignTileProperties(mapData);
return mapData;
};
module2.exports = ParseJSONTiled;
}
),
/***/
52205: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Pick = __webpack_require__2(18254);
var ParseGID = __webpack_require__2(29920);
var copyPoints = function(p) {
return { x: p.x, y: p.y };
};
var commonObjectProps = ["id", "name", "type", "rotation", "properties", "visible", "x", "y", "width", "height"];
var ParseObject = function(tiledObject, offsetX, offsetY) {
if (offsetX === void 0) {
offsetX = 0;
}
if (offsetY === void 0) {
offsetY = 0;
}
var parsedObject = Pick(tiledObject, commonObjectProps);
parsedObject.x += offsetX;
parsedObject.y += offsetY;
if (tiledObject.gid) {
var gidInfo = ParseGID(tiledObject.gid);
parsedObject.gid = gidInfo.gid;
parsedObject.flippedHorizontal = gidInfo.flippedHorizontal;
parsedObject.flippedVertical = gidInfo.flippedVertical;
parsedObject.flippedAntiDiagonal = gidInfo.flippedAntiDiagonal;
} else if (tiledObject.polyline) {
parsedObject.polyline = tiledObject.polyline.map(copyPoints);
} else if (tiledObject.polygon) {
parsedObject.polygon = tiledObject.polygon.map(copyPoints);
} else if (tiledObject.ellipse) {
parsedObject.ellipse = tiledObject.ellipse;
} else if (tiledObject.text) {
parsedObject.text = tiledObject.text;
} else if (tiledObject.point) {
parsedObject.point = true;
} else {
parsedObject.rectangle = true;
}
return parsedObject;
};
module2.exports = ParseObject;
}
),
/***/
22611: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetFastValue = __webpack_require__2(95540);
var ParseObject = __webpack_require__2(52205);
var ObjectLayer = __webpack_require__2(48700);
var CreateGroupLayer = __webpack_require__2(79677);
var ParseObjectLayers = function(json) {
var objectLayers = [];
var groupStack = [];
var curGroupState = CreateGroupLayer(json);
while (curGroupState.i < curGroupState.layers.length || groupStack.length > 0) {
if (curGroupState.i >= curGroupState.layers.length) {
if (groupStack.length < 1) {
console.warn(
"TilemapParser.parseTiledJSON - Invalid layer group hierarchy"
);
break;
}
curGroupState = groupStack.pop();
continue;
}
var curo = curGroupState.layers[curGroupState.i];
curGroupState.i++;
curo.opacity *= curGroupState.opacity;
curo.visible = curGroupState.visible && curo.visible;
if (curo.type !== "objectgroup") {
if (curo.type === "group") {
var nextGroupState = CreateGroupLayer(json, curo, curGroupState);
groupStack.push(curGroupState);
curGroupState = nextGroupState;
}
continue;
}
curo.name = curGroupState.name + curo.name;
var offsetX = curGroupState.x + GetFastValue(curo, "startx", 0) + GetFastValue(curo, "offsetx", 0);
var offsetY = curGroupState.y + GetFastValue(curo, "starty", 0) + GetFastValue(curo, "offsety", 0);
var objects = [];
for (var j = 0; j < curo.objects.length; j++) {
var parsedObject = ParseObject(curo.objects[j], offsetX, offsetY);
objects.push(parsedObject);
}
var objectLayer = new ObjectLayer(curo);
objectLayer.objects = objects;
objectLayers.push(objectLayer);
}
return objectLayers;
};
module2.exports = ParseObjectLayers;
}
),
/***/
28200: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Base64Decode = __webpack_require__2(41868);
var CONST = __webpack_require__2(91907);
var CreateGroupLayer = __webpack_require__2(79677);
var FromOrientationString = __webpack_require__2(6641);
var GetFastValue = __webpack_require__2(95540);
var LayerData = __webpack_require__2(14977);
var ParseGID = __webpack_require__2(29920);
var Tile = __webpack_require__2(23029);
var ParseTileLayers = function(json, insertNull) {
var infiniteMap = GetFastValue(json, "infinite", false);
var tileLayers = [];
var groupStack = [];
var curGroupState = CreateGroupLayer(json);
while (curGroupState.i < curGroupState.layers.length || groupStack.length > 0) {
if (curGroupState.i >= curGroupState.layers.length) {
if (groupStack.length < 1) {
console.warn(
"TilemapParser.parseTiledJSON - Invalid layer group hierarchy"
);
break;
}
curGroupState = groupStack.pop();
continue;
}
var curl = curGroupState.layers[curGroupState.i];
curGroupState.i++;
if (curl.type !== "tilelayer") {
if (curl.type === "group") {
var nextGroupState = CreateGroupLayer(json, curl, curGroupState);
groupStack.push(curGroupState);
curGroupState = nextGroupState;
}
continue;
}
if (curl.compression) {
console.warn(
"TilemapParser.parseTiledJSON - Layer compression is unsupported, skipping layer '" + curl.name + "'"
);
continue;
} else if (curl.encoding && curl.encoding === "base64") {
if (curl.chunks) {
for (var i = 0; i < curl.chunks.length; i++) {
curl.chunks[i].data = Base64Decode(curl.chunks[i].data);
}
}
if (curl.data) {
curl.data = Base64Decode(curl.data);
}
delete curl.encoding;
}
var layerData;
var gidInfo;
var tile;
var blankTile;
var output = [];
var x = 0;
if (infiniteMap) {
var layerOffsetX = GetFastValue(curl, "startx", 0) + curl.x;
var layerOffsetY = GetFastValue(curl, "starty", 0) + curl.y;
layerData = new LayerData({
name: curGroupState.name + curl.name,
id: curl.id,
x: curGroupState.x + GetFastValue(curl, "offsetx", 0) + layerOffsetX * json.tilewidth,
y: curGroupState.y + GetFastValue(curl, "offsety", 0) + layerOffsetY * json.tileheight,
width: curl.width,
height: curl.height,
tileWidth: json.tilewidth,
tileHeight: json.tileheight,
alpha: curGroupState.opacity * curl.opacity,
visible: curGroupState.visible && curl.visible,
properties: GetFastValue(curl, "properties", []),
orientation: FromOrientationString(json.orientation)
});
if (layerData.orientation === CONST.HEXAGONAL) {
layerData.hexSideLength = json.hexsidelength;
layerData.staggerAxis = json.staggeraxis;
layerData.staggerIndex = json.staggerindex;
}
for (var c = 0; c < curl.height; c++) {
output[c] = [null];
for (var j = 0; j < curl.width; j++) {
output[c][j] = null;
}
}
for (c = 0, len = curl.chunks.length; c < len; c++) {
var chunk = curl.chunks[c];
var offsetX = chunk.x - layerOffsetX;
var offsetY = chunk.y - layerOffsetY;
var y = 0;
for (var t = 0, len2 = chunk.data.length; t < len2; t++) {
var newOffsetX = x + offsetX;
var newOffsetY = y + offsetY;
gidInfo = ParseGID(chunk.data[t]);
if (gidInfo.gid > 0) {
tile = new Tile(layerData, gidInfo.gid, newOffsetX, newOffsetY, json.tilewidth, json.tileheight);
tile.rotation = gidInfo.rotation;
tile.flipX = gidInfo.flipped;
output[newOffsetY][newOffsetX] = tile;
} else {
blankTile = insertNull ? null : new Tile(layerData, -1, newOffsetX, newOffsetY, json.tilewidth, json.tileheight);
output[newOffsetY][newOffsetX] = blankTile;
}
x++;
if (x === chunk.width) {
y++;
x = 0;
}
}
}
} else {
layerData = new LayerData({
name: curGroupState.name + curl.name,
id: curl.id,
x: curGroupState.x + GetFastValue(curl, "offsetx", 0) + curl.x,
y: curGroupState.y + GetFastValue(curl, "offsety", 0) + curl.y,
width: curl.width,
height: curl.height,
tileWidth: json.tilewidth,
tileHeight: json.tileheight,
alpha: curGroupState.opacity * curl.opacity,
visible: curGroupState.visible && curl.visible,
properties: GetFastValue(curl, "properties", []),
orientation: FromOrientationString(json.orientation)
});
if (layerData.orientation === CONST.HEXAGONAL) {
layerData.hexSideLength = json.hexsidelength;
layerData.staggerAxis = json.staggeraxis;
layerData.staggerIndex = json.staggerindex;
}
var row = [];
for (var k = 0, len = curl.data.length; k < len; k++) {
gidInfo = ParseGID(curl.data[k]);
if (gidInfo.gid > 0) {
tile = new Tile(layerData, gidInfo.gid, x, output.length, json.tilewidth, json.tileheight);
tile.rotation = gidInfo.rotation;
tile.flipX = gidInfo.flipped;
row.push(tile);
} else {
blankTile = insertNull ? null : new Tile(layerData, -1, x, output.length, json.tilewidth, json.tileheight);
row.push(blankTile);
}
x++;
if (x === curl.width) {
output.push(row);
x = 0;
row = [];
}
}
}
layerData.data = output;
tileLayers.push(layerData);
}
return tileLayers;
};
module2.exports = ParseTileLayers;
}
),
/***/
24619: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Tileset = __webpack_require__2(33629);
var ImageCollection = __webpack_require__2(16536);
var ParseObject = __webpack_require__2(52205);
var ParseWangsets = __webpack_require__2(57880);
var ParseTilesets = function(json) {
var tilesets = [];
var imageCollections = [];
var lastSet = null;
var stringID;
for (var i = 0; i < json.tilesets.length; i++) {
var set = json.tilesets[i];
if (set.source) {
console.warn("External tilesets unsupported. Use Embed Tileset and re-export");
} else if (set.image) {
var newSet = new Tileset(set.name, set.firstgid, set.tilewidth, set.tileheight, set.margin, set.spacing, void 0, void 0, set.tileoffset);
if (json.version > 1) {
var datas = void 0;
var props = void 0;
if (Array.isArray(set.tiles)) {
datas = datas || {};
props = props || {};
for (var t = 0; t < set.tiles.length; t++) {
var tile = set.tiles[t];
if (tile.properties) {
var newPropData = {};
tile.properties.forEach(function(propData) {
newPropData[propData["name"]] = propData["value"];
});
props[tile.id] = newPropData;
}
if (tile.objectgroup) {
(datas[tile.id] || (datas[tile.id] = {})).objectgroup = tile.objectgroup;
if (tile.objectgroup.objects) {
var parsedObjects2 = tile.objectgroup.objects.map(function(obj) {
return ParseObject(obj);
});
datas[tile.id].objectgroup.objects = parsedObjects2;
}
}
if (tile.animation) {
(datas[tile.id] || (datas[tile.id] = {})).animation = tile.animation;
}
if (tile.type) {
(datas[tile.id] || (datas[tile.id] = {})).type = tile.type;
}
}
}
if (Array.isArray(set.wangsets)) {
datas = datas || {};
props = props || {};
ParseWangsets(set.wangsets, datas);
}
if (datas) {
newSet.tileData = datas;
newSet.tileProperties = props;
}
} else {
if (set.tileproperties) {
newSet.tileProperties = set.tileproperties;
}
if (set.tiles) {
newSet.tileData = set.tiles;
for (stringID in newSet.tileData) {
var objectGroup = newSet.tileData[stringID].objectgroup;
if (objectGroup && objectGroup.objects) {
var parsedObjects1 = objectGroup.objects.map(function(obj) {
return ParseObject(obj);
});
newSet.tileData[stringID].objectgroup.objects = parsedObjects1;
}
}
}
}
newSet.updateTileData(set.imagewidth, set.imageheight);
tilesets.push(newSet);
} else {
var newCollection = new ImageCollection(set.name, set.firstgid, set.tilewidth, set.tileheight, set.margin, set.spacing, set.properties);
var maxId = 0;
for (t = 0; t < set.tiles.length; t++) {
tile = set.tiles[t];
var image = tile.image;
var tileId = parseInt(tile.id, 10);
var gid = set.firstgid + tileId;
newCollection.addImage(gid, image);
maxId = Math.max(tileId, maxId);
}
newCollection.maxId = maxId;
imageCollections.push(newCollection);
}
if (lastSet) {
lastSet.lastgid = set.firstgid - 1;
}
lastSet = set;
}
return { tilesets, imageCollections };
};
module2.exports = ParseTilesets;
}
),
/***/
57880: (
/***/
(module2) => {
var ParseWangsets = function(wangsets, datas) {
for (var w = 0; w < wangsets.length; w++) {
var wangset = wangsets[w];
var identifier = w;
if (wangset.name && wangset.name !== "") {
identifier = wangset.name;
}
if (Array.isArray(wangset.wangtiles) && wangset.wangtiles.length > 0) {
var edgeColors = {};
var cornerColors = {};
var c;
var color;
var colorIndex;
if (Array.isArray(wangset.edgecolors)) {
for (c = 0; c < wangset.edgecolors.length; c++) {
colorIndex = 1 + c;
color = wangset.edgecolors[c];
if (color.name !== "") {
edgeColors[colorIndex] = color.name;
}
}
}
if (Array.isArray(wangset.cornercolors)) {
for (c = 0; c < wangset.cornercolors.length; c++) {
colorIndex = 1 + c;
color = wangset.cornercolors[c];
if (color.name !== "") {
cornerColors[colorIndex] = color.name;
}
}
}
if (Array.isArray(wangset.colors)) {
for (c = 0; c < wangset.colors.length; c++) {
color = wangset.colors[c];
colorIndex = 1 + c;
if (color.name !== "") {
edgeColors[colorIndex] = cornerColors[colorIndex] = color.name;
}
}
}
var idLayout = [
edgeColors,
cornerColors,
edgeColors,
cornerColors,
edgeColors,
cornerColors,
edgeColors,
cornerColors
];
for (var t = 0; t < wangset.wangtiles.length; t++) {
var wangtile = wangset.wangtiles[t];
var obj = datas[wangtile.tileid] || (datas[wangtile.tileid] = {});
obj = obj.wangid || (obj.wangid = {});
var wangid = [];
for (var i = 0; i < Math.min(idLayout.length, wangtile.wangid.length); i++) {
color = wangtile.wangid[i];
if (color === 0) {
wangid.push(void 0);
continue;
}
var renamed = idLayout[i][color];
if (renamed !== void 0) {
wangid.push(renamed);
continue;
}
wangid.push(color);
}
obj[identifier] = wangid;
}
}
}
};
module2.exports = ParseWangsets;
}
),
/***/
96761: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
AssignTileProperties: __webpack_require__2(51233),
Base64Decode: __webpack_require__2(41868),
BuildTilesetIndex: __webpack_require__2(84101),
CreateGroupLayer: __webpack_require__2(79677),
ParseGID: __webpack_require__2(29920),
ParseImageLayers: __webpack_require__2(12635),
ParseJSONTiled: __webpack_require__2(46594),
ParseObject: __webpack_require__2(52205),
ParseObjectLayers: __webpack_require__2(22611),
ParseTileLayers: __webpack_require__2(28200),
ParseTilesets: __webpack_require__2(24619)
};
}
),
/***/
33385: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var PluginCache = __webpack_require__2(37277);
var SceneEvents = __webpack_require__2(44594);
var TimerEvent = __webpack_require__2(94880);
var Remove = __webpack_require__2(72905);
var Clock = new Class({
initialize: function Clock2(scene) {
this.scene = scene;
this.systems = scene.sys;
this.now = 0;
this.startTime = 0;
this.timeScale = 1;
this.paused = false;
this._active = [];
this._pendingInsertion = [];
this._pendingRemoval = [];
scene.sys.events.once(SceneEvents.BOOT, this.boot, this);
scene.sys.events.on(SceneEvents.START, this.start, this);
},
/**
* This method is called automatically, only once, when the Scene is first created.
* Do not invoke it directly.
*
* @method Phaser.Time.Clock#boot
* @private
* @since 3.5.1
*/
boot: function() {
this.now = this.systems.game.loop.time;
this.systems.events.once(SceneEvents.DESTROY, this.destroy, this);
},
/**
* This method is called automatically by the Scene when it is starting up.
* It is responsible for creating local systems, properties and listening for Scene events.
* Do not invoke it directly.
*
* @method Phaser.Time.Clock#start
* @private
* @since 3.5.0
*/
start: function() {
this.startTime = this.systems.game.loop.time;
var eventEmitter = this.systems.events;
eventEmitter.on(SceneEvents.PRE_UPDATE, this.preUpdate, this);
eventEmitter.on(SceneEvents.UPDATE, this.update, this);
eventEmitter.once(SceneEvents.SHUTDOWN, this.shutdown, this);
},
/**
* Creates a Timer Event and adds it to this Clock at the start of the next frame.
*
* You can pass in either a `TimerEventConfig` object, from with a new `TimerEvent` will
* be created, or you can pass in a `TimerEvent` instance.
*
* If passing an instance please make sure that this instance hasn't been used before.
* If it has ever entered a 'completed' state then it will no longer be suitable to
* run again.
*
* Also, if the `TimerEvent` instance is being used by _another_ Clock (in another Scene)
* it will still be updated by that Clock as well, so be careful when using this feature.
*
* @method Phaser.Time.Clock#addEvent
* @since 3.0.0
*
* @param {(Phaser.Time.TimerEvent | Phaser.Types.Time.TimerEventConfig)} config - The configuration for the Timer Event, or an existing Timer Event object.
*
* @return {Phaser.Time.TimerEvent} The Timer Event which was created, or passed in.
*/
addEvent: function(config) {
var event;
if (config instanceof TimerEvent) {
event = config;
this.removeEvent(event);
event.elapsed = event.startAt;
event.hasDispatched = false;
event.repeatCount = event.repeat === -1 || event.loop ? 999999999999 : event.repeat;
} else {
event = new TimerEvent(config);
}
this._pendingInsertion.push(event);
return event;
},
/**
* Creates a Timer Event and adds it to the Clock at the start of the frame.
*
* This is a shortcut for {@link #addEvent} which can be shorter and is compatible with the syntax of the GreenSock Animation Platform (GSAP).
*
* @method Phaser.Time.Clock#delayedCall
* @since 3.0.0
*
* @param {number} delay - The delay of the function call, in milliseconds.
* @param {function} callback - The function to call after the delay expires.
* @param {Array.<*>} [args] - The arguments to call the function with.
* @param {*} [callbackScope] - The scope (`this` object) to call the function with.
*
* @return {Phaser.Time.TimerEvent} The Timer Event which was created.
*/
delayedCall: function(delay, callback, args, callbackScope) {
return this.addEvent({ delay, callback, args, callbackScope });
},
/**
* Clears and recreates the array of pending Timer Events.
*
* @method Phaser.Time.Clock#clearPendingEvents
* @since 3.0.0
*
* @return {this} - This Clock instance.
*/
clearPendingEvents: function() {
this._pendingInsertion = [];
return this;
},
/**
* Removes the given Timer Event, or an array of Timer Events, from this Clock.
*
* The events are removed from all internal lists (active, pending and removal),
* freeing the event up to be re-used.
*
* @method Phaser.Time.Clock#removeEvent
* @since 3.50.0
*
* @param {(Phaser.Time.TimerEvent | Phaser.Time.TimerEvent[])} events - The Timer Event, or an array of Timer Events, to remove from this Clock.
*
* @return {this} - This Clock instance.
*/
removeEvent: function(events) {
if (!Array.isArray(events)) {
events = [events];
}
for (var i = 0; i < events.length; i++) {
var event = events[i];
Remove(this._pendingRemoval, event);
Remove(this._pendingInsertion, event);
Remove(this._active, event);
}
return this;
},
/**
* Schedules all active Timer Events for removal at the start of the frame.
*
* @method Phaser.Time.Clock#removeAllEvents
* @since 3.0.0
*
* @return {this} - This Clock instance.
*/
removeAllEvents: function() {
this._pendingRemoval = this._pendingRemoval.concat(this._active);
return this;
},
/**
* Updates the arrays of active and pending Timer Events. Called at the start of the frame.
*
* @method Phaser.Time.Clock#preUpdate
* @since 3.0.0
*
* @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout.
* @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
*/
preUpdate: function() {
var toRemove = this._pendingRemoval.length;
var toInsert = this._pendingInsertion.length;
if (toRemove === 0 && toInsert === 0) {
return;
}
var i;
var event;
for (i = 0; i < toRemove; i++) {
event = this._pendingRemoval[i];
var index = this._active.indexOf(event);
if (index > -1) {
this._active.splice(index, 1);
}
event.destroy();
}
for (i = 0; i < toInsert; i++) {
event = this._pendingInsertion[i];
this._active.push(event);
}
this._pendingRemoval.length = 0;
this._pendingInsertion.length = 0;
},
/**
* Updates the Clock's internal time and all of its Timer Events.
*
* @method Phaser.Time.Clock#update
* @since 3.0.0
*
* @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout.
* @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
*/
update: function(time, delta) {
this.now = time;
if (this.paused) {
return;
}
delta *= this.timeScale;
for (var i = 0; i < this._active.length; i++) {
var event = this._active[i];
if (event.paused) {
continue;
}
event.elapsed += delta * event.timeScale;
if (event.elapsed >= event.delay) {
var remainder = event.elapsed - event.delay;
event.elapsed = event.delay;
if (!event.hasDispatched && event.callback) {
event.hasDispatched = true;
event.callback.apply(event.callbackScope, event.args);
}
if (event.repeatCount > 0) {
event.repeatCount--;
if (remainder >= event.delay) {
while (remainder >= event.delay && event.repeatCount > 0) {
if (event.callback) {
event.callback.apply(event.callbackScope, event.args);
}
remainder -= event.delay;
event.repeatCount--;
}
}
event.elapsed = remainder;
event.hasDispatched = false;
} else if (event.hasDispatched) {
this._pendingRemoval.push(event);
}
}
}
},
/**
* The Scene that owns this plugin is shutting down.
* We need to kill and reset all internal properties as well as stop listening to Scene events.
*
* @method Phaser.Time.Clock#shutdown
* @private
* @since 3.0.0
*/
shutdown: function() {
var i;
for (i = 0; i < this._pendingInsertion.length; i++) {
this._pendingInsertion[i].destroy();
}
for (i = 0; i < this._active.length; i++) {
this._active[i].destroy();
}
for (i = 0; i < this._pendingRemoval.length; i++) {
this._pendingRemoval[i].destroy();
}
this._active.length = 0;
this._pendingRemoval.length = 0;
this._pendingInsertion.length = 0;
var eventEmitter = this.systems.events;
eventEmitter.off(SceneEvents.PRE_UPDATE, this.preUpdate, this);
eventEmitter.off(SceneEvents.UPDATE, this.update, this);
eventEmitter.off(SceneEvents.SHUTDOWN, this.shutdown, this);
},
/**
* The Scene that owns this plugin is being destroyed.
* We need to shutdown and then kill off all external references.
*
* @method Phaser.Time.Clock#destroy
* @private
* @since 3.0.0
*/
destroy: function() {
this.shutdown();
this.scene.sys.events.off(SceneEvents.START, this.start, this);
this.scene = null;
this.systems = null;
}
});
PluginCache.register("Clock", Clock, "time");
module2.exports = Clock;
}
),
/***/
96120: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var EventEmitter = __webpack_require__2(50792);
var GameObjectFactory = __webpack_require__2(39429);
var GetFastValue = __webpack_require__2(95540);
var SceneEvents = __webpack_require__2(44594);
var Events = __webpack_require__2(89809);
var Timeline = new Class({
Extends: EventEmitter,
initialize: function Timeline2(scene, config) {
EventEmitter.call(this);
this.scene = scene;
this.systems = scene.sys;
this.elapsed = 0;
this.timeScale = 1;
this.paused = true;
this.complete = false;
this.totalComplete = 0;
this.loop = 0;
this.iteration = 0;
this.events = [];
var eventEmitter = this.systems.events;
eventEmitter.on(SceneEvents.PRE_UPDATE, this.preUpdate, this);
eventEmitter.on(SceneEvents.UPDATE, this.update, this);
eventEmitter.once(SceneEvents.SHUTDOWN, this.destroy, this);
if (config) {
this.add(config);
}
},
/**
* Updates the elapsed time counter, if this Timeline is not paused.
*
* @method Phaser.Time.Timeline#preUpdate
* @since 3.60.0
*
* @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout.
* @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
*/
preUpdate: function(time, delta) {
if (this.paused) {
return;
}
this.elapsed += delta * this.timeScale;
},
/**
* Called automatically by the Scene update step.
*
* Iterates through all of the Timeline Events and checks to see if they should be run.
*
* If they should be run, then the `TimelineEvent.action` callback is invoked.
*
* If the `TimelineEvent.once` property is `true` then the event is removed from the Timeline.
*
* If the `TimelineEvent.event` property is set then the Timeline emits that event.
*
* If the `TimelineEvent.run` property is set then the Timeline invokes that method.
*
* If the `TimelineEvent.loop` property is set then the Timeline invokes that method when repeated.
*
* If the `TimelineEvent.target` property is set then the Timeline invokes the `run` method on that target.
*
* @method Phaser.Time.Timeline#update
* @fires Phaser.Time.Events#COMPLETE
* @since 3.60.0
*
* @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout.
* @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
*/
update: function() {
if (this.paused || this.complete) {
return;
}
var i;
var events = this.events;
var removeSweep = false;
var sys = this.systems;
var target;
for (i = 0; i < events.length; i++) {
var event = events[i];
if (!event.complete && event.time <= this.elapsed) {
event.complete = true;
this.totalComplete++;
target = event.target ? event.target : this;
if (event.if) {
if (!event.if.call(target, event)) {
continue;
}
}
if (event.once) {
removeSweep = true;
}
if (event.set && event.target) {
for (var key in event.set) {
event.target[key] = event.set[key];
}
}
if (this.iteration) {
event.repeat++;
}
if (event.loop && event.repeat) {
event.loop.call(target);
}
if (event.tween) {
event.tweenInstance = sys.tweens.add(event.tween);
}
if (event.sound) {
if (typeof event.sound === "string") {
sys.sound.play(event.sound);
} else {
sys.sound.play(event.sound.key, event.sound.config);
}
}
if (event.event) {
this.emit(event.event, target);
}
if (event.run) {
event.run.call(target);
}
if (event.stop) {
this.stop();
}
}
}
if (removeSweep) {
for (i = 0; i < events.length; i++) {
if (events[i].complete && events[i].once) {
events.splice(i, 1);
i--;
}
}
}
if (this.totalComplete >= events.length) {
if (this.loop !== 0 && (this.loop === -1 || this.loop > this.iteration)) {
this.iteration++;
this.reset(true);
} else {
this.complete = true;
}
}
if (this.complete) {
this.emit(Events.COMPLETE, this);
}
},
/**
* Starts this Timeline running.
*
* If the Timeline is already running and the `fromStart` parameter is `true`,
* then calling this method will reset the Timeline events as incomplete.
*
* If you wish to resume a paused Timeline, then use the `Timeline.resume` method instead.
*
* @method Phaser.Time.Timeline#play
* @since 3.60.0
*
* @param {boolean} [fromStart=true] - Reset this Timeline back to the start before playing.
*
* @return {this} This Timeline instance.
*/
play: function(fromStart) {
if (fromStart === void 0) {
fromStart = true;
}
this.paused = false;
this.complete = false;
this.totalComplete = 0;
if (fromStart) {
this.reset();
}
return this;
},
/**
* Pauses this Timeline.
*
* To resume it again, call the `Timeline.resume` method or set the `Timeline.paused` property to `false`.
*
* If the Timeline is paused while processing the current game step, then it
* will carry on with all events that are due to run during that step and pause
* from the next game step.
*
* Note that if any Tweens have been started prior to calling this method, they will **not** be paused as well.
*
* @method Phaser.Time.Timeline#pause
* @since 3.60.0
*
* @return {this} This Timeline instance.
*/
pause: function() {
this.paused = true;
var events = this.events;
for (var i = 0; i < events.length; i++) {
var event = events[i];
if (event.tweenInstance) {
event.tweenInstance.paused = true;
}
}
return this;
},
/**
* Repeats this Timeline.
*
* If the value for `amount` is positive, the Timeline will repeat that many additional times.
* For example a value of 1 will actually run this Timeline twice.
*
* Depending on the value given, `false` is 0 and `true`, undefined and negative numbers are infinite.
*
* If this Timeline had any events set to `once` that have already been removed,
* they will **not** be repeated each loop.
*
* @method Phaser.Time.Timeline#repeat
* @since 3.80.0
*
* @param {number|boolean} [amount=-1] - Amount of times to repeat, if `true` or negative it will be infinite.
*
* @return {this} This Timeline instance.
*/
repeat: function(amount) {
if (amount === void 0 || amount === true) {
amount = -1;
}
if (amount === false) {
amount = 0;
}
this.loop = amount;
return this;
},
/**
* Resumes this Timeline from a paused state.
*
* The Timeline will carry on from where it left off.
*
* If you need to reset the Timeline to the start, then call the `Timeline.reset` method.
*
* @method Phaser.Time.Timeline#resume
* @since 3.60.0
*
* @return {this} This Timeline instance.
*/
resume: function() {
this.paused = false;
var events = this.events;
for (var i = 0; i < events.length; i++) {
var event = events[i];
if (event.tweenInstance) {
event.tweenInstance.paused = false;
}
}
return this;
},
/**
* Stops this Timeline.
*
* This will set the `paused` and `complete` properties to `true`.
*
* If you wish to reset the Timeline to the start, then call the `Timeline.reset` method.
*
* @method Phaser.Time.Timeline#stop
* @since 3.60.0
*
* @return {this} This Timeline instance.
*/
stop: function() {
this.paused = true;
this.complete = true;
return this;
},
/**
* Resets this Timeline back to the start.
*
* This will set the elapsed time to zero and set all events to be incomplete.
*
* If the Timeline had any events that were set to `once` that have already
* been removed, they will **not** be present again after calling this method.
*
* If the Timeline isn't currently running (i.e. it's paused or complete) then
* calling this method resets those states, the same as calling `Timeline.play(true)`.
*
* Any Tweens that were currently running by this Timeline will be stopped.
*
* @method Phaser.Time.Timeline#reset
* @since 3.60.0
*
* @param {boolean} [loop=false] - Set to true if you do not want to reset the loop counters.
*
* @return {this} This Timeline instance.
*/
reset: function(loop) {
if (loop === void 0) {
loop = false;
}
this.elapsed = 0;
if (!loop) {
this.iteration = 0;
}
var events = this.events;
for (var i = 0; i < events.length; i++) {
var event = events[i];
event.complete = false;
if (!loop) {
event.repeat = 0;
}
if (event.tweenInstance) {
event.tweenInstance.stop();
}
}
return this.play(false);
},
/**
* Adds one or more events to this Timeline.
*
* You can pass in a single configuration object, or an array of them:
*
* ```js
* const timeline = this.add.timeline({
* at: 1000,
* run: () => {
* this.add.sprite(400, 300, 'logo');
* }
* });
* ```
*
* @method Phaser.Time.Timeline#add
* @since 3.60.0
*
* @param {Phaser.Types.Time.TimelineEventConfig|Phaser.Types.Time.TimelineEventConfig[]} config - The configuration object for this Timeline Event, or an array of them.
*
* @return {this} This Timeline instance.
*/
add: function(config) {
if (!Array.isArray(config)) {
config = [config];
}
var events = this.events;
var prevTime = 0;
if (events.length > 0) {
prevTime = events[events.length - 1].time;
}
for (var i = 0; i < config.length; i++) {
var entry = config[i];
var startTime = GetFastValue(entry, "at", 0);
var offsetTime = GetFastValue(entry, "in", null);
if (offsetTime !== null) {
startTime = this.elapsed + offsetTime;
}
var fromTime = GetFastValue(entry, "from", null);
if (fromTime !== null) {
startTime = prevTime + fromTime;
}
events.push({
complete: false,
time: startTime,
repeat: 0,
if: GetFastValue(entry, "if", null),
run: GetFastValue(entry, "run", null),
loop: GetFastValue(entry, "loop", null),
event: GetFastValue(entry, "event", null),
target: GetFastValue(entry, "target", null),
set: GetFastValue(entry, "set", null),
tween: GetFastValue(entry, "tween", null),
sound: GetFastValue(entry, "sound", null),
once: GetFastValue(entry, "once", false),
stop: GetFastValue(entry, "stop", false)
});
prevTime = startTime;
}
this.complete = false;
return this;
},
/**
* Removes all events from this Timeline, resets the elapsed time to zero
* and pauses the Timeline.
*
* Any Tweens that were currently running as a result of this Timeline will be stopped.
*
* @method Phaser.Time.Timeline#clear
* @since 3.60.0
*
* @return {this} This Timeline instance.
*/
clear: function() {
var events = this.events;
for (var i = 0; i < events.length; i++) {
var event = events[i];
if (event.tweenInstance) {
event.tweenInstance.stop();
}
}
events = [];
this.elapsed = 0;
this.paused = true;
return this;
},
/**
* Returns `true` if this Timeline is currently playing.
*
* A Timeline is playing if it is not paused or not complete.
*
* @method Phaser.Time.Timeline#isPlaying
* @since 3.60.0
*
* @return {boolean} `true` if this Timeline is playing, otherwise `false`.
*/
isPlaying: function() {
return !this.paused && !this.complete;
},
/**
* Returns a number between 0 and 1 representing the progress of this Timeline.
*
* A value of 0 means the Timeline has just started, 0.5 means it's half way through,
* and 1 means it's complete.
*
* If the Timeline has no events, or all events have been removed, this will return 1.
*
* If the Timeline is paused, this will return the progress value at the time it was paused.
*
* Note that the value returned is based on the number of events that have been completed,
* not the 'duration' of the events (as this is unknown to the Timeline).
*
* @method Phaser.Time.Timeline#getProgress
* @since 3.60.0
*
* @return {number} A number between 0 and 1 representing the progress of this Timeline.
*/
getProgress: function() {
var total = Math.min(this.totalComplete, this.events.length);
return total / this.events.length;
},
/**
* Destroys this Timeline.
*
* This will remove all events from the Timeline and stop it from processing.
*
* Any Tweens that were currently running as a result of this Timeline will be stopped.
*
* This method is called automatically when the Scene shuts down, but you may
* also call it directly should you need to destroy the Timeline earlier.
*
* @method Phaser.Time.Timeline#destroy
* @since 3.60.0
*/
destroy: function() {
var eventEmitter = this.systems.events;
eventEmitter.off(SceneEvents.PRE_UPDATE, this.preUpdate, this);
eventEmitter.off(SceneEvents.UPDATE, this.update, this);
eventEmitter.off(SceneEvents.SHUTDOWN, this.destroy, this);
this.clear();
this.scene = null;
this.systems = null;
}
});
GameObjectFactory.register("timeline", function(config) {
return new Timeline(this.scene, config);
});
module2.exports = Timeline;
}
),
/***/
94880: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var GetFastValue = __webpack_require__2(95540);
var TimerEvent = new Class({
initialize: function TimerEvent2(config) {
this.delay = 0;
this.repeat = 0;
this.repeatCount = 0;
this.loop = false;
this.callback;
this.callbackScope;
this.args;
this.timeScale = 1;
this.startAt = 0;
this.elapsed = 0;
this.paused = false;
this.hasDispatched = false;
this.reset(config);
},
/**
* Completely reinitializes the Timer Event, regardless of its current state, according to a configuration object.
*
* @method Phaser.Time.TimerEvent#reset
* @since 3.0.0
*
* @param {Phaser.Types.Time.TimerEventConfig} config - The new state for the Timer Event.
*
* @return {Phaser.Time.TimerEvent} This TimerEvent object.
*/
reset: function(config) {
this.delay = GetFastValue(config, "delay", 0);
this.repeat = GetFastValue(config, "repeat", 0);
this.loop = GetFastValue(config, "loop", false);
this.callback = GetFastValue(config, "callback", void 0);
this.callbackScope = GetFastValue(config, "callbackScope", this);
this.args = GetFastValue(config, "args", []);
this.timeScale = GetFastValue(config, "timeScale", 1);
this.startAt = GetFastValue(config, "startAt", 0);
this.paused = GetFastValue(config, "paused", false);
this.elapsed = this.startAt;
this.hasDispatched = false;
this.repeatCount = this.repeat === -1 || this.loop ? 999999999999 : this.repeat;
if (this.delay === 0 && (this.repeat > 0 || this.loop)) {
throw new Error("TimerEvent infinite loop created via zero delay");
}
return this;
},
/**
* Gets the progress of the current iteration, not factoring in repeats.
*
* @method Phaser.Time.TimerEvent#getProgress
* @since 3.0.0
*
* @return {number} A number between 0 and 1 representing the current progress.
*/
getProgress: function() {
return this.elapsed / this.delay;
},
/**
* Gets the progress of the timer overall, factoring in repeats.
*
* @method Phaser.Time.TimerEvent#getOverallProgress
* @since 3.0.0
*
* @return {number} The overall progress of the Timer Event, between 0 and 1.
*/
getOverallProgress: function() {
if (this.repeat > 0) {
var totalDuration = this.delay + this.delay * this.repeat;
var totalElapsed = this.elapsed + this.delay * (this.repeat - this.repeatCount);
return totalElapsed / totalDuration;
} else {
return this.getProgress();
}
},
/**
* Returns the number of times this Timer Event will repeat before finishing.
*
* This should not be confused with the number of times the Timer Event will fire before finishing. A return value of 0 doesn't indicate that the Timer Event has finished running - it indicates that it will not repeat after the next time it fires.
*
* @method Phaser.Time.TimerEvent#getRepeatCount
* @since 3.0.0
*
* @return {number} How many times the Timer Event will repeat.
*/
getRepeatCount: function() {
return this.repeatCount;
},
/**
* Returns the local elapsed time for the current iteration of the Timer Event.
*
* @method Phaser.Time.TimerEvent#getElapsed
* @since 3.0.0
*
* @return {number} The local elapsed time in milliseconds.
*/
getElapsed: function() {
return this.elapsed;
},
/**
* Returns the local elapsed time for the current iteration of the Timer Event in seconds.
*
* @method Phaser.Time.TimerEvent#getElapsedSeconds
* @since 3.0.0
*
* @return {number} The local elapsed time in seconds.
*/
getElapsedSeconds: function() {
return this.elapsed * 1e-3;
},
/**
* Returns the time interval until the next iteration of the Timer Event.
*
* @method Phaser.Time.TimerEvent#getRemaining
* @since 3.50.0
*
* @return {number} The time interval in milliseconds.
*/
getRemaining: function() {
return this.delay - this.elapsed;
},
/**
* Returns the time interval until the next iteration of the Timer Event in seconds.
*
* @method Phaser.Time.TimerEvent#getRemainingSeconds
* @since 3.50.0
*
* @return {number} The time interval in seconds.
*/
getRemainingSeconds: function() {
return this.getRemaining() * 1e-3;
},
/**
* Returns the time interval until the last iteration of the Timer Event.
*
* @method Phaser.Time.TimerEvent#getOverallRemaining
* @since 3.50.0
*
* @return {number} The time interval in milliseconds.
*/
getOverallRemaining: function() {
return this.delay * (1 + this.repeatCount) - this.elapsed;
},
/**
* Returns the time interval until the last iteration of the Timer Event in seconds.
*
* @method Phaser.Time.TimerEvent#getOverallRemainingSeconds
* @since 3.50.0
*
* @return {number} The time interval in seconds.
*/
getOverallRemainingSeconds: function() {
return this.getOverallRemaining() * 1e-3;
},
/**
* Forces the Timer Event to immediately expire, thus scheduling its removal in the next frame.
*
* @method Phaser.Time.TimerEvent#remove
* @since 3.0.0
*
* @param {boolean} [dispatchCallback=false] - If `true`, the function of the Timer Event will be called before its removal.
*/
remove: function(dispatchCallback) {
if (dispatchCallback === void 0) {
dispatchCallback = false;
}
this.elapsed = this.delay;
this.hasDispatched = !dispatchCallback;
this.repeatCount = 0;
},
/**
* Destroys all object references in the Timer Event, i.e. its callback, scope, and arguments.
*
* Normally, this method is only called by the Clock when it shuts down. As such, it doesn't stop the Timer Event. If called manually, the Timer Event will still be updated by the Clock, but it won't do anything when it fires.
*
* @method Phaser.Time.TimerEvent#destroy
* @since 3.0.0
*/
destroy: function() {
this.callback = void 0;
this.callbackScope = void 0;
this.args = [];
}
});
module2.exports = TimerEvent;
}
),
/***/
35945: (
/***/
(module2) => {
module2.exports = "complete";
}
),
/***/
89809: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
COMPLETE: __webpack_require__2(35945)
};
}
),
/***/
90291: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Clock: __webpack_require__2(33385),
Events: __webpack_require__2(89809),
Timeline: __webpack_require__2(96120),
TimerEvent: __webpack_require__2(94880)
};
}
),
/***/
40382: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var ArrayRemove = __webpack_require__2(72905);
var Class = __webpack_require__2(83419);
var Flatten = __webpack_require__2(43491);
var NumberTweenBuilder = __webpack_require__2(88032);
var PluginCache = __webpack_require__2(37277);
var SceneEvents = __webpack_require__2(44594);
var StaggerBuilder = __webpack_require__2(93109);
var Tween = __webpack_require__2(86081);
var TweenBuilder = __webpack_require__2(8357);
var TweenChain = __webpack_require__2(43960);
var TweenChainBuilder = __webpack_require__2(26012);
var TweenManager = new Class({
initialize: function TweenManager2(scene) {
this.scene = scene;
this.events = scene.sys.events;
this.timeScale = 1;
this.paused = false;
this.processing = false;
this.tweens = [];
this.time = 0;
this.startTime = 0;
this.nextTime = 0;
this.prevTime = 0;
this.maxLag = 500;
this.lagSkip = 33;
this.gap = 1e3 / 240;
this.events.once(SceneEvents.BOOT, this.boot, this);
this.events.on(SceneEvents.START, this.start, this);
},
/**
* This method is called automatically, only once, when the Scene is first created.
* Do not invoke it directly.
*
* @method Phaser.Tweens.TweenManager#boot
* @private
* @since 3.5.1
*/
boot: function() {
this.events.once(SceneEvents.DESTROY, this.destroy, this);
},
/**
* This method is called automatically by the Scene when it is starting up.
* It is responsible for creating local systems, properties and listening for Scene events.
* Do not invoke it directly.
*
* @method Phaser.Tweens.TweenManager#start
* @private
* @since 3.5.0
*/
start: function() {
this.timeScale = 1;
this.paused = false;
this.startTime = Date.now();
this.prevTime = this.startTime;
this.nextTime = this.gap;
this.events.on(SceneEvents.UPDATE, this.update, this);
this.events.once(SceneEvents.SHUTDOWN, this.shutdown, this);
},
/**
* Create a Tween and return it, but does not add it to this Tween Manager.
*
* Please note that a Tween will not manipulate any target property that begins with an underscore.
*
* In order to play this tween, you'll need to add it to a Tween Manager via
* the `TweenManager.existing` method.
*
* You can optionally pass an **array** of Tween Configuration objects to this method and it will create
* one Tween per entry in the array. If an array is given, an array of tweens is returned.
*
* @method Phaser.Tweens.TweenManager#create
* @since 3.0.0
*
* @param {Phaser.Types.Tweens.TweenBuilderConfig|Phaser.Types.Tweens.TweenBuilderConfig[]|object|object[]} config - A Tween Configuration object. Or an array of Tween Configuration objects.
*
* @return {Phaser.Tweens.Tween|Phaser.Tweens.Tween[]} The created Tween, or an array of Tweens if an array of tween configs was provided.
*/
create: function(config) {
if (!Array.isArray(config)) {
config = [config];
}
var result = [];
for (var i = 0; i < config.length; i++) {
var tween = config[i];
if (tween instanceof Tween || tween instanceof TweenChain) {
result.push(tween);
} else if (Array.isArray(tween.tweens)) {
result.push(TweenChainBuilder(this, tween));
} else {
result.push(TweenBuilder(this, tween));
}
}
return result.length === 1 ? result[0] : result;
},
/**
* Create a Tween and add it to this Tween Manager by passing a Tween Configuration object.
*
* Example, run from within a Scene:
*
* ```js
* const logo = this.add.image(100, 100, 'logo');
*
* this.tweens.add({
* targets: logo,
* x: 600,
* ease: 'Power1',
* duration: 2000
* });
* ```
*
* See the `TweenBuilderConfig` for all of the options you have available.
*
* Playback will start immediately unless the tween has been configured to be paused.
*
* Please note that a Tween will not manipulate any target property that begins with an underscore.
*
* Tweens are designed to be 'fire-and-forget'. They automatically destroy themselves once playback
* is complete, to free-up memory and resources. If you wish to keep a tween after playback, i.e. to
* play it again at a later time, then you should set the `persist` property to `true` in the config.
* However, doing so means it's entirely up to _you_ to destroy the tween when you're finished with it,
* otherwise it will linger in memory forever.
*
* If you wish to chain Tweens together for sequential playback, see the `TweenManager.chain` method.
*
* @method Phaser.Tweens.TweenManager#add
* @since 3.0.0
*
* @param {Phaser.Types.Tweens.TweenBuilderConfig|Phaser.Types.Tweens.TweenChainBuilderConfig|Phaser.Tweens.Tween|Phaser.Tweens.TweenChain} config - A Tween Configuration object, or a Tween or TweenChain instance.
*
* @return {Phaser.Tweens.Tween} The created Tween.
*/
add: function(config) {
var tween = config;
var tweens = this.tweens;
if (tween instanceof Tween || tween instanceof TweenChain) {
tweens.push(tween.reset());
} else {
if (Array.isArray(tween.tweens)) {
tween = TweenChainBuilder(this, tween);
} else {
tween = TweenBuilder(this, tween);
}
tweens.push(tween.reset());
}
return tween;
},
/**
* Create multiple Tweens and add them all to this Tween Manager, by passing an array of Tween Configuration objects.
*
* See the `TweenBuilderConfig` for all of the options you have available.
*
* Playback will start immediately unless the tweens have been configured to be paused.
*
* Please note that a Tween will not manipulate any target property that begins with an underscore.
*
* Tweens are designed to be 'fire-and-forget'. They automatically destroy themselves once playback
* is complete, to free-up memory and resources. If you wish to keep a tween after playback, i.e. to
* play it again at a later time, then you should set the `persist` property to `true` in the config.
* However, doing so means it's entirely up to _you_ to destroy the tween when you're finished with it,
* otherwise it will linger in memory forever.
*
* If you wish to chain Tweens together for sequential playback, see the `TweenManager.chain` method.
*
* @method Phaser.Tweens.TweenManager#addMultiple
* @since 3.60.0
*
* @param {Phaser.Types.Tweens.TweenBuilderConfig[]|object[]} configs - An array of Tween Configuration objects.
*
* @return {Phaser.Tweens.Tween[]} An array of created Tweens.
*/
addMultiple: function(configs) {
var tween;
var result = [];
var tweens = this.tweens;
for (var i = 0; i < configs.length; i++) {
tween = configs[i];
if (tween instanceof Tween || tween instanceof TweenChain) {
tweens.push(tween.reset());
} else {
if (Array.isArray(tween.tweens)) {
tween = TweenChainBuilder(this, tween);
} else {
tween = TweenBuilder(this, tween);
}
tweens.push(tween.reset());
}
result.push(tween);
}
return result;
},
/**
* Create a sequence of Tweens, chained to one-another, and add them to this Tween Manager.
*
* The tweens are played in order, from start to finish. You can optionally set the chain
* to repeat as many times as you like. Once the chain has finished playing, or repeating if set,
* all tweens in the chain will be destroyed automatically. To override this, set the `persist`
* argument to 'true'.
*
* Playback will start immediately unless the _first_ Tween has been configured to be paused.
*
* Please note that Tweens will not manipulate any target property that begins with an underscore.
*
* @method Phaser.Tweens.TweenManager#chain
* @since 3.60.0
*
* @param {Phaser.Types.Tweens.TweenChainBuilderConfig|object} tweens - A Tween Chain configuration object.
*
* @return {Phaser.Tweens.TweenChain} The Tween Chain instance.
*/
chain: function(config) {
var chain = TweenChainBuilder(this, config);
this.tweens.push(chain.init());
return chain;
},
/**
* Returns an array containing this Tween and all Tweens chained to it,
* in the order in which they will be played.
*
* If there are no chained Tweens an empty array is returned.
*
* @method Phaser.Tweens.TweenManager#getChainedTweens
* @since 3.60.0
*
* @param {Phaser.Tweens.Tween} tween - The Tween to return the chain from.
*
* @return {Phaser.Tweens.Tween[]} An array of the chained tweens, or an empty array if there aren't any.
*/
getChainedTweens: function(tween) {
return tween.getChainedTweens();
},
/**
* Check to see if the given Tween instance exists within this Tween Manager.
*
* Will return `true` as long as the Tween is being processed by this Tween Manager.
*
* Will return `false` if not present, or has a state of `REMOVED` or `DESTROYED`.
*
* @method Phaser.Tweens.TweenManager#has
* @since 3.60.0
*
* @param {Phaser.Tweens.Tween} tween - The Tween instance to check.
*
* @return {boolean} `true` if the Tween exists within this Tween Manager, otherwise `false`.
*/
has: function(tween) {
return this.tweens.indexOf(tween) > -1;
},
/**
* Add an existing Tween to this Tween Manager.
*
* Playback will start immediately unless the tween has been configured to be paused.
*
* @method Phaser.Tweens.TweenManager#existing
* @since 3.0.0
*
* @param {Phaser.Tweens.Tween} tween - The Tween to add.
*
* @return {this} This Tween Manager instance.
*/
existing: function(tween) {
if (!this.has(tween)) {
this.tweens.push(tween.reset());
}
return this;
},
/**
* Create a Number Tween and add it to the active Tween list.
*
* A Number Tween is a special kind of tween that doesn't have a target. Instead,
* it allows you to tween between 2 numeric values. The default values are
* `0` and `1`, but you can change them via the `from` and `to` properties.
*
* You can get the current tweened value via the `Tween.getValue()` method.
*
* Playback will start immediately unless the tween has been configured to be paused.
*
* Please note that a Tween will not manipulate any target property that begins with an underscore.
*
* @method Phaser.Tweens.TweenManager#addCounter
* @since 3.0.0
*
* @param {Phaser.Types.Tweens.NumberTweenBuilderConfig} config - The configuration object for the Number Tween.
*
* @return {Phaser.Tweens.Tween} The created Number Tween.
*/
addCounter: function(config) {
var tween = NumberTweenBuilder(this, config);
this.tweens.push(tween.reset());
return tween;
},
/**
* Creates a Stagger function to be used by a Tween property.
*
* The stagger function will allow you to stagger changes to the value of the property across all targets of the tween.
*
* This is only worth using if the tween has multiple targets.
*
* The following will stagger the delay by 100ms across all targets of the tween, causing them to scale down to 0.2
* over the duration specified:
*
* ```javascript
* this.tweens.add({
* targets: [ ... ],
* scale: 0.2,
* ease: 'linear',
* duration: 1000,
* delay: this.tweens.stagger(100)
* });
* ```
*
* The following will stagger the delay by 500ms across all targets of the tween using a 10 x 6 grid, staggering
* from the center out, using a cubic ease.
*
* ```javascript
* this.tweens.add({
* targets: [ ... ],
* scale: 0.2,
* ease: 'linear',
* duration: 1000,
* delay: this.tweens.stagger(500, { grid: [ 10, 6 ], from: 'center', ease: 'cubic.out' })
* });
* ```
*
* @method Phaser.Tweens.TweenManager#stagger
* @since 3.19.0
*
* @param {(number|number[])} value - The amount to stagger by, or an array containing two elements representing the min and max values to stagger between.
* @param {Phaser.Types.Tweens.StaggerConfig} config - The configuration object for the Stagger function.
*
* @return {function} The stagger function.
*/
stagger: function(value, options) {
return StaggerBuilder(value, options);
},
/**
* Set the limits that are used when a browser encounters lag, or delays that cause the elapsed
* time between two frames to exceed the expected amount. If this occurs, the Tween Manager will
* act as if the 'skip' amount of times has passed, in order to maintain strict tween sequencing.
*
* This is enabled by default with the values 500ms for the lag limit and 33ms for the skip.
*
* You should not set these to low values, as it won't give time for the browser to ever
* catch-up with itself and reclaim sync.
*
* Call this method with no arguments to disable smoothing.
*
* Call it with the arguments `500` and `33` to reset to the defaults.
*
* @method Phaser.Tweens.TweenManager#setLagSmooth
* @since 3.60.0
*
* @param {number} [limit=0] - If the browser exceeds this amount, in milliseconds, it will act as if the 'skip' amount has elapsed instead.
* @param {number} [skip=0] - The amount, in milliseconds, to use as the step delta should the browser lag beyond the 'limit'.
*
* @return {this} This Tween Manager instance.
*/
setLagSmooth: function(limit, skip) {
if (limit === void 0) {
limit = 1 / 1e-8;
}
if (skip === void 0) {
skip = 0;
}
this.maxLag = limit;
this.lagSkip = Math.min(skip, this.maxLag);
return this;
},
/**
* Limits the Tween system to run at a particular frame rate.
*
* You should not set this _above_ the frequency of the browser,
* but instead can use it to throttle the frame rate lower, should
* you need to in certain situations.
*
* @method Phaser.Tweens.TweenManager#setFps
* @since 3.60.0
*
* @param {number} [fps=240] - The frame rate to tick at.
*
* @return {this} This Tween Manager instance.
*/
setFps: function(fps) {
if (fps === void 0) {
fps = 240;
}
this.gap = 1e3 / fps;
this.nextTime = this.time * 1e3 + this.gap;
return this;
},
/**
* Internal method that calculates the delta value, along with the other timing values,
* and returns the new delta.
*
* You should not typically call this method directly.
*
* @method Phaser.Tweens.TweenManager#getDelta
* @since 3.60.0
*
* @param {boolean} [tick=false] - Is this a manual tick, or an automated tick?
*
* @return {number} The new delta value.
*/
getDelta: function(tick) {
var elapsed = Date.now() - this.prevTime;
if (elapsed > this.maxLag) {
this.startTime += elapsed - this.lagSkip;
}
this.prevTime += elapsed;
var time = this.prevTime - this.startTime;
var overlap = time - this.nextTime;
var delta = time - this.time * 1e3;
if (overlap > 0 || tick) {
time /= 1e3;
this.time = time;
this.nextTime += overlap + (overlap >= this.gap ? 4 : this.gap - overlap);
} else {
delta = 0;
}
return delta;
},
/**
* Manually advance the Tween system by one step.
*
* This will update all Tweens even if the Tween Manager is currently
* paused.
*
* @method Phaser.Tweens.TweenManager#tick
* @since 3.60.0
*
* @return {this} This Tween Manager instance.
*/
tick: function() {
this.step(true);
return this;
},
/**
* Internal update handler.
*
* Calls `TweenManager.step` as long as the Tween Manager has not
* been paused.
*
* @method Phaser.Tweens.TweenManager#update
* @since 3.0.0
*/
update: function() {
if (!this.paused) {
this.step(false);
}
},
/**
* Updates all Tweens belonging to this Tween Manager.
*
* Called automatically by `update` and `tick`.
*
* @method Phaser.Tweens.TweenManager#step
* @since 3.60.0
*
* @param {boolean} [tick=false] - Is this a manual tick, or an automated tick?
*/
step: function(tick) {
if (tick === void 0) {
tick = false;
}
var delta = this.getDelta(tick);
if (delta <= 0) {
return;
}
this.processing = true;
var i;
var tween;
var toDestroy = [];
var list = this.tweens;
for (i = 0; i < list.length; i++) {
tween = list[i];
if (tween.update(delta)) {
toDestroy.push(tween);
}
}
var count = toDestroy.length;
if (count && list.length > 0) {
for (i = 0; i < count; i++) {
tween = toDestroy[i];
var idx = list.indexOf(tween);
if (idx > -1 && (tween.isPendingRemove() || tween.isDestroyed())) {
list.splice(idx, 1);
tween.destroy();
}
}
toDestroy.length = 0;
}
this.processing = false;
},
/**
* Removes the given Tween from this Tween Manager, even if it hasn't started
* playback yet. If this method is called while the Tween Manager is processing
* an update loop, then the tween will be flagged for removal at the start of
* the next frame. Otherwise, it is removed immediately.
*
* The removed tween is _not_ destroyed. It is just removed from this Tween Manager.
*
* @method Phaser.Tweens.TweenManager#remove
* @since 3.17.0
*
* @param {Phaser.Tweens.Tween} tween - The Tween to be removed.
*
* @return {this} This Tween Manager instance.
*/
remove: function(tween) {
if (this.processing) {
tween.setPendingRemoveState();
} else {
ArrayRemove(this.tweens, tween);
tween.setRemovedState();
}
return this;
},
/**
* Resets the given Tween.
*
* If the Tween does not belong to this Tween Manager, it will first be added.
*
* Then it will seek to position 0 and playback will start on the next frame.
*
* @method Phaser.Tweens.TweenManager#reset
* @since 3.60.0
*
* @param {Phaser.Tweens.Tween} tween - The Tween to be reset.
*
* @return {this} This Tween Manager instance.
*/
reset: function(tween) {
this.existing(tween);
tween.seek();
tween.setActiveState();
return this;
},
/**
* Checks if a Tween is active and adds it to the Tween Manager at the start of the frame if it isn't.
*
* @method Phaser.Tweens.TweenManager#makeActive
* @since 3.0.0
*
* @param {Phaser.Tweens.Tween} tween - The Tween to check.
*
* @return {this} This Tween Manager instance.
*/
makeActive: function(tween) {
this.existing(tween);
tween.setActiveState();
return this;
},
/**
* Passes all Tweens to the given callback.
*
* @method Phaser.Tweens.TweenManager#each
* @since 3.0.0
*
* @param {function} callback - The function to call.
* @param {object} [scope] - The scope (`this` object) to call the function with.
* @param {...*} [args] - The arguments to pass into the function. Its first argument will always be the Tween currently being iterated.
*
* @return {this} This Tween Manager instance.
*/
each: function(callback, scope) {
var i;
var args = [null];
for (i = 1; i < arguments.length; i++) {
args.push(arguments[i]);
}
this.tweens.forEach(function(tween) {
args[0] = tween;
callback.apply(scope, args);
});
return this;
},
/**
* Returns an array containing references to all Tweens in this Tween Manager.
*
* It is safe to mutate the returned array. However, acting upon any of the Tweens
* within it, will adjust those stored in this Tween Manager, as they are passed
* by reference and not cloned.
*
* If you wish to get tweens for a specific target, see `getTweensOf`.
*
* @method Phaser.Tweens.TweenManager#getTweens
* @since 3.0.0
*
* @return {Phaser.Tweens.Tween[]} A new array containing references to all Tweens.
*/
getTweens: function() {
return this.tweens.slice();
},
/**
* Returns an array of all Tweens in the Tween Manager which affect the given target, or array of targets.
*
* It's possible for this method to return tweens that are about to be removed from
* the Tween Manager. You should check the state of the returned tween before acting
* upon it.
*
* @method Phaser.Tweens.TweenManager#getTweensOf
* @since 3.0.0
*
* @param {(object|object[])} target - The target to look for. Provide an array to look for multiple targets.
*
* @return {Phaser.Tweens.Tween[]} A new array containing all Tweens which affect the given target(s).
*/
getTweensOf: function(target) {
var output = [];
var list = this.tweens;
if (!Array.isArray(target)) {
target = [target];
} else {
target = Flatten(target);
}
var targetLen = target.length;
for (var i = 0; i < list.length; i++) {
var tween = list[i];
for (var t = 0; t < targetLen; t++) {
if (!tween.isDestroyed() && tween.hasTarget(target[t])) {
output.push(tween);
}
}
}
return output;
},
/**
* Returns the scale of the time delta for all Tweens owned by this Tween Manager.
*
* @method Phaser.Tweens.TweenManager#getGlobalTimeScale
* @since 3.0.0
*
* @return {number} The scale of the time delta, usually 1.
*/
getGlobalTimeScale: function() {
return this.timeScale;
},
/**
* Sets a new scale of the time delta for this Tween Manager.
*
* The time delta is the time elapsed between two consecutive frames and influences the speed of time for this Tween Manager and all Tweens it owns. Values higher than 1 increase the speed of time, while values smaller than 1 decrease it. A value of 0 freezes time and is effectively equivalent to pausing all Tweens.
*
* @method Phaser.Tweens.TweenManager#setGlobalTimeScale
* @since 3.0.0
*
* @param {number} value - The new scale of the time delta, where 1 is the normal speed.
*
* @return {this} This Tween Manager instance.
*/
setGlobalTimeScale: function(value) {
this.timeScale = value;
return this;
},
/**
* Checks if the given object is being affected by a _playing_ Tween.
*
* If the Tween is paused, this method will return false.
*
* @method Phaser.Tweens.TweenManager#isTweening
* @since 3.0.0
*
* @param {object} target - The object to check if a tween is active for it, or not.
*
* @return {boolean} Returns `true` if a tween is active on the given target, otherwise `false`.
*/
isTweening: function(target) {
var list = this.tweens;
var tween;
for (var i = 0; i < list.length; i++) {
tween = list[i];
if (tween.isPlaying() && tween.hasTarget(target)) {
return true;
}
}
return false;
},
/**
* Destroys all Tweens in this Tween Manager.
*
* The tweens will erase all references to any targets they hold
* and be stopped immediately.
*
* If this method is called while the Tween Manager is running its
* update process, then the tweens will be removed at the start of
* the next frame. Outside of this, they are removed immediately.
*
* @method Phaser.Tweens.TweenManager#killAll
* @since 3.0.0
*
* @return {this} This Tween Manager instance.
*/
killAll: function() {
var tweens = this.processing ? this.getTweens() : this.tweens;
for (var i = 0; i < tweens.length; i++) {
tweens[i].destroy();
}
if (!this.processing) {
tweens.length = 0;
}
return this;
},
/**
* Stops all Tweens which affect the given target or array of targets.
*
* The tweens will erase all references to any targets they hold
* and be stopped immediately.
*
* If this method is called while the Tween Manager is running its
* update process, then the tweens will be removed at the start of
* the next frame. Outside of this, they are removed immediately.
*
* @see {@link #getTweensOf}
*
* @method Phaser.Tweens.TweenManager#killTweensOf
* @since 3.0.0
*
* @param {(object|array)} target - The target to kill the tweens of. Provide an array to use multiple targets.
*
* @return {this} This Tween Manager instance.
*/
killTweensOf: function(target) {
var tweens = this.getTweensOf(target);
for (var i = 0; i < tweens.length; i++) {
tweens[i].destroy();
}
return this;
},
/**
* Pauses this Tween Manager. No Tweens will update while paused.
*
* This includes tweens created after this method was called.
*
* See `TweenManager#resumeAll` to resume the playback.
*
* As of Phaser 3.60 you can also toggle the boolean property `TweenManager.paused`.
*
* @method Phaser.Tweens.TweenManager#pauseAll
* @since 3.0.0
*
* @return {this} This Tween Manager instance.
*/
pauseAll: function() {
this.paused = true;
return this;
},
/**
* Resumes playback of this Tween Manager.
*
* All active Tweens will continue updating.
*
* See `TweenManager#pauseAll` to pause the playback.
*
* As of Phaser 3.60 you can also toggle the boolean property `TweenManager.paused`.
*
* @method Phaser.Tweens.TweenManager#resumeAll
* @since 3.0.0
*
* @return {this} This Tween Manager instance.
*/
resumeAll: function() {
this.paused = false;
return this;
},
/**
* The Scene that owns this plugin is shutting down.
*
* We need to kill and reset all internal properties as well as stop listening to Scene events.
*
* @method Phaser.Tweens.TweenManager#shutdown
* @since 3.0.0
*/
shutdown: function() {
this.killAll();
this.tweens = [];
this.events.off(SceneEvents.UPDATE, this.update, this);
this.events.off(SceneEvents.SHUTDOWN, this.shutdown, this);
},
/**
* The Scene that owns this plugin is being destroyed.
* We need to shutdown and then kill off all external references.
*
* @method Phaser.Tweens.TweenManager#destroy
* @since 3.0.0
*/
destroy: function() {
this.shutdown();
this.events.off(SceneEvents.START, this.start, this);
this.scene = null;
this.events = null;
}
});
PluginCache.register("TweenManager", TweenManager, "tweens");
module2.exports = TweenManager;
}
),
/***/
57355: (
/***/
(module2) => {
var GetBoolean = function(source, key, defaultValue) {
if (!source) {
return defaultValue;
} else if (source.hasOwnProperty(key)) {
return source[key];
} else {
return defaultValue;
}
};
module2.exports = GetBoolean;
}
),
/***/
6113: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var EaseMap = __webpack_require__2(62640);
var UppercaseFirst = __webpack_require__2(35355);
var GetEaseFunction = function(ease, easeParams) {
var easeFunction = EaseMap.Power0;
if (typeof ease === "string") {
if (EaseMap.hasOwnProperty(ease)) {
easeFunction = EaseMap[ease];
} else {
var direction = "";
if (ease.indexOf(".")) {
direction = ease.substring(ease.indexOf(".") + 1);
var directionLower = direction.toLowerCase();
if (directionLower === "in") {
direction = "easeIn";
} else if (directionLower === "out") {
direction = "easeOut";
} else if (directionLower === "inout") {
direction = "easeInOut";
}
}
ease = UppercaseFirst(ease.substring(0, ease.indexOf(".") + 1) + direction);
if (EaseMap.hasOwnProperty(ease)) {
easeFunction = EaseMap[ease];
}
}
} else if (typeof ease === "function") {
easeFunction = ease;
}
if (!easeParams) {
return easeFunction;
}
var cloneParams = easeParams.slice(0);
cloneParams.unshift(0);
return function(v) {
cloneParams[0] = v;
return easeFunction.apply(this, cloneParams);
};
};
module2.exports = GetEaseFunction;
}
),
/***/
91389: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Bezier = __webpack_require__2(89318);
var CatmullRom = __webpack_require__2(77259);
var Linear = __webpack_require__2(28392);
var FuncMap = {
bezier: Bezier,
catmull: CatmullRom,
catmullrom: CatmullRom,
linear: Linear
};
var GetInterpolationFunction = function(interpolation) {
if (interpolation === null) {
return null;
}
var interpolationFunction = FuncMap.linear;
if (typeof interpolation === "string") {
if (FuncMap.hasOwnProperty(interpolation)) {
interpolationFunction = FuncMap[interpolation];
}
} else if (typeof interpolation === "function") {
interpolationFunction = interpolation;
}
return interpolationFunction;
};
module2.exports = GetInterpolationFunction;
}
),
/***/
55292: (
/***/
(module2) => {
var GetNewValue = function(source, key, defaultValue) {
var valueCallback;
if (source.hasOwnProperty(key)) {
var t = typeof source[key];
if (t === "function") {
valueCallback = function(target, targetKey, value, targetIndex, totalTargets, tween) {
return source[key](target, targetKey, value, targetIndex, totalTargets, tween);
};
} else {
valueCallback = function() {
return source[key];
};
}
} else if (typeof defaultValue === "function") {
valueCallback = defaultValue;
} else {
valueCallback = function() {
return defaultValue;
};
}
return valueCallback;
};
module2.exports = GetNewValue;
}
),
/***/
82985: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var RESERVED = __webpack_require__2(81076);
var GetProps = function(config) {
var key;
var keys = [];
if (config.hasOwnProperty("props")) {
for (key in config.props) {
if (key.substring(0, 1) !== "_") {
keys.push({ key, value: config.props[key] });
}
}
} else {
for (key in config) {
if (RESERVED.indexOf(key) === -1 && key.substring(0, 1) !== "_") {
keys.push({ key, value: config[key] });
}
}
}
return keys;
};
module2.exports = GetProps;
}
),
/***/
62329: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetValue = __webpack_require__2(35154);
var GetTargets = function(config) {
var targets = GetValue(config, "targets", null);
if (targets === null) {
return targets;
}
if (typeof targets === "function") {
targets = targets.call();
}
if (!Array.isArray(targets)) {
targets = [targets];
}
return targets;
};
module2.exports = GetTargets;
}
),
/***/
17777: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Between = __webpack_require__2(30976);
var FloatBetween = __webpack_require__2(99472);
function hasGetActive(def) {
return !!def.getActive && typeof def.getActive === "function";
}
function hasGetStart(def) {
return !!def.getStart && typeof def.getStart === "function";
}
function hasGetEnd(def) {
return !!def.getEnd && typeof def.getEnd === "function";
}
function hasGetters(def) {
return hasGetStart(def) || hasGetEnd(def) || hasGetActive(def);
}
var GetValueOp = function(key, propertyValue) {
var callbacks;
var getEnd = function(target, key2, value) {
return value;
};
var getStart = function(target, key2, value) {
return value;
};
var getActive = null;
var t = typeof propertyValue;
if (t === "number") {
getEnd = function() {
return propertyValue;
};
} else if (Array.isArray(propertyValue)) {
getStart = function() {
return propertyValue[0];
};
getEnd = function() {
return propertyValue[propertyValue.length - 1];
};
} else if (t === "string") {
var op = propertyValue.toLowerCase();
var isRandom = op.substring(0, 6) === "random";
var isInt = op.substring(0, 3) === "int";
if (isRandom || isInt) {
var brace1 = op.indexOf("(");
var brace2 = op.indexOf(")");
var comma = op.indexOf(",");
if (brace1 && brace2 && comma) {
var value1 = parseFloat(op.substring(brace1 + 1, comma));
var value2 = parseFloat(op.substring(comma + 1, brace2));
if (isRandom) {
getEnd = function() {
return FloatBetween(value1, value2);
};
} else {
getEnd = function() {
return Between(value1, value2);
};
}
} else {
throw new Error("invalid random() format");
}
} else {
op = op[0];
var num = parseFloat(propertyValue.substr(2));
switch (op) {
case "+":
getEnd = function(target, key2, value) {
return value + num;
};
break;
case "-":
getEnd = function(target, key2, value) {
return value - num;
};
break;
case "*":
getEnd = function(target, key2, value) {
return value * num;
};
break;
case "/":
getEnd = function(target, key2, value) {
return value / num;
};
break;
default:
getEnd = function() {
return parseFloat(propertyValue);
};
}
}
} else if (t === "function") {
getEnd = propertyValue;
} else if (t === "object") {
if (hasGetters(propertyValue)) {
if (hasGetActive(propertyValue)) {
getActive = propertyValue.getActive;
}
if (hasGetEnd(propertyValue)) {
getEnd = propertyValue.getEnd;
}
if (hasGetStart(propertyValue)) {
getStart = propertyValue.getStart;
}
} else if (propertyValue.hasOwnProperty("value")) {
callbacks = GetValueOp(key, propertyValue.value);
} else {
var hasTo = propertyValue.hasOwnProperty("to");
var hasFrom = propertyValue.hasOwnProperty("from");
var hasStart = propertyValue.hasOwnProperty("start");
if (hasTo && (hasFrom || hasStart)) {
callbacks = GetValueOp(key, propertyValue.to);
if (hasStart) {
var startCallbacks = GetValueOp(key, propertyValue.start);
callbacks.getActive = startCallbacks.getEnd;
}
if (hasFrom) {
var fromCallbacks = GetValueOp(key, propertyValue.from);
callbacks.getStart = fromCallbacks.getEnd;
}
}
}
}
if (!callbacks) {
callbacks = {
getActive,
getEnd,
getStart
};
}
return callbacks;
};
module2.exports = GetValueOp;
}
),
/***/
88032: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BaseTween = __webpack_require__2(70402);
var Defaults = __webpack_require__2(69902);
var GetAdvancedValue = __webpack_require__2(23568);
var GetBoolean = __webpack_require__2(57355);
var GetEaseFunction = __webpack_require__2(6113);
var GetNewValue = __webpack_require__2(55292);
var GetValue = __webpack_require__2(35154);
var GetValueOp = __webpack_require__2(17777);
var MergeRight = __webpack_require__2(269);
var Tween = __webpack_require__2(86081);
var NumberTweenBuilder = function(parent, config, defaults) {
if (config instanceof Tween) {
config.parent = parent;
return config;
}
if (defaults === void 0) {
defaults = Defaults;
} else {
defaults = MergeRight(Defaults, defaults);
}
var from = GetValue(config, "from", 0);
var to = GetValue(config, "to", 1);
var targets = [{ value: from }];
var delay = GetValue(config, "delay", defaults.delay);
var easeParams = GetValue(config, "easeParams", defaults.easeParams);
var ease = GetValue(config, "ease", defaults.ease);
var ops = GetValueOp("value", to);
var tween = new Tween(parent, targets);
var tweenData = tween.add(
0,
"value",
ops.getEnd,
ops.getStart,
ops.getActive,
GetEaseFunction(GetValue(config, "ease", ease), GetValue(config, "easeParams", easeParams)),
GetNewValue(config, "delay", delay),
GetValue(config, "duration", defaults.duration),
GetBoolean(config, "yoyo", defaults.yoyo),
GetValue(config, "hold", defaults.hold),
GetValue(config, "repeat", defaults.repeat),
GetValue(config, "repeatDelay", defaults.repeatDelay),
false,
false
);
tweenData.start = from;
tweenData.current = from;
tween.completeDelay = GetAdvancedValue(config, "completeDelay", 0);
tween.loop = Math.round(GetAdvancedValue(config, "loop", 0));
tween.loopDelay = Math.round(GetAdvancedValue(config, "loopDelay", 0));
tween.paused = GetBoolean(config, "paused", false);
tween.persist = GetBoolean(config, "persist", false);
tween.callbackScope = GetValue(config, "callbackScope", tween);
var callbacks = BaseTween.TYPES;
for (var i = 0; i < callbacks.length; i++) {
var type = callbacks[i];
var callback = GetValue(config, type, false);
if (callback) {
var callbackParams = GetValue(config, type + "Params", []);
tween.setCallback(type, callback, callbackParams);
}
}
return tween;
};
module2.exports = NumberTweenBuilder;
}
),
/***/
93109: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetEaseFunction = __webpack_require__2(6113);
var GetValue = __webpack_require__2(35154);
var MATH_CONST = __webpack_require__2(36383);
var StaggerBuilder = function(value, options) {
if (options === void 0) {
options = {};
}
var result;
var start = GetValue(options, "start", 0);
var ease = GetValue(options, "ease", null);
var grid = GetValue(options, "grid", null);
var from = GetValue(options, "from", 0);
var fromFirst = from === "first";
var fromCenter = from === "center";
var fromLast = from === "last";
var fromValue = typeof from === "number";
var isRange = Array.isArray(value);
var value1 = isRange ? parseFloat(value[0]) : parseFloat(value);
var value2 = isRange ? parseFloat(value[1]) : 0;
var maxValue = Math.max(value1, value2);
if (isRange) {
start += value1;
}
if (grid) {
var gridWidth = grid[0];
var gridHeight = grid[1];
var fromX = 0;
var fromY = 0;
var distanceX = 0;
var distanceY = 0;
var gridValues = [];
if (fromLast) {
fromX = gridWidth - 1;
fromY = gridHeight - 1;
} else if (fromValue) {
fromX = from % gridWidth;
fromY = Math.floor(from / gridWidth);
} else if (fromCenter) {
fromX = (gridWidth - 1) / 2;
fromY = (gridHeight - 1) / 2;
}
var gridMax = MATH_CONST.MIN_SAFE_INTEGER;
for (var toY = 0; toY < gridHeight; toY++) {
gridValues[toY] = [];
for (var toX = 0; toX < gridWidth; toX++) {
distanceX = fromX - toX;
distanceY = fromY - toY;
var dist = Math.sqrt(distanceX * distanceX + distanceY * distanceY);
if (dist > gridMax) {
gridMax = dist;
}
gridValues[toY][toX] = dist;
}
}
}
var easeFunction = ease ? GetEaseFunction(ease) : null;
if (grid) {
result = function(target, key, value3, index) {
var gridSpace = 0;
var toX2 = index % gridWidth;
var toY2 = Math.floor(index / gridWidth);
if (toX2 >= 0 && toX2 < gridWidth && toY2 >= 0 && toY2 < gridHeight) {
gridSpace = gridValues[toY2][toX2];
}
var output;
if (isRange) {
var diff = value2 - value1;
if (easeFunction) {
output = gridSpace / gridMax * diff * easeFunction(gridSpace / gridMax);
} else {
output = gridSpace / gridMax * diff;
}
} else if (easeFunction) {
output = gridSpace * value1 * easeFunction(gridSpace / gridMax);
} else {
output = gridSpace * value1;
}
return output + start;
};
} else {
result = function(target, key, value3, index, total) {
total--;
var fromIndex;
if (fromFirst) {
fromIndex = index;
} else if (fromCenter) {
fromIndex = Math.abs(total / 2 - index);
} else if (fromLast) {
fromIndex = total - index;
} else if (fromValue) {
fromIndex = Math.abs(from - index);
}
var output;
if (isRange) {
var spacing;
if (fromCenter) {
spacing = (value2 - value1) / total * (fromIndex * 2);
} else {
spacing = (value2 - value1) / total * fromIndex;
}
if (easeFunction) {
output = spacing * easeFunction(fromIndex / total);
} else {
output = spacing;
}
} else if (easeFunction) {
output = total * maxValue * easeFunction(fromIndex / total);
} else {
output = fromIndex * value1;
}
return output + start;
};
}
return result;
};
module2.exports = StaggerBuilder;
}
),
/***/
8357: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BaseTween = __webpack_require__2(70402);
var Defaults = __webpack_require__2(69902);
var GetAdvancedValue = __webpack_require__2(23568);
var GetBoolean = __webpack_require__2(57355);
var GetEaseFunction = __webpack_require__2(6113);
var GetInterpolationFunction = __webpack_require__2(91389);
var GetNewValue = __webpack_require__2(55292);
var GetProps = __webpack_require__2(82985);
var GetTargets = __webpack_require__2(62329);
var GetValue = __webpack_require__2(35154);
var GetValueOp = __webpack_require__2(17777);
var MergeRight = __webpack_require__2(269);
var Tween = __webpack_require__2(86081);
var TweenBuilder = function(parent, config, defaults) {
if (config instanceof Tween) {
config.parent = parent;
return config;
}
if (defaults === void 0) {
defaults = Defaults;
} else {
defaults = MergeRight(Defaults, defaults);
}
var targets = GetTargets(config);
if (!targets && defaults.targets) {
targets = defaults.targets;
}
var props = GetProps(config);
var delay = GetValue(config, "delay", defaults.delay);
var duration = GetValue(config, "duration", defaults.duration);
var easeParams = GetValue(config, "easeParams", defaults.easeParams);
var ease = GetValue(config, "ease", defaults.ease);
var hold = GetValue(config, "hold", defaults.hold);
var repeat = GetValue(config, "repeat", defaults.repeat);
var repeatDelay = GetValue(config, "repeatDelay", defaults.repeatDelay);
var yoyo = GetBoolean(config, "yoyo", defaults.yoyo);
var flipX = GetBoolean(config, "flipX", defaults.flipX);
var flipY = GetBoolean(config, "flipY", defaults.flipY);
var interpolation = GetValue(config, "interpolation", defaults.interpolation);
var addTarget = function(tween2, targetIndex2, key2, value2) {
if (key2 === "texture") {
var texture = value2;
var frame = void 0;
if (Array.isArray(value2)) {
texture = value2[0];
frame = value2[1];
} else if (value2.hasOwnProperty("value")) {
texture = value2.value;
if (Array.isArray(value2.value)) {
texture = value2.value[0];
frame = value2.value[1];
} else if (typeof value2.value === "string") {
texture = value2.value;
}
} else if (typeof value2 === "string") {
texture = value2;
}
tween2.addFrame(
targetIndex2,
texture,
frame,
GetNewValue(value2, "delay", delay),
GetValue(value2, "duration", duration),
GetValue(value2, "hold", hold),
GetValue(value2, "repeat", repeat),
GetValue(value2, "repeatDelay", repeatDelay),
GetBoolean(value2, "flipX", flipX),
GetBoolean(value2, "flipY", flipY)
);
} else {
var ops = GetValueOp(key2, value2);
var interpolationFunc = GetInterpolationFunction(GetValue(value2, "interpolation", interpolation));
tween2.add(
targetIndex2,
key2,
ops.getEnd,
ops.getStart,
ops.getActive,
GetEaseFunction(GetValue(value2, "ease", ease), GetValue(value2, "easeParams", easeParams)),
GetNewValue(value2, "delay", delay),
GetValue(value2, "duration", duration),
GetBoolean(value2, "yoyo", yoyo),
GetValue(value2, "hold", hold),
GetValue(value2, "repeat", repeat),
GetValue(value2, "repeatDelay", repeatDelay),
GetBoolean(value2, "flipX", flipX),
GetBoolean(value2, "flipY", flipY),
interpolationFunc,
interpolationFunc ? value2 : null
);
}
};
var tween = new Tween(parent, targets);
for (var p = 0; p < props.length; p++) {
var key = props[p].key;
var value = props[p].value;
for (var targetIndex = 0; targetIndex < targets.length; targetIndex++) {
if (key === "scale" && !targets[targetIndex].hasOwnProperty("scale")) {
addTarget(tween, targetIndex, "scaleX", value);
addTarget(tween, targetIndex, "scaleY", value);
} else {
addTarget(tween, targetIndex, key, value);
}
}
}
tween.completeDelay = GetAdvancedValue(config, "completeDelay", 0);
tween.loop = Math.round(GetAdvancedValue(config, "loop", 0));
tween.loopDelay = Math.round(GetAdvancedValue(config, "loopDelay", 0));
tween.paused = GetBoolean(config, "paused", false);
tween.persist = GetBoolean(config, "persist", false);
tween.callbackScope = GetValue(config, "callbackScope", tween);
var callbacks = BaseTween.TYPES;
for (var i = 0; i < callbacks.length; i++) {
var type = callbacks[i];
var callback = GetValue(config, type, false);
if (callback) {
var callbackParams = GetValue(config, type + "Params", []);
tween.setCallback(type, callback, callbackParams);
}
}
return tween;
};
module2.exports = TweenBuilder;
}
),
/***/
26012: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BaseTween = __webpack_require__2(70402);
var GetAdvancedValue = __webpack_require__2(23568);
var GetBoolean = __webpack_require__2(57355);
var GetTargets = __webpack_require__2(62329);
var GetValue = __webpack_require__2(35154);
var TweenBuilder = __webpack_require__2(8357);
var TweenChain = __webpack_require__2(43960);
var TweenChainBuilder = function(parent, config) {
if (config instanceof TweenChain) {
config.parent = parent;
return config;
}
var chain = new TweenChain(parent);
chain.startDelay = GetValue(config, "delay", 0);
chain.completeDelay = GetAdvancedValue(config, "completeDelay", 0);
chain.loop = Math.round(GetAdvancedValue(config, "loop", GetValue(config, "repeat", 0)));
chain.loopDelay = Math.round(GetAdvancedValue(config, "loopDelay", GetValue(config, "repeatDelay", 0)));
chain.paused = GetBoolean(config, "paused", false);
chain.persist = GetBoolean(config, "persist", false);
chain.callbackScope = GetValue(config, "callbackScope", chain);
var i;
var callbacks = BaseTween.TYPES;
for (i = 0; i < callbacks.length; i++) {
var type = callbacks[i];
var callback = GetValue(config, type, false);
if (callback) {
var callbackParams = GetValue(config, type + "Params", []);
chain.setCallback(type, callback, callbackParams);
}
}
var tweens = GetValue(config, "tweens", null);
if (Array.isArray(tweens)) {
var chainedTweens = [];
var targets = GetTargets(config);
var defaults = void 0;
if (targets) {
defaults = { targets };
}
for (i = 0; i < tweens.length; i++) {
chainedTweens.push(TweenBuilder(chain, tweens[i], defaults));
}
chain.add(chainedTweens);
}
return chain;
};
module2.exports = TweenChainBuilder;
}
),
/***/
30231: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
GetBoolean: __webpack_require__2(57355),
GetEaseFunction: __webpack_require__2(6113),
GetInterpolationFunction: __webpack_require__2(91389),
GetNewValue: __webpack_require__2(55292),
GetProps: __webpack_require__2(82985),
GetTargets: __webpack_require__2(62329),
GetValueOp: __webpack_require__2(17777),
NumberTweenBuilder: __webpack_require__2(88032),
StaggerBuilder: __webpack_require__2(93109),
TweenBuilder: __webpack_require__2(8357)
};
}
),
/***/
73685: (
/***/
(module2) => {
module2.exports = "active";
}
),
/***/
98540: (
/***/
(module2) => {
module2.exports = "complete";
}
),
/***/
67233: (
/***/
(module2) => {
module2.exports = "loop";
}
),
/***/
2859: (
/***/
(module2) => {
module2.exports = "pause";
}
),
/***/
98336: (
/***/
(module2) => {
module2.exports = "repeat";
}
),
/***/
25764: (
/***/
(module2) => {
module2.exports = "resume";
}
),
/***/
32193: (
/***/
(module2) => {
module2.exports = "start";
}
),
/***/
84371: (
/***/
(module2) => {
module2.exports = "stop";
}
),
/***/
70766: (
/***/
(module2) => {
module2.exports = "update";
}
),
/***/
55659: (
/***/
(module2) => {
module2.exports = "yoyo";
}
),
/***/
842: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
TWEEN_ACTIVE: __webpack_require__2(73685),
TWEEN_COMPLETE: __webpack_require__2(98540),
TWEEN_LOOP: __webpack_require__2(67233),
TWEEN_PAUSE: __webpack_require__2(2859),
TWEEN_RESUME: __webpack_require__2(25764),
TWEEN_REPEAT: __webpack_require__2(98336),
TWEEN_START: __webpack_require__2(32193),
TWEEN_STOP: __webpack_require__2(84371),
TWEEN_UPDATE: __webpack_require__2(70766),
TWEEN_YOYO: __webpack_require__2(55659)
};
}
),
/***/
43066: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Tweens = {
States: __webpack_require__2(86353),
Builders: __webpack_require__2(30231),
Events: __webpack_require__2(842),
TweenManager: __webpack_require__2(40382),
Tween: __webpack_require__2(86081),
TweenData: __webpack_require__2(48177),
TweenFrameData: __webpack_require__2(42220),
BaseTween: __webpack_require__2(70402),
TweenChain: __webpack_require__2(43960)
};
module2.exports = Tweens;
}
),
/***/
70402: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var EventEmitter = __webpack_require__2(50792);
var Events = __webpack_require__2(842);
var TWEEN_CONST = __webpack_require__2(86353);
var BaseTween = new Class({
Extends: EventEmitter,
initialize: function BaseTween2(parent) {
EventEmitter.call(this);
this.parent = parent;
this.data = [];
this.totalData = 0;
this.startDelay = 0;
this.hasStarted = false;
this.timeScale = 1;
this.loop = 0;
this.loopDelay = 0;
this.loopCounter = 0;
this.completeDelay = 0;
this.countdown = 0;
this.state = TWEEN_CONST.PENDING;
this.paused = false;
this.callbacks = {
onActive: null,
onComplete: null,
onLoop: null,
onPause: null,
onRepeat: null,
onResume: null,
onStart: null,
onStop: null,
onUpdate: null,
onYoyo: null
};
this.callbackScope;
this.persist = false;
},
/**
* Sets the value of the time scale applied to this Tween. A value of 1 runs in real-time.
* A value of 0.5 runs 50% slower, and so on.
*
* The value isn't used when calculating total duration of the tween, it's a run-time delta adjustment only.
*
* This value is multiplied by the `TweenManager.timeScale`.
*
* @method Phaser.Tweens.BaseTween#setTimeScale
* @since 3.60.0
*
* @param {number} value - The time scale value to set.
*
* @return {this} This Tween instance.
*/
setTimeScale: function(value) {
this.timeScale = value;
return this;
},
/**
* Gets the value of the time scale applied to this Tween. A value of 1 runs in real-time.
* A value of 0.5 runs 50% slower, and so on.
*
* @method Phaser.Tweens.BaseTween#getTimeScale
* @since 3.60.0
*
* @return {number} The value of the time scale applied to this Tween.
*/
getTimeScale: function() {
return this.timeScale;
},
/**
* Checks if this Tween is currently playing.
*
* If this Tween is paused, or not active, this method will return false.
*
* @method Phaser.Tweens.BaseTween#isPlaying
* @since 3.60.0
*
* @return {boolean} `true` if the Tween is playing, otherwise `false`.
*/
isPlaying: function() {
return !this.paused && this.isActive();
},
/**
* Checks if the Tween is currently paused.
*
* This is the same as inspecting the `BaseTween.paused` property directly.
*
* @method Phaser.Tweens.BaseTween#isPaused
* @since 3.60.0
*
* @return {boolean} `true` if the Tween is paused, otherwise `false`.
*/
isPaused: function() {
return this.paused;
},
/**
* Pauses the Tween immediately. Use `resume` to continue playback.
*
* You can also toggle the `Tween.paused` boolean property, but doing so will not trigger the PAUSE event.
*
* @method Phaser.Tweens.BaseTween#pause
* @fires Phaser.Tweens.Events#TWEEN_PAUSE
* @since 3.60.0
*
* @return {this} This Tween instance.
*/
pause: function() {
if (!this.paused) {
this.paused = true;
this.dispatchEvent(Events.TWEEN_PAUSE, "onPause");
}
return this;
},
/**
* Resumes the playback of a previously paused Tween.
*
* You can also toggle the `Tween.paused` boolean property, but doing so will not trigger the RESUME event.
*
* @method Phaser.Tweens.BaseTween#resume
* @fires Phaser.Tweens.Events#TWEEN_RESUME
* @since 3.60.0
*
* @return {this} This Tween instance.
*/
resume: function() {
if (this.paused) {
this.paused = false;
this.dispatchEvent(Events.TWEEN_RESUME, "onResume");
}
return this;
},
/**
* Internal method that makes this Tween active within the TweenManager
* and emits the onActive event and callback.
*
* @method Phaser.Tweens.BaseTween#makeActive
* @fires Phaser.Tweens.Events#TWEEN_ACTIVE
* @since 3.60.0
*/
makeActive: function() {
this.parent.makeActive(this);
this.dispatchEvent(Events.TWEEN_ACTIVE, "onActive");
},
/**
* Internal method that handles this tween completing and emitting the onComplete event
* and callback.
*
* @method Phaser.Tweens.BaseTween#onCompleteHandler
* @since 3.60.0
*/
onCompleteHandler: function() {
this.setPendingRemoveState();
this.dispatchEvent(Events.TWEEN_COMPLETE, "onComplete");
},
/**
* Flags the Tween as being complete, whatever stage of progress it is at.
*
* If an `onComplete` callback has been defined it will automatically invoke it, unless a `delay`
* argument is provided, in which case the Tween will delay for that period of time before calling the callback.
*
* If you don't need a delay or don't have an `onComplete` callback then call `Tween.stop` instead.
*
* @method Phaser.Tweens.BaseTween#complete
* @fires Phaser.Tweens.Events#TWEEN_COMPLETE
* @since 3.2.0
*
* @param {number} [delay=0] - The time to wait before invoking the complete callback. If zero it will fire immediately.
*
* @return {this} This Tween instance.
*/
complete: function(delay) {
if (delay === void 0) {
delay = 0;
}
if (delay) {
this.setCompleteDelayState();
this.countdown = delay;
} else {
this.onCompleteHandler();
}
return this;
},
/**
* Flags the Tween as being complete only once the current loop has finished.
*
* This is a useful way to stop an infinitely looping tween once a complete cycle is over,
* rather than abruptly.
*
* If you don't have a loop then call `Tween.stop` instead.
*
* @method Phaser.Tweens.BaseTween#completeAfterLoop
* @fires Phaser.Tweens.Events#TWEEN_COMPLETE
* @since 3.60.0
*
* @param {number} [loops=0] - The number of loops that should finish before this tween completes. Zero means complete just the current loop.
*
* @return {this} This Tween instance.
*/
completeAfterLoop: function(loops) {
if (loops === void 0) {
loops = 0;
}
if (this.loopCounter > loops) {
this.loopCounter = loops;
}
return this;
},
/**
* Immediately removes this Tween from the TweenManager and all of its internal arrays,
* no matter what stage it is at. Then sets the tween state to `REMOVED`.
*
* You should dispose of your reference to this tween after calling this method, to
* free it from memory. If you no longer require it, call `Tween.destroy()` on it.
*
* @method Phaser.Tweens.BaseTween#remove
* @since 3.60.0
*
* @return {this} This Tween instance.
*/
remove: function() {
if (this.parent) {
this.parent.remove(this);
}
return this;
},
/**
* Stops the Tween immediately, whatever stage of progress it is at.
*
* If not a part of a Tween Chain it is also flagged for removal by the Tween Manager.
*
* If an `onStop` callback has been defined it will automatically invoke it.
*
* The Tween will be removed during the next game frame, but should be considered 'destroyed' from this point on.
*
* Typically, you cannot play a Tween that has been stopped. If you just wish to pause the tween, not destroy it,
* then call the `pause` method instead and use `resume` to continue playback. If you wish to restart the Tween,
* use the `restart` or `seek` methods.
*
* @method Phaser.Tweens.BaseTween#stop
* @fires Phaser.Tweens.Events#TWEEN_STOP
* @since 3.60.0
*
* @return {this} This Tween instance.
*/
stop: function() {
if (this.parent && !this.isRemoved() && !this.isPendingRemove() && !this.isDestroyed()) {
this.dispatchEvent(Events.TWEEN_STOP, "onStop");
this.setPendingRemoveState();
}
return this;
},
/**
* Internal method that handles the processing of the loop delay countdown timer and
* the dispatch of related events. Called automatically by `Tween.update`.
*
* @method Phaser.Tweens.BaseTween#updateLoopCountdown
* @since 3.60.0
*
* @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
*/
updateLoopCountdown: function(delta) {
this.countdown -= delta;
if (this.countdown <= 0) {
this.setActiveState();
this.dispatchEvent(Events.TWEEN_LOOP, "onLoop");
}
},
/**
* Internal method that handles the processing of the start delay countdown timer and
* the dispatch of related events. Called automatically by `Tween.update`.
*
* @method Phaser.Tweens.BaseTween#updateStartCountdown
* @since 3.60.0
*
* @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
*/
updateStartCountdown: function(delta) {
this.countdown -= delta;
if (this.countdown <= 0) {
this.hasStarted = true;
this.setActiveState();
this.dispatchEvent(Events.TWEEN_START, "onStart");
delta = 0;
}
return delta;
},
/**
* Internal method that handles the processing of the complete delay countdown timer and
* the dispatch of related events. Called automatically by `Tween.update`.
*
* @method Phaser.Tweens.BaseTween#updateCompleteDelay
* @since 3.60.0
*
* @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
*/
updateCompleteDelay: function(delta) {
this.countdown -= delta;
if (this.countdown <= 0) {
this.onCompleteHandler();
}
},
/**
* Sets an event based callback to be invoked during playback.
*
* Calling this method will replace a previously set callback for the given type, if any exists.
*
* The types available are:
*
* `onActive` - When the Tween is first created it moves to an 'active' state when added to the Tween Manager. 'Active' does not mean 'playing'.
* `onStart` - When the Tween starts playing after a delayed or paused state. This will happen at the same time as `onActive` if the tween has no delay and isn't paused.
* `onLoop` - When a Tween loops, if it has been set to do so. This happens _after_ the `loopDelay` expires, if set.
* `onComplete` - When the Tween finishes playback fully. Never invoked if the Tween is set to repeat infinitely.
* `onStop` - Invoked only if the `Tween.stop` method is called.
* `onPause` - Invoked only if the `Tween.pause` method is called. Not invoked if the Tween Manager is paused.
* `onResume` - Invoked only if the `Tween.resume` method is called. Not invoked if the Tween Manager is resumed.
*
* The following types are also available and are invoked on a `TweenData` level - that is per-object, per-property, being tweened.
*
* `onYoyo` - When a TweenData starts a yoyo. This happens _after_ the `hold` delay expires, if set.
* `onRepeat` - When a TweenData repeats playback. This happens _after_ the `repeatDelay` expires, if set.
* `onUpdate` - When a TweenData updates a property on a source target during playback.
*
* @method Phaser.Tweens.BaseTween#setCallback
* @since 3.60.0
*
* @param {Phaser.Types.Tweens.TweenCallbackTypes} type - The type of callback to set. One of: `onActive`, `onComplete`, `onLoop`, `onPause`, `onRepeat`, `onResume`, `onStart`, `onStop`, `onUpdate` or `onYoyo`.
* @param {function} callback - Your callback that will be invoked.
* @param {array} [params] - The parameters to pass to the callback. Pass an empty array if you don't want to define any, but do wish to set the scope.
*
* @return {this} This Tween instance.
*/
setCallback: function(type, callback, params) {
if (params === void 0) {
params = [];
}
if (this.callbacks.hasOwnProperty(type)) {
this.callbacks[type] = { func: callback, params };
}
return this;
},
/**
* Sets this Tween state to PENDING.
*
* @method Phaser.Tweens.BaseTween#setPendingState
* @since 3.60.0
*/
setPendingState: function() {
this.state = TWEEN_CONST.PENDING;
},
/**
* Sets this Tween state to ACTIVE.
*
* @method Phaser.Tweens.BaseTween#setActiveState
* @since 3.60.0
*/
setActiveState: function() {
this.state = TWEEN_CONST.ACTIVE;
this.hasStarted = false;
},
/**
* Sets this Tween state to LOOP_DELAY.
*
* @method Phaser.Tweens.BaseTween#setLoopDelayState
* @since 3.60.0
*/
setLoopDelayState: function() {
this.state = TWEEN_CONST.LOOP_DELAY;
},
/**
* Sets this Tween state to COMPLETE_DELAY.
*
* @method Phaser.Tweens.BaseTween#setCompleteDelayState
* @since 3.60.0
*/
setCompleteDelayState: function() {
this.state = TWEEN_CONST.COMPLETE_DELAY;
},
/**
* Sets this Tween state to START_DELAY.
*
* @method Phaser.Tweens.BaseTween#setStartDelayState
* @since 3.60.0
*/
setStartDelayState: function() {
this.state = TWEEN_CONST.START_DELAY;
this.countdown = this.startDelay;
this.hasStarted = false;
},
/**
* Sets this Tween state to PENDING_REMOVE.
*
* @method Phaser.Tweens.BaseTween#setPendingRemoveState
* @since 3.60.0
*/
setPendingRemoveState: function() {
this.state = TWEEN_CONST.PENDING_REMOVE;
},
/**
* Sets this Tween state to REMOVED.
*
* @method Phaser.Tweens.BaseTween#setRemovedState
* @since 3.60.0
*/
setRemovedState: function() {
this.state = TWEEN_CONST.REMOVED;
},
/**
* Sets this Tween state to FINISHED.
*
* @method Phaser.Tweens.BaseTween#setFinishedState
* @since 3.60.0
*/
setFinishedState: function() {
this.state = TWEEN_CONST.FINISHED;
},
/**
* Sets this Tween state to DESTROYED.
*
* @method Phaser.Tweens.BaseTween#setDestroyedState
* @since 3.60.0
*/
setDestroyedState: function() {
this.state = TWEEN_CONST.DESTROYED;
},
/**
* Returns `true` if this Tween has a _current_ state of PENDING, otherwise `false`.
*
* @method Phaser.Tweens.BaseTween#isPending
* @since 3.60.0
*
* @return {boolean} `true` if this Tween has a _current_ state of PENDING, otherwise `false`.
*/
isPending: function() {
return this.state === TWEEN_CONST.PENDING;
},
/**
* Returns `true` if this Tween has a _current_ state of ACTIVE, otherwise `false`.
*
* @method Phaser.Tweens.BaseTween#isActive
* @since 3.60.0
*
* @return {boolean} `true` if this Tween has a _current_ state of ACTIVE, otherwise `false`.
*/
isActive: function() {
return this.state === TWEEN_CONST.ACTIVE;
},
/**
* Returns `true` if this Tween has a _current_ state of LOOP_DELAY, otherwise `false`.
*
* @method Phaser.Tweens.BaseTween#isLoopDelayed
* @since 3.60.0
*
* @return {boolean} `true` if this Tween has a _current_ state of LOOP_DELAY, otherwise `false`.
*/
isLoopDelayed: function() {
return this.state === TWEEN_CONST.LOOP_DELAY;
},
/**
* Returns `true` if this Tween has a _current_ state of COMPLETE_DELAY, otherwise `false`.
*
* @method Phaser.Tweens.BaseTween#isCompleteDelayed
* @since 3.60.0
*
* @return {boolean} `true` if this Tween has a _current_ state of COMPLETE_DELAY, otherwise `false`.
*/
isCompleteDelayed: function() {
return this.state === TWEEN_CONST.COMPLETE_DELAY;
},
/**
* Returns `true` if this Tween has a _current_ state of START_DELAY, otherwise `false`.
*
* @method Phaser.Tweens.BaseTween#isStartDelayed
* @since 3.60.0
*
* @return {boolean} `true` if this Tween has a _current_ state of START_DELAY, otherwise `false`.
*/
isStartDelayed: function() {
return this.state === TWEEN_CONST.START_DELAY;
},
/**
* Returns `true` if this Tween has a _current_ state of PENDING_REMOVE, otherwise `false`.
*
* @method Phaser.Tweens.BaseTween#isPendingRemove
* @since 3.60.0
*
* @return {boolean} `true` if this Tween has a _current_ state of PENDING_REMOVE, otherwise `false`.
*/
isPendingRemove: function() {
return this.state === TWEEN_CONST.PENDING_REMOVE;
},
/**
* Returns `true` if this Tween has a _current_ state of REMOVED, otherwise `false`.
*
* @method Phaser.Tweens.BaseTween#isRemoved
* @since 3.60.0
*
* @return {boolean} `true` if this Tween has a _current_ state of REMOVED, otherwise `false`.
*/
isRemoved: function() {
return this.state === TWEEN_CONST.REMOVED;
},
/**
* Returns `true` if this Tween has a _current_ state of FINISHED, otherwise `false`.
*
* @method Phaser.Tweens.BaseTween#isFinished
* @since 3.60.0
*
* @return {boolean} `true` if this Tween has a _current_ state of FINISHED, otherwise `false`.
*/
isFinished: function() {
return this.state === TWEEN_CONST.FINISHED;
},
/**
* Returns `true` if this Tween has a _current_ state of DESTROYED, otherwise `false`.
*
* @method Phaser.Tweens.BaseTween#isDestroyed
* @since 3.60.0
*
* @return {boolean} `true` if this Tween has a _current_ state of DESTROYED, otherwise `false`.
*/
isDestroyed: function() {
return this.state === TWEEN_CONST.DESTROYED;
},
/**
* Handles the destroy process of this Tween, clearing out the
* Tween Data and resetting the targets. A Tween that has been
* destroyed cannot ever be played or used again.
*
* @method Phaser.Tweens.BaseTween#destroy
* @since 3.60.0
*/
destroy: function() {
if (this.data) {
this.data.forEach(function(tweenData) {
tweenData.destroy();
});
}
this.removeAllListeners();
this.callbacks = null;
this.data = null;
this.parent = null;
this.setDestroyedState();
}
});
BaseTween.TYPES = [
"onActive",
"onComplete",
"onLoop",
"onPause",
"onRepeat",
"onResume",
"onStart",
"onStop",
"onUpdate",
"onYoyo"
];
module2.exports = BaseTween;
}
),
/***/
95042: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Class = __webpack_require__2(83419);
var Events = __webpack_require__2(842);
var TWEEN_CONST = __webpack_require__2(86353);
var BaseTweenData = new Class({
initialize: function BaseTweenData2(tween, targetIndex, delay, duration, yoyo, hold, repeat, repeatDelay, flipX, flipY) {
this.tween = tween;
this.targetIndex = targetIndex;
this.duration = duration;
this.totalDuration = 0;
this.delay = 0;
this.getDelay = delay;
this.yoyo = yoyo;
this.hold = hold;
this.repeat = repeat;
this.repeatDelay = repeatDelay;
this.repeatCounter = 0;
this.flipX = flipX;
this.flipY = flipY;
this.progress = 0;
this.elapsed = 0;
this.state = 0;
this.isCountdown = false;
},
/**
* Returns a reference to the target object belonging to this TweenData.
*
* @method Phaser.Tweens.BaseTweenData#getTarget
* @since 3.60.0
*
* @return {object} The target object. Can be any JavaScript object, but is typically a Game Object.
*/
getTarget: function() {
return this.tween.targets[this.targetIndex];
},
/**
* Sets this TweenData's target object property to be the given value.
*
* @method Phaser.Tweens.BaseTweenData#setTargetValue
* @since 3.60.0
*
* @param {number} [value] - The value to set on the target. If not given, sets it to the last `current` value.
*/
setTargetValue: function(value) {
if (value === void 0) {
value = this.current;
}
this.tween.targets[this.targetIndex][this.key] = value;
},
/**
* Sets this TweenData state to CREATED.
*
* @method Phaser.Tweens.BaseTweenData#setCreatedState
* @since 3.60.0
*/
setCreatedState: function() {
this.state = TWEEN_CONST.CREATED;
this.isCountdown = false;
},
/**
* Sets this TweenData state to DELAY.
*
* @method Phaser.Tweens.BaseTweenData#setDelayState
* @since 3.60.0
*/
setDelayState: function() {
this.state = TWEEN_CONST.DELAY;
this.isCountdown = true;
},
/**
* Sets this TweenData state to PENDING_RENDER.
*
* @method Phaser.Tweens.BaseTweenData#setPendingRenderState
* @since 3.60.0
*/
setPendingRenderState: function() {
this.state = TWEEN_CONST.PENDING_RENDER;
this.isCountdown = false;
},
/**
* Sets this TweenData state to PLAYING_FORWARD.
*
* @method Phaser.Tweens.BaseTweenData#setPlayingForwardState
* @since 3.60.0
*/
setPlayingForwardState: function() {
this.state = TWEEN_CONST.PLAYING_FORWARD;
this.isCountdown = false;
},
/**
* Sets this TweenData state to PLAYING_BACKWARD.
*
* @method Phaser.Tweens.BaseTweenData#setPlayingBackwardState
* @since 3.60.0
*/
setPlayingBackwardState: function() {
this.state = TWEEN_CONST.PLAYING_BACKWARD;
this.isCountdown = false;
},
/**
* Sets this TweenData state to HOLD_DELAY.
*
* @method Phaser.Tweens.BaseTweenData#setHoldState
* @since 3.60.0
*/
setHoldState: function() {
this.state = TWEEN_CONST.HOLD_DELAY;
this.isCountdown = true;
},
/**
* Sets this TweenData state to REPEAT_DELAY.
*
* @method Phaser.Tweens.BaseTweenData#setRepeatState
* @since 3.60.0
*/
setRepeatState: function() {
this.state = TWEEN_CONST.REPEAT_DELAY;
this.isCountdown = true;
},
/**
* Sets this TweenData state to COMPLETE.
*
* @method Phaser.Tweens.BaseTweenData#setCompleteState
* @since 3.60.0
*/
setCompleteState: function() {
this.state = TWEEN_CONST.COMPLETE;
this.isCountdown = false;
},
/**
* Returns `true` if this TweenData has a _current_ state of CREATED, otherwise `false`.
*
* @method Phaser.Tweens.BaseTweenData#isCreated
* @since 3.60.0
*
* @return {boolean} `true` if this TweenData has a _current_ state of CREATED, otherwise `false`.
*/
isCreated: function() {
return this.state === TWEEN_CONST.CREATED;
},
/**
* Returns `true` if this TweenData has a _current_ state of DELAY, otherwise `false`.
*
* @method Phaser.Tweens.BaseTweenData#isDelayed
* @since 3.60.0
*
* @return {boolean} `true` if this TweenData has a _current_ state of DELAY, otherwise `false`.
*/
isDelayed: function() {
return this.state === TWEEN_CONST.DELAY;
},
/**
* Returns `true` if this TweenData has a _current_ state of PENDING_RENDER, otherwise `false`.
*
* @method Phaser.Tweens.BaseTweenData#isPendingRender
* @since 3.60.0
*
* @return {boolean} `true` if this TweenData has a _current_ state of PENDING_RENDER, otherwise `false`.
*/
isPendingRender: function() {
return this.state === TWEEN_CONST.PENDING_RENDER;
},
/**
* Returns `true` if this TweenData has a _current_ state of PLAYING_FORWARD, otherwise `false`.
*
* @method Phaser.Tweens.BaseTweenData#isPlayingForward
* @since 3.60.0
*
* @return {boolean} `true` if this TweenData has a _current_ state of PLAYING_FORWARD, otherwise `false`.
*/
isPlayingForward: function() {
return this.state === TWEEN_CONST.PLAYING_FORWARD;
},
/**
* Returns `true` if this TweenData has a _current_ state of PLAYING_BACKWARD, otherwise `false`.
*
* @method Phaser.Tweens.BaseTweenData#isPlayingBackward
* @since 3.60.0
*
* @return {boolean} `true` if this TweenData has a _current_ state of PLAYING_BACKWARD, otherwise `false`.
*/
isPlayingBackward: function() {
return this.state === TWEEN_CONST.PLAYING_BACKWARD;
},
/**
* Returns `true` if this TweenData has a _current_ state of HOLD_DELAY, otherwise `false`.
*
* @method Phaser.Tweens.BaseTweenData#isHolding
* @since 3.60.0
*
* @return {boolean} `true` if this TweenData has a _current_ state of HOLD_DELAY, otherwise `false`.
*/
isHolding: function() {
return this.state === TWEEN_CONST.HOLD_DELAY;
},
/**
* Returns `true` if this TweenData has a _current_ state of REPEAT_DELAY, otherwise `false`.
*
* @method Phaser.Tweens.BaseTweenData#isRepeating
* @since 3.60.0
*
* @return {boolean} `true` if this TweenData has a _current_ state of REPEAT_DELAY, otherwise `false`.
*/
isRepeating: function() {
return this.state === TWEEN_CONST.REPEAT_DELAY;
},
/**
* Returns `true` if this TweenData has a _current_ state of COMPLETE, otherwise `false`.
*
* @method Phaser.Tweens.BaseTweenData#isComplete
* @since 3.60.0
*
* @return {boolean} `true` if this TweenData has a _current_ state of COMPLETE, otherwise `false`.
*/
isComplete: function() {
return this.state === TWEEN_CONST.COMPLETE;
},
/**
* Internal method used as part of the playback process that checks if this
* TweenData should yoyo, repeat, or has completed.
*
* @method Phaser.Tweens.BaseTweenData#setStateFromEnd
* @fires Phaser.Tweens.Events#TWEEN_REPEAT
* @fires Phaser.Tweens.Events#TWEEN_YOYO
* @since 3.60.0
*
* @param {number} diff - Any extra time that needs to be accounted for in the elapsed and progress values.
*/
setStateFromEnd: function(diff) {
if (this.yoyo) {
this.onRepeat(diff, true, true);
} else if (this.repeatCounter > 0) {
this.onRepeat(diff, true, false);
} else {
this.setCompleteState();
}
},
/**
* Internal method used as part of the playback process that checks if this
* TweenData should repeat or has completed.
*
* @method Phaser.Tweens.BaseTweenData#setStateFromStart
* @fires Phaser.Tweens.Events#TWEEN_REPEAT
* @since 3.60.0
*
* @param {number} diff - Any extra time that needs to be accounted for in the elapsed and progress values.
*/
setStateFromStart: function(diff) {
if (this.repeatCounter > 0) {
this.onRepeat(diff, false);
} else {
this.setCompleteState();
}
},
/**
* Internal method that resets this Tween Data entirely, including the progress and elapsed values.
*
* Called automatically by the parent Tween. Should not be called directly.
*
* @method Phaser.Tweens.BaseTweenData#reset
* @since 3.60.0
*/
reset: function() {
var tween = this.tween;
var totalTargets = tween.totalTargets;
var targetIndex = this.targetIndex;
var target = tween.targets[targetIndex];
var key = this.key;
this.progress = 0;
this.elapsed = 0;
this.delay = this.getDelay(target, key, 0, targetIndex, totalTargets, tween);
this.repeatCounter = this.repeat === -1 ? TWEEN_CONST.MAX : this.repeat;
this.setPendingRenderState();
var t1 = this.duration + this.hold;
if (this.yoyo) {
t1 += this.duration;
}
var t2 = t1 + this.repeatDelay;
this.totalDuration = this.delay + t1;
if (this.repeat === -1) {
this.totalDuration += t2 * TWEEN_CONST.MAX;
tween.isInfinite = true;
} else if (this.repeat > 0) {
this.totalDuration += t2 * this.repeat;
}
if (this.totalDuration > tween.duration) {
tween.duration = this.totalDuration;
}
if (this.delay < tween.startDelay) {
tween.startDelay = this.delay;
}
if (this.delay > 0) {
this.elapsed = this.delay;
this.setDelayState();
}
},
/**
* Internal method that handles repeating or yoyo'ing this TweenData.
*
* Called automatically by `setStateFromStart` and `setStateFromEnd`.
*
* @method Phaser.Tweens.BaseTweenData#onRepeat
* @fires Phaser.Tweens.Events#TWEEN_REPEAT
* @fires Phaser.Tweens.Events#TWEEN_YOYO
* @since 3.60.0
*
* @param {number} diff - Any extra time that needs to be accounted for in the elapsed and progress values.
* @param {boolean} setStart - Set the TweenData start values?
* @param {boolean} isYoyo - Is this call a Yoyo check?
*/
onRepeat: function(diff, setStart, isYoyo) {
var tween = this.tween;
var totalTargets = tween.totalTargets;
var targetIndex = this.targetIndex;
var target = tween.targets[targetIndex];
var key = this.key;
var isTweenData = key !== "texture";
this.elapsed = diff;
this.progress = diff / this.duration;
if (this.flipX) {
target.toggleFlipX();
}
if (this.flipY) {
target.toggleFlipY();
}
if (isTweenData && (setStart || isYoyo)) {
this.start = this.getStartValue(target, key, this.start, targetIndex, totalTargets, tween);
}
if (isYoyo) {
this.setPlayingBackwardState();
this.dispatchEvent(Events.TWEEN_YOYO, "onYoyo");
return;
}
this.repeatCounter--;
if (isTweenData) {
this.end = this.getEndValue(target, key, this.start, targetIndex, totalTargets, tween);
}
if (this.repeatDelay > 0) {
this.elapsed = this.repeatDelay - diff;
if (isTweenData) {
this.current = this.start;
target[key] = this.current;
}
this.setRepeatState();
} else {
this.setPlayingForwardState();
this.dispatchEvent(Events.TWEEN_REPEAT, "onRepeat");
}
},
/**
* Immediately destroys this TweenData, nulling of all its references.
*
* @method Phaser.Tweens.BaseTweenData#destroy
* @since 3.60.0
*/
destroy: function() {
this.tween = null;
this.getDelay = null;
this.setCompleteState();
}
});
module2.exports = BaseTweenData;
}
),
/***/
69902: (
/***/
(module2) => {
var TWEEN_DEFAULTS = {
targets: null,
delay: 0,
duration: 1e3,
ease: "Power0",
easeParams: null,
hold: 0,
repeat: 0,
repeatDelay: 0,
yoyo: false,
flipX: false,
flipY: false,
persist: false,
interpolation: null
};
module2.exports = TWEEN_DEFAULTS;
}
),
/***/
81076: (
/***/
(module2) => {
module2.exports = [
"callbackScope",
"completeDelay",
"delay",
"duration",
"ease",
"easeParams",
"flipX",
"flipY",
"hold",
"interpolation",
"loop",
"loopDelay",
"onActive",
"onActiveParams",
"onComplete",
"onCompleteParams",
"onLoop",
"onLoopParams",
"onPause",
"onPauseParams",
"onRepeat",
"onRepeatParams",
"onResume",
"onResumeParams",
"onStart",
"onStartParams",
"onStop",
"onStopParams",
"onUpdate",
"onUpdateParams",
"onYoyo",
"onYoyoParams",
"paused",
"persist",
"props",
"repeat",
"repeatDelay",
"targets",
"yoyo"
];
}
),
/***/
86081: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BaseTween = __webpack_require__2(70402);
var Class = __webpack_require__2(83419);
var Events = __webpack_require__2(842);
var GameObjectCreator = __webpack_require__2(44603);
var GameObjectFactory = __webpack_require__2(39429);
var MATH_CONST = __webpack_require__2(36383);
var TWEEN_CONST = __webpack_require__2(86353);
var TweenData = __webpack_require__2(48177);
var TweenFrameData = __webpack_require__2(42220);
var Tween = new Class({
Extends: BaseTween,
initialize: function Tween2(parent, targets) {
BaseTween.call(this, parent);
this.targets = targets;
this.totalTargets = targets.length;
this.isSeeking = false;
this.isInfinite = false;
this.elapsed = 0;
this.totalElapsed = 0;
this.duration = 0;
this.progress = 0;
this.totalDuration = 0;
this.totalProgress = 0;
},
/**
* Adds a new TweenData to this Tween. Typically, this method is called
* automatically by the TweenBuilder, however you can also invoke it
* yourself.
*
* @method Phaser.Tweens.Tween#add
* @since 3.60.0
*
* @param {number} targetIndex - The target index within the Tween targets array.
* @param {string} key - The property of the target to tween.
* @param {Phaser.Types.Tweens.GetEndCallback} getEnd - What the property will be at the END of the Tween.
* @param {Phaser.Types.Tweens.GetStartCallback} getStart - What the property will be at the START of the Tween.
* @param {?Phaser.Types.Tweens.GetActiveCallback} getActive - If not null, is invoked _immediately_ as soon as the TweenData is running, and is set on the target property.
* @param {function} ease - The ease function this tween uses.
* @param {function} delay - Function that returns the time in milliseconds before tween will start.
* @param {number} duration - The duration of the tween in milliseconds.
* @param {boolean} yoyo - Determines whether the tween should return back to its start value after hold has expired.
* @param {number} hold - Function that returns the time in milliseconds the tween will pause before repeating or returning to its starting value if yoyo is set to true.
* @param {number} repeat - Function that returns the number of times to repeat the tween. The tween will always run once regardless, so a repeat value of '1' will play the tween twice.
* @param {number} repeatDelay - Function that returns the time in milliseconds before the repeat will start.
* @param {boolean} flipX - Should toggleFlipX be called when yoyo or repeat happens?
* @param {boolean} flipY - Should toggleFlipY be called when yoyo or repeat happens?
* @param {?function} interpolation - The interpolation function to be used for arrays of data. Defaults to 'null'.
* @param {?number[]} interpolationData - The array of interpolation data to be set. Defaults to 'null'.
*
* @return {Phaser.Tweens.TweenData} The TweenData instance that was added.
*/
add: function(targetIndex, key, getEnd, getStart, getActive, ease, delay, duration, yoyo, hold, repeat, repeatDelay, flipX, flipY, interpolation, interpolationData) {
var tweenData = new TweenData(this, targetIndex, key, getEnd, getStart, getActive, ease, delay, duration, yoyo, hold, repeat, repeatDelay, flipX, flipY, interpolation, interpolationData);
this.totalData = this.data.push(tweenData);
return tweenData;
},
/**
* Adds a new TweenFrameData to this Tween. Typically, this method is called
* automatically by the TweenBuilder, however you can also invoke it
* yourself.
*
* @method Phaser.Tweens.Tween#addFrame
* @since 3.60.0
*
* @param {number} targetIndex - The target index within the Tween targets array.
* @param {string} texture - The texture to set on the target at the end of the tween.
* @param {string|number} frame - The texture frame to set on the target at the end of the tween.
* @param {function} delay - Function that returns the time in milliseconds before tween will start.
* @param {number} duration - The duration of the tween in milliseconds.
* @param {number} hold - Function that returns the time in milliseconds the tween will pause before repeating or returning to its starting value if yoyo is set to true.
* @param {number} repeat - Function that returns the number of times to repeat the tween. The tween will always run once regardless, so a repeat value of '1' will play the tween twice.
* @param {number} repeatDelay - Function that returns the time in milliseconds before the repeat will start.
* @param {boolean} flipX - Should toggleFlipX be called when yoyo or repeat happens?
* @param {boolean} flipY - Should toggleFlipY be called when yoyo or repeat happens?
*
* @return {Phaser.Tweens.TweenFrameData} The TweenFrameData instance that was added.
*/
addFrame: function(targetIndex, texture, frame, delay, duration, hold, repeat, repeatDelay, flipX, flipY) {
var tweenData = new TweenFrameData(this, targetIndex, texture, frame, delay, duration, hold, repeat, repeatDelay, flipX, flipY);
this.totalData = this.data.push(tweenData);
return tweenData;
},
/**
* Returns the current value of the specified Tween Data.
*
* If this Tween has been destroyed, it will return `null`.
*
* @method Phaser.Tweens.Tween#getValue
* @since 3.0.0
*
* @param {number} [index=0] - The Tween Data to return the value from.
*
* @return {number} The value of the requested Tween Data, or `null` if this Tween has been destroyed.
*/
getValue: function(index) {
if (index === void 0) {
index = 0;
}
var value = null;
if (this.data) {
value = this.data[index].current;
}
return value;
},
/**
* See if this Tween is currently acting upon the given target.
*
* @method Phaser.Tweens.Tween#hasTarget
* @since 3.0.0
*
* @param {object} target - The target to check against this Tween.
*
* @return {boolean} `true` if the given target is a target of this Tween, otherwise `false`.
*/
hasTarget: function(target) {
return this.targets && this.targets.indexOf(target) !== -1;
},
/**
* Updates the 'end' value of the given property across all matching targets, as long
* as this Tween is currently playing (either forwards or backwards).
*
* Calling this does not adjust the duration of the Tween, or the current progress.
*
* You can optionally tell it to set the 'start' value to be the current value.
*
* If this Tween is in any other state other than playing then calling this method has no effect.
*
* Additionally, if the Tween repeats, is reset, or is seeked, it will revert to the original
* starting and ending values.
*
* @method Phaser.Tweens.Tween#updateTo
* @since 3.0.0
*
* @param {string} key - The property to set the new value for. You cannot update the 'texture' property via this method.
* @param {number} value - The new value of the property.
* @param {boolean} [startToCurrent=false] - Should this change set the start value to be the current value?
*
* @return {this} This Tween instance.
*/
updateTo: function(key, value, startToCurrent) {
if (startToCurrent === void 0) {
startToCurrent = false;
}
if (key !== "texture") {
for (var i = 0; i < this.totalData; i++) {
var tweenData = this.data[i];
if (tweenData.key === key && (tweenData.isPlayingForward() || tweenData.isPlayingBackward())) {
tweenData.end = value;
if (startToCurrent) {
tweenData.start = tweenData.current;
}
}
}
}
return this;
},
/**
* Restarts the Tween from the beginning.
*
* If the Tween has already finished and been destroyed, restarting it will throw an error.
*
* If you wish to restart the Tween from a specific point, use the `Tween.seek` method instead.
*
* @method Phaser.Tweens.Tween#restart
* @since 3.0.0
*
* @return {this} This Tween instance.
*/
restart: function() {
switch (this.state) {
case TWEEN_CONST.REMOVED:
case TWEEN_CONST.FINISHED:
this.seek();
this.parent.makeActive(this);
break;
case TWEEN_CONST.PENDING:
case TWEEN_CONST.PENDING_REMOVE:
this.parent.reset(this);
break;
case TWEEN_CONST.DESTROYED:
console.warn("Cannot restart destroyed Tween", this);
break;
default:
this.seek();
break;
}
this.paused = false;
this.hasStarted = false;
return this;
},
/**
* Internal method that advances to the next state of the Tween during playback.
*
* @method Phaser.Tweens.Tween#nextState
* @fires Phaser.Tweens.Events#TWEEN_COMPLETE
* @fires Phaser.Tweens.Events#TWEEN_LOOP
* @since 3.0.0
*
* @return {boolean} `true` if this Tween has completed, otherwise `false`.
*/
nextState: function() {
if (this.loopCounter > 0) {
this.elapsed = 0;
this.progress = 0;
this.loopCounter--;
this.initTweenData(true);
if (this.loopDelay > 0) {
this.countdown = this.loopDelay;
this.setLoopDelayState();
} else {
this.setActiveState();
this.dispatchEvent(Events.TWEEN_LOOP, "onLoop");
}
} else if (this.completeDelay > 0) {
this.countdown = this.completeDelay;
this.setCompleteDelayState();
} else {
this.onCompleteHandler();
return true;
}
return false;
},
/**
* Internal method that handles this tween completing and starting
* the next tween in the chain, if any.
*
* @method Phaser.Tweens.Tween#onCompleteHandler
* @since 3.60.0
*/
onCompleteHandler: function() {
this.progress = 1;
this.totalProgress = 1;
BaseTween.prototype.onCompleteHandler.call(this);
},
/**
* Starts a Tween playing.
*
* You only need to call this method if you have configured the tween to be paused on creation.
*
* If the Tween is already playing, calling this method again will have no effect. If you wish to
* restart the Tween, use `Tween.restart` instead.
*
* Calling this method after the Tween has completed will start the Tween playing again from the beginning.
* This is the same as calling `Tween.seek(0)` and then `Tween.play()`.
*
* @method Phaser.Tweens.Tween#play
* @since 3.0.0
*
* @return {this} This Tween instance.
*/
play: function() {
if (this.isDestroyed()) {
console.warn("Cannot play destroyed Tween", this);
return this;
}
if (this.isPendingRemove() || this.isFinished()) {
this.seek();
}
this.paused = false;
this.setActiveState();
return this;
},
/**
* Seeks to a specific point in the Tween.
*
* The given amount is a value in milliseconds that represents how far into the Tween
* you wish to seek, based on the start of the Tween.
*
* Note that the seek amount takes the entire duration of the Tween into account, including delays, loops and repeats.
* For example, a Tween that lasts for 2 seconds, but that loops 3 times, would have a total duration of 6 seconds,
* so seeking to 3000 ms would seek to the Tweens half-way point based on its _entire_ duration.
*
* Prior to Phaser 3.60 this value was given as a number between 0 and 1 and didn't
* work for Tweens had an infinite repeat. This new method works for all Tweens.
*
* Seeking works by resetting the Tween to its initial values and then iterating through the Tween at `delta`
* jumps per step. The longer the Tween, the longer this can take. If you need more precision you can
* reduce the delta value. If you need a faster seek, you can increase it. When the Tween is
* reset it will refresh the starting and ending values. If these are coming from a dynamic function,
* or a random array, it will be called for each seek.
*
* While seeking the Tween will _not_ emit any of its events or callbacks unless
* the 3rd parameter is set to `true`.
*
* If this Tween is paused, seeking will not change this fact. It will advance the Tween
* to the desired point and then pause it again.
*
* @method Phaser.Tweens.Tween#seek
* @since 3.0.0
*
* @param {number} [amount=0] - The number of milliseconds to seek into the Tween from the beginning.
* @param {number} [delta=16.6] - The size of each step when seeking through the Tween. A higher value completes faster but at the cost of less precision.
* @param {boolean} [emit=false] - While seeking, should the Tween emit any of its events or callbacks? The default is 'false', i.e. to seek silently.
*
* @return {this} This Tween instance.
*/
seek: function(amount, delta, emit) {
if (amount === void 0) {
amount = 0;
}
if (delta === void 0) {
delta = 16.6;
}
if (emit === void 0) {
emit = false;
}
if (this.isDestroyed()) {
console.warn("Cannot seek destroyed Tween", this);
return this;
}
if (!emit) {
this.isSeeking = true;
}
this.reset(true);
this.initTweenData(true);
this.setActiveState();
this.dispatchEvent(Events.TWEEN_ACTIVE, "onActive");
var isPaused = this.paused;
this.paused = false;
if (amount > 0) {
var iterations = Math.floor(amount / delta);
var remainder = amount - iterations * delta;
for (var i = 0; i < iterations; i++) {
this.update(delta);
}
if (remainder > 0) {
this.update(remainder);
}
}
this.paused = isPaused;
this.isSeeking = false;
return this;
},
/**
* Initialises all of the Tween Data and Tween values.
*
* This is called automatically and should not typically be invoked directly.
*
* @method Phaser.Tweens.Tween#initTweenData
* @since 3.60.0
*
* @param {boolean} [isSeeking=false] - Is the Tween Data being reset as part of a seek?
*/
initTweenData: function(isSeeking) {
if (isSeeking === void 0) {
isSeeking = false;
}
this.duration = 0;
this.startDelay = MATH_CONST.MAX_SAFE_INTEGER;
var data = this.data;
for (var i = 0; i < this.totalData; i++) {
data[i].reset(isSeeking);
}
this.duration = Math.max(this.duration, 0.01);
var duration = this.duration;
var completeDelay = this.completeDelay;
var loopCounter = this.loopCounter;
var loopDelay = this.loopDelay;
if (loopCounter > 0) {
this.totalDuration = duration + completeDelay + (duration + loopDelay) * loopCounter;
} else {
this.totalDuration = duration + completeDelay;
}
},
/**
* Resets this Tween ready for another play-through.
*
* This is called automatically from the Tween Manager, or from the parent TweenChain,
* and should not typically be invoked directly.
*
* If you wish to restart this Tween, use the `Tween.restart` or `Tween.seek` methods instead.
*
* @method Phaser.Tweens.Tween#reset
* @fires Phaser.Tweens.Events#TWEEN_ACTIVE
* @since 3.60.0
*
* @param {boolean} [skipInit=false] - Skip resetting the TweenData and Active State?
*
* @return {this} This Tween instance.
*/
reset: function(skipInit) {
if (skipInit === void 0) {
skipInit = false;
}
this.elapsed = 0;
this.totalElapsed = 0;
this.progress = 0;
this.totalProgress = 0;
this.loopCounter = this.loop;
if (this.loop === -1) {
this.isInfinite = true;
this.loopCounter = TWEEN_CONST.MAX;
}
if (!skipInit) {
this.initTweenData();
this.setActiveState();
this.dispatchEvent(Events.TWEEN_ACTIVE, "onActive");
}
return this;
},
/**
* Internal method that advances the Tween based on the time values.
*
* @method Phaser.Tweens.Tween#update
* @fires Phaser.Tweens.Events#TWEEN_COMPLETE
* @fires Phaser.Tweens.Events#TWEEN_LOOP
* @fires Phaser.Tweens.Events#TWEEN_START
* @since 3.0.0
*
* @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
*
* @return {boolean} Returns `true` if this Tween has finished and should be removed from the Tween Manager, otherwise returns `false`.
*/
update: function(delta) {
if (this.isPendingRemove() || this.isDestroyed()) {
return true;
} else if (this.paused || this.isFinished()) {
return false;
}
delta *= this.timeScale * this.parent.timeScale;
if (this.isLoopDelayed()) {
this.updateLoopCountdown(delta);
return false;
} else if (this.isCompleteDelayed()) {
this.updateCompleteDelay(delta);
return false;
} else if (!this.hasStarted) {
this.startDelay -= delta;
if (this.startDelay <= 0) {
this.hasStarted = true;
this.dispatchEvent(Events.TWEEN_START, "onStart");
delta = 0;
}
}
var stillRunning = false;
if (this.isActive()) {
var data = this.data;
for (var i = 0; i < this.totalData; i++) {
if (data[i].update(delta)) {
stillRunning = true;
}
}
}
this.elapsed += delta;
this.progress = Math.min(this.elapsed / this.duration, 1);
this.totalElapsed += delta;
this.totalProgress = Math.min(this.totalElapsed / this.totalDuration, 1);
if (!stillRunning) {
this.nextState();
}
var remove = this.isPendingRemove();
if (remove && this.persist) {
this.setFinishedState();
remove = false;
}
return remove;
},
/**
* Moves this Tween forward by the given amount of milliseconds.
*
* It will only advance through the current loop of the Tween. For example, if the
* Tween is set to repeat or yoyo, it can only fast forward through a single
* section of the sequence. Use `Tween.seek` for more complex playhead control.
*
* If the Tween is paused or has already finished, calling this will have no effect.
*
* @method Phaser.Tweens.Tween#forward
* @since 3.60.0
*
* @param {number} ms - The number of milliseconds to advance this Tween by.
*
* @return {this} This Tween instance.
*/
forward: function(ms) {
this.update(ms);
return this;
},
/**
* Moves this Tween backward by the given amount of milliseconds.
*
* It will only rewind through the current loop of the Tween. For example, if the
* Tween is set to repeat or yoyo, it can only fast forward through a single
* section of the sequence. Use `Tween.seek` for more complex playhead control.
*
* If the Tween is paused or has already finished, calling this will have no effect.
*
* @method Phaser.Tweens.Tween#rewind
* @since 3.60.0
*
* @param {number} ms - The number of milliseconds to rewind this Tween by.
*
* @return {this} This Tween instance.
*/
rewind: function(ms) {
this.update(-ms);
return this;
},
/**
* Internal method that will emit a Tween based Event and invoke the given callback.
*
* @method Phaser.Tweens.Tween#dispatchEvent
* @since 3.60.0
*
* @param {Phaser.Types.Tweens.Event} event - The Event to be dispatched.
* @param {Phaser.Types.Tweens.TweenCallbackTypes} [callback] - The name of the callback to be invoked. Can be `null` or `undefined` to skip invocation.
*/
dispatchEvent: function(event, callback) {
if (!this.isSeeking) {
this.emit(event, this, this.targets);
var handler = this.callbacks[callback];
if (handler) {
handler.func.apply(this.callbackScope, [this, this.targets].concat(handler.params));
}
}
},
/**
* Handles the destroy process of this Tween, clearing out the
* Tween Data and resetting the targets. A Tween that has been
* destroyed cannot ever be played or used again.
*
* @method Phaser.Tweens.Tween#destroy
* @since 3.60.0
*/
destroy: function() {
BaseTween.prototype.destroy.call(this);
this.targets = null;
}
});
GameObjectFactory.register("tween", function(config) {
return this.scene.sys.tweens.add(config);
});
GameObjectCreator.register("tween", function(config) {
return this.scene.sys.tweens.create(config);
});
module2.exports = Tween;
}
),
/***/
43960: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var ArrayRemove = __webpack_require__2(72905);
var BaseTween = __webpack_require__2(70402);
var Class = __webpack_require__2(83419);
var Events = __webpack_require__2(842);
var GameObjectCreator = __webpack_require__2(44603);
var GameObjectFactory = __webpack_require__2(39429);
var TWEEN_CONST = __webpack_require__2(86353);
var TweenChain = new Class({
Extends: BaseTween,
initialize: function TweenChain2(parent) {
BaseTween.call(this, parent);
this.currentTween = null;
this.currentIndex = 0;
},
/**
* Prepares this TweenChain for playback.
*
* Called automatically by the TweenManager. Should not be called directly.
*
* @method Phaser.Tweens.TweenChain#init
* @fires Phaser.Tweens.Events#TWEEN_ACTIVE
* @since 3.60.0
*
* @return {this} This TweenChain instance.
*/
init: function() {
this.loopCounter = this.loop === -1 ? TWEEN_CONST.MAX : this.loop;
this.setCurrentTween(0);
if (this.startDelay > 0 && !this.isStartDelayed()) {
this.setStartDelayState();
} else {
this.setActiveState();
}
return this;
},
/**
* Create a sequence of Tweens, chained to one-another, and add them to this Tween Manager.
*
* The tweens are played in order, from start to finish. You can optionally set the chain
* to repeat as many times as you like. Once the chain has finished playing, or repeating if set,
* all tweens in the chain will be destroyed automatically. To override this, set the 'persist'
* argument to 'true'.
*
* Playback will start immediately unless the _first_ Tween has been configured to be paused.
*
* Please note that Tweens will not manipulate any target property that begins with an underscore.
*
* @method Phaser.Tweens.TweenChain#add
* @since 3.60.0
*
* @param {Phaser.Types.Tweens.TweenBuilderConfig[]|object[]} tweens - An array of Tween configuration objects for the Tweens in this chain.
*
* @return {this} This TweenChain instance.
*/
add: function(tweens) {
var newTweens = this.parent.create(tweens);
if (!Array.isArray(newTweens)) {
newTweens = [newTweens];
}
var data = this.data;
for (var i = 0; i < newTweens.length; i++) {
var tween = newTweens[i];
tween.parent = this;
data.push(tween.reset());
}
this.totalData = data.length;
return this;
},
/**
* Removes the given Tween from this Tween Chain.
*
* The removed tween is _not_ destroyed. It is just removed from this Tween Chain.
*
* If the given Tween is currently playing then the chain will automatically move
* to the next tween in the chain. If there are no more tweens, this chain will complete.
*
* @method Phaser.Tweens.TweenChain#remove
* @since 3.60.0
* @override
*
* @param {Phaser.Tweens.Tween} tween - The Tween to be removed.
*
* @return {this} This Tween Chain instance.
*/
remove: function(tween) {
ArrayRemove(this.data, tween);
tween.setRemovedState();
if (tween === this.currentTween) {
this.nextTween();
}
this.totalData = this.data.length;
return this;
},
/**
* See if any of the tweens in this Tween Chain is currently acting upon the given target.
*
* @method Phaser.Tweens.TweenChain#hasTarget
* @since 3.60.0
*
* @param {object} target - The target to check against this TweenChain.
*
* @return {boolean} `true` if the given target is a target of this TweenChain, otherwise `false`.
*/
hasTarget: function(target) {
var data = this.data;
for (var i = 0; i < this.totalData; i++) {
if (data[i].hasTarget(target)) {
return true;
}
}
return false;
},
/**
* Restarts the TweenChain from the beginning.
*
* If this TweenChain was configured to have a loop, or start delay, those
* are reset to their initial values as well. It will also dispatch the
* `onActive` callback and event again.
*
* @method Phaser.Tweens.TweenChain#restart
* @since 3.60.0
*
* @return {this} This TweenChain instance.
*/
restart: function() {
if (this.isDestroyed()) {
console.warn("Cannot restart destroyed TweenChain", this);
return this;
}
if (this.isRemoved()) {
this.parent.makeActive(this);
}
this.resetTweens();
this.paused = false;
return this.init();
},
/**
* Resets the given Tween.
*
* It will seek to position 0 and playback will start on the next frame.
*
* @method Phaser.Tweens.TweenChain#reset
* @since 3.60.0
*
* @param {Phaser.Tweens.Tween} tween - The Tween to be reset.
*
* @return {this} This TweenChain instance.
*/
reset: function(tween) {
tween.seek();
tween.setActiveState();
return this;
},
/**
* Re-initialises the given Tween and sets it to the Active state.
*
* @method Phaser.Tweens.TweenChain#makeActive
* @since 3.60.0
* @override
*
* @param {Phaser.Tweens.Tween} tween - The Tween to check.
*
* @return {this} This TweenChain instance.
*/
makeActive: function(tween) {
tween.reset();
tween.setActiveState();
return this;
},
/**
* Internal method that advances to the next state of the TweenChain playback.
*
* @method Phaser.Tweens.TweenChain#nextState
* @fires Phaser.Tweens.Events#TWEEN_COMPLETE
* @fires Phaser.Tweens.Events#TWEEN_LOOP
* @since 3.60.0
*
* @return {boolean} `true` if this TweenChain has completed, otherwise `false`.
*/
nextState: function() {
if (this.loopCounter > 0) {
this.loopCounter--;
this.resetTweens();
if (this.loopDelay > 0) {
this.countdown = this.loopDelay;
this.setLoopDelayState();
} else {
this.setActiveState();
this.dispatchEvent(Events.TWEEN_LOOP, "onLoop");
}
} else if (this.completeDelay > 0) {
this.countdown = this.completeDelay;
this.setCompleteDelayState();
} else {
this.onCompleteHandler();
return true;
}
return false;
},
/**
* Starts this TweenChain playing.
*
* You only need to call this method if you have configured this TweenChain to be paused on creation.
*
* If the TweenChain is already playing, calling this method again will have no effect. If you wish to
* restart the chain, use `TweenChain.restart` instead.
*
* Calling this method after the TweenChain has completed will start the chain playing again from the beginning.
*
* @method Phaser.Tweens.TweenChain#play
* @since 3.60.0
*
* @return {this} This TweenChain instance.
*/
play: function() {
if (this.isDestroyed()) {
console.warn("Cannot play destroyed TweenChain", this);
return this;
}
if (this.isPendingRemove() || this.isPending()) {
this.resetTweens();
}
this.paused = false;
if (this.startDelay > 0 && !this.isStartDelayed()) {
this.setStartDelayState();
} else {
this.setActiveState();
}
return this;
},
/**
* Internal method that resets all of the Tweens and the current index pointer.
*
* @method Phaser.Tweens.TweenChain#resetTweens
* @since 3.60.0
*/
resetTweens: function() {
var data = this.data;
var total = this.totalData;
for (var i = 0; i < total; i++) {
data[i].reset(false);
}
this.setCurrentTween(0);
},
/**
* Internal method that advances the TweenChain based on the time values.
*
* @method Phaser.Tweens.TweenChain#update
* @fires Phaser.Tweens.Events#TWEEN_COMPLETE
* @fires Phaser.Tweens.Events#TWEEN_LOOP
* @fires Phaser.Tweens.Events#TWEEN_START
* @since 3.60.0
*
* @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
*
* @return {boolean} Returns `true` if this TweenChain has finished and should be removed from the Tween Manager, otherwise returns `false`.
*/
update: function(delta) {
if (this.isPendingRemove() || this.isDestroyed()) {
return true;
} else if (this.isFinished() || this.paused) {
return false;
}
delta *= this.parent.timeScale;
if (this.isLoopDelayed()) {
this.updateLoopCountdown(delta);
} else if (this.isCompleteDelayed()) {
this.updateCompleteDelay(delta);
} else if (this.isStartDelayed()) {
delta = this.updateStartCountdown(delta);
}
var remove = false;
if (this.isActive() && this.currentTween) {
if (this.currentTween.update(delta)) {
if (this.nextTween()) {
this.nextState();
}
}
remove = this.isPendingRemove();
if (remove && this.persist) {
this.setFinishedState();
remove = false;
}
}
return remove;
},
/**
* Immediately advances to the next Tween in the chain.
*
* This is typically called internally, but can be used if you need to
* advance playback for some reason.
*
* @method Phaser.Tweens.TweenChain#nextTween
* @since 3.60.0
*
* @return {boolean} `true` if there are no more Tweens in the chain, otherwise `false`.
*/
nextTween: function() {
this.currentIndex++;
if (this.currentIndex === this.totalData) {
return true;
} else {
this.setCurrentTween(this.currentIndex);
}
return false;
},
/**
* Sets the current active Tween to the given index, based on its
* entry in the TweenChain data array.
*
* @method Phaser.Tweens.TweenChain#setCurrentTween
* @since 3.60.0
*
* @param {number} index - The index of the Tween to be made current.
*/
setCurrentTween: function(index) {
this.currentIndex = index;
this.currentTween = this.data[index];
this.currentTween.setActiveState();
},
/**
* Internal method that will emit a TweenChain based Event and invoke the given callback.
*
* @method Phaser.Tweens.TweenChain#dispatchEvent
* @since 3.60.0
*
* @param {Phaser.Types.Tweens.Event} event - The Event to be dispatched.
* @param {Phaser.Types.Tweens.TweenCallbackTypes} [callback] - The name of the callback to be invoked. Can be `null` or `undefined` to skip invocation.
*/
dispatchEvent: function(event, callback) {
this.emit(event, this);
var handler = this.callbacks[callback];
if (handler) {
handler.func.apply(this.callbackScope, [this].concat(handler.params));
}
},
/**
* Immediately destroys this TweenChain, nulling of all its references.
*
* @method Phaser.Tweens.TweenChain#destroy
* @since 3.60.0
*/
destroy: function() {
BaseTween.prototype.destroy.call(this);
this.currentTween = null;
}
});
GameObjectFactory.register("tweenchain", function(config) {
return this.scene.sys.tweens.chain(config);
});
GameObjectCreator.register("tweenchain", function(config) {
return this.scene.sys.tweens.create(config);
});
module2.exports = TweenChain;
}
),
/***/
48177: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BaseTweenData = __webpack_require__2(95042);
var Clamp = __webpack_require__2(45319);
var Class = __webpack_require__2(83419);
var Events = __webpack_require__2(842);
var TweenData = new Class({
Extends: BaseTweenData,
initialize: function TweenData2(tween, targetIndex, key, getEnd, getStart, getActive, ease, delay, duration, yoyo, hold, repeat, repeatDelay, flipX, flipY, interpolation, interpolationData) {
BaseTweenData.call(this, tween, targetIndex, delay, duration, yoyo, hold, repeat, repeatDelay, flipX, flipY);
this.key = key;
this.getActiveValue = getActive;
this.getEndValue = getEnd;
this.getStartValue = getStart;
this.ease = ease;
this.start = 0;
this.previous = 0;
this.current = 0;
this.end = 0;
this.interpolation = interpolation;
this.interpolationData = interpolationData;
},
/**
* Internal method that resets this Tween Data entirely, including the progress and elapsed values.
*
* Called automatically by the parent Tween. Should not be called directly.
*
* @method Phaser.Tweens.TweenData#reset
* @since 3.60.0
*
* @param {boolean} [isSeeking=false] - Is the Tween Data being reset as part of a Tween seek?
*/
reset: function(isSeeking) {
BaseTweenData.prototype.reset.call(this);
var target = this.tween.targets[this.targetIndex];
var key = this.key;
if (isSeeking) {
target[key] = this.start;
}
this.start = 0;
this.previous = 0;
this.current = 0;
this.end = 0;
if (this.getActiveValue) {
target[key] = this.getActiveValue(target, key, 0);
}
},
/**
* Internal method that advances this TweenData based on the delta value given.
*
* @method Phaser.Tweens.TweenData#update
* @fires Phaser.Tweens.Events#TWEEN_UPDATE
* @fires Phaser.Tweens.Events#TWEEN_REPEAT
* @since 3.60.0
*
* @param {number} delta - The elapsed delta time in ms.
*
* @return {boolean} `true` if this TweenData is still playing, or `false` if it has finished entirely.
*/
update: function(delta) {
var tween = this.tween;
var totalTargets = tween.totalTargets;
var targetIndex = this.targetIndex;
var target = tween.targets[targetIndex];
var key = this.key;
if (!target) {
this.setCompleteState();
return false;
}
if (this.isCountdown) {
this.elapsed -= delta;
if (this.elapsed <= 0) {
this.elapsed = 0;
delta = 0;
if (this.isDelayed()) {
this.setPendingRenderState();
} else if (this.isRepeating()) {
this.setPlayingForwardState();
this.dispatchEvent(Events.TWEEN_REPEAT, "onRepeat");
} else if (this.isHolding()) {
this.setStateFromEnd(0);
}
}
}
if (this.isPendingRender()) {
this.start = this.getStartValue(target, key, target[key], targetIndex, totalTargets, tween);
this.end = this.getEndValue(target, key, this.start, targetIndex, totalTargets, tween);
this.current = this.start;
target[key] = this.start;
this.setPlayingForwardState();
return true;
}
var forward = this.isPlayingForward();
var backward = this.isPlayingBackward();
if (forward || backward) {
var elapsed = this.elapsed;
var duration = this.duration;
var diff = 0;
var complete = false;
elapsed += delta;
if (elapsed >= duration) {
diff = elapsed - duration;
elapsed = duration;
complete = true;
} else if (elapsed < 0) {
elapsed = 0;
}
var progress = Clamp(elapsed / duration, 0, 1);
this.elapsed = elapsed;
this.progress = progress;
this.previous = this.current;
if (complete) {
if (forward) {
this.current = this.end;
target[key] = this.end;
if (this.hold > 0) {
this.elapsed = this.hold;
this.setHoldState();
} else {
this.setStateFromEnd(diff);
}
} else {
this.current = this.start;
target[key] = this.start;
this.setStateFromStart(diff);
}
} else {
if (!forward) {
progress = 1 - progress;
}
var v = this.ease(progress);
if (this.interpolation) {
this.current = this.interpolation(this.interpolationData, v);
} else {
this.current = this.start + (this.end - this.start) * v;
}
target[key] = this.current;
}
this.dispatchEvent(Events.TWEEN_UPDATE, "onUpdate");
}
return !this.isComplete();
},
/**
* Internal method that will emit a TweenData based Event on the
* parent Tween and also invoke the given callback, if provided.
*
* @method Phaser.Tweens.TweenData#dispatchEvent
* @since 3.60.0
*
* @param {Phaser.Types.Tweens.Event} event - The Event to be dispatched.
* @param {Phaser.Types.Tweens.TweenCallbackTypes} [callback] - The name of the callback to be invoked. Can be `null` or `undefined` to skip invocation.
*/
dispatchEvent: function(event, callback) {
var tween = this.tween;
if (!tween.isSeeking) {
var target = tween.targets[this.targetIndex];
var key = this.key;
var current = this.current;
var previous = this.previous;
tween.emit(event, tween, key, target, current, previous);
var handler = tween.callbacks[callback];
if (handler) {
handler.func.apply(tween.callbackScope, [tween, target, key, current, previous].concat(handler.params));
}
}
},
/**
* Immediately destroys this TweenData, nulling of all its references.
*
* @method Phaser.Tweens.TweenData#destroy
* @since 3.60.0
*/
destroy: function() {
BaseTweenData.prototype.destroy.call(this);
this.getActiveValue = null;
this.getEndValue = null;
this.getStartValue = null;
this.ease = null;
}
});
module2.exports = TweenData;
}
),
/***/
42220: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var BaseTweenData = __webpack_require__2(95042);
var Clamp = __webpack_require__2(45319);
var Class = __webpack_require__2(83419);
var Events = __webpack_require__2(842);
var TweenFrameData = new Class({
Extends: BaseTweenData,
initialize: function TweenFrameData2(tween, targetIndex, texture, frame, delay, duration, hold, repeat, repeatDelay, flipX, flipY) {
BaseTweenData.call(this, tween, targetIndex, delay, duration, false, hold, repeat, repeatDelay, flipX, flipY);
this.key = "texture";
this.startTexture = null;
this.endTexture = texture;
this.startFrame = null;
this.endFrame = frame;
this.yoyo = repeat !== 0 ? true : false;
},
/**
* Internal method that resets this Tween Data entirely, including the progress and elapsed values.
*
* Called automatically by the parent Tween. Should not be called directly.
*
* @method Phaser.Tweens.TweenFrameData#reset
* @since 3.60.0
*
* @param {boolean} [isSeeking=false] - Is the Tween Data being reset as part of a Tween seek?
*/
reset: function(isSeeking) {
BaseTweenData.prototype.reset.call(this);
var target = this.tween.targets[this.targetIndex];
if (!this.startTexture) {
this.startTexture = target.texture.key;
this.startFrame = target.frame.name;
}
if (isSeeking) {
target.setTexture(this.startTexture, this.startFrame);
}
},
/**
* Internal method that advances this TweenData based on the delta value given.
*
* @method Phaser.Tweens.TweenFrameData#update
* @fires Phaser.Tweens.Events#TWEEN_UPDATE
* @fires Phaser.Tweens.Events#TWEEN_REPEAT
* @since 3.60.0
*
* @param {number} delta - The elapsed delta time in ms.
*
* @return {boolean} `true` if this TweenData is still playing, or `false` if it has finished entirely.
*/
update: function(delta) {
var tween = this.tween;
var targetIndex = this.targetIndex;
var target = tween.targets[targetIndex];
if (!target) {
this.setCompleteState();
return false;
}
if (this.isCountdown) {
this.elapsed -= delta;
if (this.elapsed <= 0) {
this.elapsed = 0;
delta = 0;
if (this.isDelayed()) {
this.setPendingRenderState();
} else if (this.isRepeating()) {
this.setPlayingForwardState();
this.dispatchEvent(Events.TWEEN_REPEAT, "onRepeat");
} else if (this.isHolding()) {
this.setStateFromEnd(0);
}
}
}
if (this.isPendingRender()) {
if (this.startTexture) {
target.setTexture(this.startTexture, this.startFrame);
}
this.setPlayingForwardState();
return true;
}
var forward = this.isPlayingForward();
var backward = this.isPlayingBackward();
if (forward || backward) {
var elapsed = this.elapsed;
var duration = this.duration;
var diff = 0;
var complete = false;
elapsed += delta;
if (elapsed >= duration) {
diff = elapsed - duration;
elapsed = duration;
complete = true;
} else if (elapsed < 0) {
elapsed = 0;
}
var progress = Clamp(elapsed / duration, 0, 1);
this.elapsed = elapsed;
this.progress = progress;
if (complete) {
if (forward) {
target.setTexture(this.endTexture, this.endFrame);
if (this.hold > 0) {
this.elapsed = this.hold;
this.setHoldState();
} else {
this.setStateFromEnd(diff);
}
} else {
target.setTexture(this.startTexture, this.startFrame);
this.setStateFromStart(diff);
}
}
this.dispatchEvent(Events.TWEEN_UPDATE, "onUpdate");
}
return !this.isComplete();
},
/**
* Internal method that will emit a TweenData based Event on the
* parent Tween and also invoke the given callback, if provided.
*
* @method Phaser.Tweens.TweenFrameData#dispatchEvent
* @since 3.60.0
*
* @param {Phaser.Types.Tweens.Event} event - The Event to be dispatched.
* @param {Phaser.Types.Tweens.TweenCallbackTypes} [callback] - The name of the callback to be invoked. Can be `null` or `undefined` to skip invocation.
*/
dispatchEvent: function(event, callback) {
var tween = this.tween;
if (!tween.isSeeking) {
var target = tween.targets[this.targetIndex];
var key = this.key;
tween.emit(event, tween, key, target);
var handler = tween.callbacks[callback];
if (handler) {
handler.func.apply(tween.callbackScope, [tween, target, key].concat(handler.params));
}
}
},
/**
* Immediately destroys this TweenData, nulling of all its references.
*
* @method Phaser.Tweens.TweenFrameData#destroy
* @since 3.60.0
*/
destroy: function() {
BaseTweenData.prototype.destroy.call(this);
this.startTexture = null;
this.endTexture = null;
this.startFrame = null;
this.endFrame = null;
}
});
module2.exports = TweenFrameData;
}
),
/***/
86353: (
/***/
(module2) => {
var TWEEN_CONST = {
/**
* TweenData state.
*
* @name Phaser.Tweens.States.CREATED
* @type {number}
* @const
* @since 3.0.0
*/
CREATED: 0,
// 1 used to be INIT prior to 3.60
/**
* TweenData state.
*
* @name Phaser.Tweens.States.DELAY
* @type {number}
* @const
* @since 3.0.0
*/
DELAY: 2,
// 3 used to be OFFSET_DELAY prior to 3.60
/**
* TweenData state.
*
* @name Phaser.Tweens.States.PENDING_RENDER
* @type {number}
* @const
* @since 3.0.0
*/
PENDING_RENDER: 4,
/**
* TweenData state.
*
* @name Phaser.Tweens.States.PLAYING_FORWARD
* @type {number}
* @const
* @since 3.0.0
*/
PLAYING_FORWARD: 5,
/**
* TweenData state.
*
* @name Phaser.Tweens.States.PLAYING_BACKWARD
* @type {number}
* @const
* @since 3.0.0
*/
PLAYING_BACKWARD: 6,
/**
* TweenData state.
*
* @name Phaser.Tweens.States.HOLD_DELAY
* @type {number}
* @const
* @since 3.0.0
*/
HOLD_DELAY: 7,
/**
* TweenData state.
*
* @name Phaser.Tweens.States.REPEAT_DELAY
* @type {number}
* @const
* @since 3.0.0
*/
REPEAT_DELAY: 8,
/**
* TweenData state.
*
* @name Phaser.Tweens.States.COMPLETE
* @type {number}
* @const
* @since 3.0.0
*/
COMPLETE: 9,
// Tween specific (starts from 20 to cleanly allow extra TweenData consts in the future)
/**
* Tween state. The Tween has been created but has not yet been added to the Tween Manager.
*
* @name Phaser.Tweens.States.PENDING
* @type {number}
* @const
* @since 3.0.0
*/
PENDING: 20,
/**
* Tween state. The Tween is active within the Tween Manager. This means it is either playing,
* or was playing and is currently paused, but in both cases it's still being processed by
* the Tween Manager, so is considered 'active'.
*
* @name Phaser.Tweens.States.ACTIVE
* @type {number}
* @const
* @since 3.0.0
*/
ACTIVE: 21,
/**
* Tween state. The Tween is waiting for a loop countdown to elapse.
*
* @name Phaser.Tweens.States.LOOP_DELAY
* @type {number}
* @const
* @since 3.0.0
*/
LOOP_DELAY: 22,
/**
* Tween state. The Tween is waiting for a complete delay to elapse.
*
* @name Phaser.Tweens.States.COMPLETE_DELAY
* @type {number}
* @const
* @since 3.0.0
*/
COMPLETE_DELAY: 23,
/**
* Tween state. The Tween is waiting for a starting delay to elapse.
*
* @name Phaser.Tweens.States.START_DELAY
* @type {number}
* @const
* @since 3.0.0
*/
START_DELAY: 24,
/**
* Tween state. The Tween has finished playback and is waiting to be removed from the Tween Manager.
*
* @name Phaser.Tweens.States.PENDING_REMOVE
* @type {number}
* @const
* @since 3.0.0
*/
PENDING_REMOVE: 25,
/**
* Tween state. The Tween has been removed from the Tween Manager.
*
* @name Phaser.Tweens.States.REMOVED
* @type {number}
* @const
* @since 3.0.0
*/
REMOVED: 26,
/**
* Tween state. The Tween has finished playback but was flagged as 'persistent' during creation,
* so will not be automatically removed by the Tween Manager.
*
* @name Phaser.Tweens.States.FINISHED
* @type {number}
* @const
* @since 3.60.0
*/
FINISHED: 27,
/**
* Tween state. The Tween has been destroyed and can no longer be played by a Tween Manager.
*
* @name Phaser.Tweens.States.DESTROYED
* @type {number}
* @const
* @since 3.60.0
*/
DESTROYED: 28,
/**
* A large integer value used for 'infinite' style countdowns.
*
* Similar use-case to Number.MAX_SAFE_INTEGER but we cannot use that because it's not
* supported on IE.
*
* @name Phaser.Tweens.States.MAX
* @type {number}
* @const
* @since 3.60.0
*/
MAX: 999999999999
};
module2.exports = TWEEN_CONST;
}
),
/***/
83419: (
/***/
(module2) => {
function hasGetterOrSetter(def) {
return !!def.get && typeof def.get === "function" || !!def.set && typeof def.set === "function";
}
function getProperty(definition, k, isClassDescriptor) {
var def = isClassDescriptor ? definition[k] : Object.getOwnPropertyDescriptor(definition, k);
if (!isClassDescriptor && def.value && typeof def.value === "object") {
def = def.value;
}
if (def && hasGetterOrSetter(def)) {
if (typeof def.enumerable === "undefined") {
def.enumerable = true;
}
if (typeof def.configurable === "undefined") {
def.configurable = true;
}
return def;
} else {
return false;
}
}
function hasNonConfigurable(obj, k) {
var prop = Object.getOwnPropertyDescriptor(obj, k);
if (!prop) {
return false;
}
if (prop.value && typeof prop.value === "object") {
prop = prop.value;
}
if (prop.configurable === false) {
return true;
}
return false;
}
function extend(ctor, definition, isClassDescriptor, extend2) {
for (var k in definition) {
if (!definition.hasOwnProperty(k)) {
continue;
}
var def = getProperty(definition, k, isClassDescriptor);
if (def !== false) {
var parent = extend2 || ctor;
if (hasNonConfigurable(parent.prototype, k)) {
if (Class.ignoreFinals) {
continue;
}
throw new Error("cannot override final property '" + k + "', set Class.ignoreFinals = true to skip");
}
Object.defineProperty(ctor.prototype, k, def);
} else {
ctor.prototype[k] = definition[k];
}
}
}
function mixin(myClass, mixins) {
if (!mixins) {
return;
}
if (!Array.isArray(mixins)) {
mixins = [mixins];
}
for (var i = 0; i < mixins.length; i++) {
extend(myClass, mixins[i].prototype || mixins[i]);
}
}
function Class(definition) {
if (!definition) {
definition = {};
}
var initialize;
var Extends;
if (definition.initialize) {
if (typeof definition.initialize !== "function") {
throw new Error("initialize must be a function");
}
initialize = definition.initialize;
delete definition.initialize;
} else if (definition.Extends) {
var base = definition.Extends;
initialize = function() {
base.apply(this, arguments);
};
} else {
initialize = function() {
};
}
if (definition.Extends) {
initialize.prototype = Object.create(definition.Extends.prototype);
initialize.prototype.constructor = initialize;
Extends = definition.Extends;
delete definition.Extends;
} else {
initialize.prototype.constructor = initialize;
}
var mixins = null;
if (definition.Mixins) {
mixins = definition.Mixins;
delete definition.Mixins;
}
mixin(initialize, mixins);
extend(initialize, definition, true, Extends);
return initialize;
}
Class.extend = extend;
Class.mixin = mixin;
Class.ignoreFinals = false;
module2.exports = Class;
}
),
/***/
29747: (
/***/
(module2) => {
var NOOP = function() {
};
module2.exports = NOOP;
}
),
/***/
20242: (
/***/
(module2) => {
var NULL = function() {
return null;
};
module2.exports = NULL;
}
),
/***/
71146: (
/***/
(module2) => {
var Add = function(array, item, limit, callback, context) {
if (context === void 0) {
context = array;
}
if (limit > 0) {
var remaining = limit - array.length;
if (remaining <= 0) {
return null;
}
}
if (!Array.isArray(item)) {
if (array.indexOf(item) === -1) {
array.push(item);
if (callback) {
callback.call(context, item);
}
return item;
} else {
return null;
}
}
var itemLength = item.length - 1;
while (itemLength >= 0) {
if (array.indexOf(item[itemLength]) !== -1) {
item.splice(itemLength, 1);
}
itemLength--;
}
itemLength = item.length;
if (itemLength === 0) {
return null;
}
if (limit > 0 && itemLength > remaining) {
item.splice(remaining);
itemLength = remaining;
}
for (var i = 0; i < itemLength; i++) {
var entry = item[i];
array.push(entry);
if (callback) {
callback.call(context, entry);
}
}
return item;
};
module2.exports = Add;
}
),
/***/
51067: (
/***/
(module2) => {
var AddAt = function(array, item, index, limit, callback, context) {
if (index === void 0) {
index = 0;
}
if (context === void 0) {
context = array;
}
if (limit > 0) {
var remaining = limit - array.length;
if (remaining <= 0) {
return null;
}
}
if (!Array.isArray(item)) {
if (array.indexOf(item) === -1) {
array.splice(index, 0, item);
if (callback) {
callback.call(context, item);
}
return item;
} else {
return null;
}
}
var itemLength = item.length - 1;
while (itemLength >= 0) {
if (array.indexOf(item[itemLength]) !== -1) {
item.pop();
}
itemLength--;
}
itemLength = item.length;
if (itemLength === 0) {
return null;
}
if (limit > 0 && itemLength > remaining) {
item.splice(remaining);
itemLength = remaining;
}
for (var i = itemLength - 1; i >= 0; i--) {
var entry = item[i];
array.splice(index, 0, entry);
if (callback) {
callback.call(context, entry);
}
}
return item;
};
module2.exports = AddAt;
}
),
/***/
66905: (
/***/
(module2) => {
var BringToTop = function(array, item) {
var currentIndex = array.indexOf(item);
if (currentIndex !== -1 && currentIndex < array.length) {
array.splice(currentIndex, 1);
array.push(item);
}
return item;
};
module2.exports = BringToTop;
}
),
/***/
21612: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var SafeRange = __webpack_require__2(82011);
var CountAllMatching = function(array, property, value, startIndex, endIndex) {
if (startIndex === void 0) {
startIndex = 0;
}
if (endIndex === void 0) {
endIndex = array.length;
}
var total = 0;
if (SafeRange(array, startIndex, endIndex)) {
for (var i = startIndex; i < endIndex; i++) {
var child = array[i];
if (child[property] === value) {
total++;
}
}
}
return total;
};
module2.exports = CountAllMatching;
}
),
/***/
95428: (
/***/
(module2) => {
var Each = function(array, callback, context) {
var i;
var args = [null];
for (i = 3; i < arguments.length; i++) {
args.push(arguments[i]);
}
for (i = 0; i < array.length; i++) {
args[0] = array[i];
callback.apply(context, args);
}
return array;
};
module2.exports = Each;
}
),
/***/
36914: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var SafeRange = __webpack_require__2(82011);
var EachInRange = function(array, callback, context, startIndex, endIndex) {
if (startIndex === void 0) {
startIndex = 0;
}
if (endIndex === void 0) {
endIndex = array.length;
}
if (SafeRange(array, startIndex, endIndex)) {
var i;
var args = [null];
for (i = 5; i < arguments.length; i++) {
args.push(arguments[i]);
}
for (i = startIndex; i < endIndex; i++) {
args[0] = array[i];
callback.apply(context, args);
}
}
return array;
};
module2.exports = EachInRange;
}
),
/***/
81957: (
/***/
(module2) => {
var FindClosestInSorted = function(value, array, key) {
if (!array.length) {
return NaN;
} else if (array.length === 1) {
return array[0];
}
var i = 1;
var low;
var high;
if (key) {
if (value < array[0][key]) {
return array[0];
}
while (array[i][key] < value) {
i++;
}
} else {
while (array[i] < value) {
i++;
}
}
if (i > array.length) {
i = array.length;
}
if (key) {
low = array[i - 1][key];
high = array[i][key];
return high - value <= value - low ? array[i] : array[i - 1];
} else {
low = array[i - 1];
high = array[i];
return high - value <= value - low ? high : low;
}
};
module2.exports = FindClosestInSorted;
}
),
/***/
43491: (
/***/
(module2) => {
var Flatten = function(array, output) {
if (output === void 0) {
output = [];
}
for (var i = 0; i < array.length; i++) {
if (Array.isArray(array[i])) {
Flatten(array[i], output);
} else {
output.push(array[i]);
}
}
return output;
};
module2.exports = Flatten;
}
),
/***/
46710: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var SafeRange = __webpack_require__2(82011);
var GetAll = function(array, property, value, startIndex, endIndex) {
if (startIndex === void 0) {
startIndex = 0;
}
if (endIndex === void 0) {
endIndex = array.length;
}
var output = [];
if (SafeRange(array, startIndex, endIndex)) {
for (var i = startIndex; i < endIndex; i++) {
var child = array[i];
if (!property || property && value === void 0 && child.hasOwnProperty(property) || property && value !== void 0 && child[property] === value) {
output.push(child);
}
}
}
return output;
};
module2.exports = GetAll;
}
),
/***/
58731: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var SafeRange = __webpack_require__2(82011);
var GetFirst = function(array, property, value, startIndex, endIndex) {
if (startIndex === void 0) {
startIndex = 0;
}
if (endIndex === void 0) {
endIndex = array.length;
}
if (SafeRange(array, startIndex, endIndex)) {
for (var i = startIndex; i < endIndex; i++) {
var child = array[i];
if (!property || property && value === void 0 && child.hasOwnProperty(property) || property && value !== void 0 && child[property] === value) {
return child;
}
}
}
return null;
};
module2.exports = GetFirst;
}
),
/***/
26546: (
/***/
(module2) => {
var GetRandom = function(array, startIndex, length) {
if (startIndex === void 0) {
startIndex = 0;
}
if (length === void 0) {
length = array.length;
}
var randomIndex = startIndex + Math.floor(Math.random() * length);
return array[randomIndex] === void 0 ? null : array[randomIndex];
};
module2.exports = GetRandom;
}
),
/***/
85835: (
/***/
(module2) => {
var MoveAbove = function(array, item1, item2) {
if (item1 === item2) {
return array;
}
var currentIndex = array.indexOf(item1);
var baseIndex = array.indexOf(item2);
if (currentIndex < 0 || baseIndex < 0) {
throw new Error("Supplied items must be elements of the same array");
}
if (currentIndex > baseIndex) {
return array;
}
array.splice(currentIndex, 1);
baseIndex = array.indexOf(item2);
array.splice(baseIndex + 1, 0, item1);
return array;
};
module2.exports = MoveAbove;
}
),
/***/
83371: (
/***/
(module2) => {
var MoveBelow = function(array, item1, item2) {
if (item1 === item2) {
return array;
}
var currentIndex = array.indexOf(item1);
var baseIndex = array.indexOf(item2);
if (currentIndex < 0 || baseIndex < 0) {
throw new Error("Supplied items must be elements of the same array");
}
if (currentIndex < baseIndex) {
return array;
}
array.splice(currentIndex, 1);
if (baseIndex === 0) {
array.unshift(item1);
} else {
array.splice(baseIndex, 0, item1);
}
return array;
};
module2.exports = MoveBelow;
}
),
/***/
70864: (
/***/
(module2) => {
var MoveDown = function(array, item) {
var currentIndex = array.indexOf(item);
if (currentIndex > 0) {
var item2 = array[currentIndex - 1];
var index2 = array.indexOf(item2);
array[currentIndex] = item2;
array[index2] = item;
}
return array;
};
module2.exports = MoveDown;
}
),
/***/
69693: (
/***/
(module2) => {
var MoveTo = function(array, item, index) {
var currentIndex = array.indexOf(item);
if (currentIndex === -1 || index < 0 || index >= array.length) {
throw new Error("Supplied index out of bounds");
}
if (currentIndex !== index) {
array.splice(currentIndex, 1);
array.splice(index, 0, item);
}
return item;
};
module2.exports = MoveTo;
}
),
/***/
40853: (
/***/
(module2) => {
var MoveUp = function(array, item) {
var currentIndex = array.indexOf(item);
if (currentIndex !== -1 && currentIndex < array.length - 1) {
var item2 = array[currentIndex + 1];
var index2 = array.indexOf(item2);
array[currentIndex] = item2;
array[index2] = item;
}
return array;
};
module2.exports = MoveUp;
}
),
/***/
20283: (
/***/
(module2) => {
var NumberArray = function(start, end, prefix, suffix) {
var result = [];
var i;
var asString = false;
if (prefix || suffix) {
asString = true;
if (!prefix) {
prefix = "";
}
if (!suffix) {
suffix = "";
}
}
if (end < start) {
for (i = start; i >= end; i--) {
if (asString) {
result.push(prefix + i.toString() + suffix);
} else {
result.push(i);
}
}
} else {
for (i = start; i <= end; i++) {
if (asString) {
result.push(prefix + i.toString() + suffix);
} else {
result.push(i);
}
}
}
return result;
};
module2.exports = NumberArray;
}
),
/***/
593: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var RoundAwayFromZero = __webpack_require__2(2284);
var NumberArrayStep = function(start, end, step) {
if (start === void 0) {
start = 0;
}
if (end === void 0) {
end = null;
}
if (step === void 0) {
step = 1;
}
if (end === null) {
end = start;
start = 0;
}
var result = [];
var total = Math.max(RoundAwayFromZero((end - start) / (step || 1)), 0);
for (var i = 0; i < total; i++) {
result.push(start);
start += step;
}
return result;
};
module2.exports = NumberArrayStep;
}
),
/***/
43886: (
/***/
(module2) => {
function swap(arr, i, j) {
var tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
function defaultCompare(a, b) {
return a < b ? -1 : a > b ? 1 : 0;
}
var QuickSelect = function(arr, k, left, right, compare) {
if (left === void 0) {
left = 0;
}
if (right === void 0) {
right = arr.length - 1;
}
if (compare === void 0) {
compare = defaultCompare;
}
while (right > left) {
if (right - left > 600) {
var n = right - left + 1;
var m = k - left + 1;
var z = Math.log(n);
var s = 0.5 * Math.exp(2 * z / 3);
var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);
var newLeft = Math.max(left, Math.floor(k - m * s / n + sd));
var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));
QuickSelect(arr, k, newLeft, newRight, compare);
}
var t = arr[k];
var i = left;
var j = right;
swap(arr, left, k);
if (compare(arr[right], t) > 0) {
swap(arr, left, right);
}
while (i < j) {
swap(arr, i, j);
i++;
j--;
while (compare(arr[i], t) < 0) {
i++;
}
while (compare(arr[j], t) > 0) {
j--;
}
}
if (compare(arr[left], t) === 0) {
swap(arr, left, j);
} else {
j++;
swap(arr, j, right);
}
if (j <= k) {
left = j + 1;
}
if (k <= j) {
right = j - 1;
}
}
};
module2.exports = QuickSelect;
}
),
/***/
88492: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetValue = __webpack_require__2(35154);
var Shuffle = __webpack_require__2(33680);
var BuildChunk = function(a, b, qty) {
var out = [];
for (var aIndex = 0; aIndex < a.length; aIndex++) {
for (var bIndex = 0; bIndex < b.length; bIndex++) {
for (var i = 0; i < qty; i++) {
out.push({ a: a[aIndex], b: b[bIndex] });
}
}
}
return out;
};
var Range = function(a, b, options) {
var max = GetValue(options, "max", 0);
var qty = GetValue(options, "qty", 1);
var random = GetValue(options, "random", false);
var randomB = GetValue(options, "randomB", false);
var repeat = GetValue(options, "repeat", 0);
var yoyo = GetValue(options, "yoyo", false);
var out = [];
if (randomB) {
Shuffle(b);
}
if (repeat === -1) {
if (max === 0) {
repeat = 0;
} else {
var total = a.length * b.length * qty;
if (yoyo) {
total *= 2;
}
repeat = Math.ceil(max / total);
}
}
for (var i = 0; i <= repeat; i++) {
var chunk = BuildChunk(a, b, qty);
if (random) {
Shuffle(chunk);
}
out = out.concat(chunk);
if (yoyo) {
chunk.reverse();
out = out.concat(chunk);
}
}
if (max) {
out.splice(max);
}
return out;
};
module2.exports = Range;
}
),
/***/
72905: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var SpliceOne = __webpack_require__2(19133);
var Remove = function(array, item, callback, context) {
if (context === void 0) {
context = array;
}
var index;
if (!Array.isArray(item)) {
index = array.indexOf(item);
if (index !== -1) {
SpliceOne(array, index);
if (callback) {
callback.call(context, item);
}
return item;
} else {
return null;
}
}
var itemLength = item.length - 1;
var removed = [];
while (itemLength >= 0) {
var entry = item[itemLength];
index = array.indexOf(entry);
if (index !== -1) {
SpliceOne(array, index);
removed.push(entry);
if (callback) {
callback.call(context, entry);
}
}
itemLength--;
}
return removed;
};
module2.exports = Remove;
}
),
/***/
60248: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var SpliceOne = __webpack_require__2(19133);
var RemoveAt = function(array, index, callback, context) {
if (context === void 0) {
context = array;
}
if (index < 0 || index > array.length - 1) {
throw new Error("Index out of bounds");
}
var item = SpliceOne(array, index);
if (callback) {
callback.call(context, item);
}
return item;
};
module2.exports = RemoveAt;
}
),
/***/
81409: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var SafeRange = __webpack_require__2(82011);
var RemoveBetween = function(array, startIndex, endIndex, callback, context) {
if (startIndex === void 0) {
startIndex = 0;
}
if (endIndex === void 0) {
endIndex = array.length;
}
if (context === void 0) {
context = array;
}
if (SafeRange(array, startIndex, endIndex)) {
var size = endIndex - startIndex;
var removed = array.splice(startIndex, size);
if (callback) {
for (var i = 0; i < removed.length; i++) {
var entry = removed[i];
callback.call(context, entry);
}
}
return removed;
} else {
return [];
}
};
module2.exports = RemoveBetween;
}
),
/***/
31856: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var SpliceOne = __webpack_require__2(19133);
var RemoveRandomElement = function(array, start, length) {
if (start === void 0) {
start = 0;
}
if (length === void 0) {
length = array.length;
}
var randomIndex = start + Math.floor(Math.random() * length);
return SpliceOne(array, randomIndex);
};
module2.exports = RemoveRandomElement;
}
),
/***/
42169: (
/***/
(module2) => {
var Replace = function(array, oldChild, newChild) {
var index1 = array.indexOf(oldChild);
var index2 = array.indexOf(newChild);
if (index1 !== -1 && index2 === -1) {
array[index1] = newChild;
return true;
} else {
return false;
}
};
module2.exports = Replace;
}
),
/***/
86003: (
/***/
(module2) => {
var RotateLeft = function(array, total) {
if (total === void 0) {
total = 1;
}
var element = null;
for (var i = 0; i < total; i++) {
element = array.shift();
array.push(element);
}
return element;
};
module2.exports = RotateLeft;
}
),
/***/
49498: (
/***/
(module2) => {
var RotateRight = function(array, total) {
if (total === void 0) {
total = 1;
}
var element = null;
for (var i = 0; i < total; i++) {
element = array.pop();
array.unshift(element);
}
return element;
};
module2.exports = RotateRight;
}
),
/***/
82011: (
/***/
(module2) => {
var SafeRange = function(array, startIndex, endIndex, throwError) {
var len = array.length;
if (startIndex < 0 || startIndex > len || startIndex >= endIndex || endIndex > len) {
if (throwError) {
throw new Error("Range Error: Values outside acceptable range");
}
return false;
} else {
return true;
}
};
module2.exports = SafeRange;
}
),
/***/
89545: (
/***/
(module2) => {
var SendToBack = function(array, item) {
var currentIndex = array.indexOf(item);
if (currentIndex !== -1 && currentIndex > 0) {
array.splice(currentIndex, 1);
array.unshift(item);
}
return item;
};
module2.exports = SendToBack;
}
),
/***/
17810: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var SafeRange = __webpack_require__2(82011);
var SetAll = function(array, property, value, startIndex, endIndex) {
if (startIndex === void 0) {
startIndex = 0;
}
if (endIndex === void 0) {
endIndex = array.length;
}
if (SafeRange(array, startIndex, endIndex)) {
for (var i = startIndex; i < endIndex; i++) {
var entry = array[i];
if (entry.hasOwnProperty(property)) {
entry[property] = value;
}
}
}
return array;
};
module2.exports = SetAll;
}
),
/***/
33680: (
/***/
(module2) => {
var Shuffle = function(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
};
module2.exports = Shuffle;
}
),
/***/
90126: (
/***/
(module2) => {
var SortByDigits = function(array) {
var re = /\D/g;
array.sort(function(a, b) {
return parseInt(a.replace(re, ""), 10) - parseInt(b.replace(re, ""), 10);
});
return array;
};
module2.exports = SortByDigits;
}
),
/***/
19133: (
/***/
(module2) => {
var SpliceOne = function(array, index) {
if (index >= array.length) {
return;
}
var len = array.length - 1;
var item = array[index];
for (var i = index; i < len; i++) {
array[i] = array[i + 1];
}
array.length = len;
return item;
};
module2.exports = SpliceOne;
}
),
/***/
19186: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Device = __webpack_require__2(82264);
function Compare(a, b) {
return String(a).localeCompare(b);
}
function Process(array, compare) {
var len = array.length;
if (len <= 1) {
return array;
}
var buffer = new Array(len);
for (var chk = 1; chk < len; chk *= 2) {
RunPass(array, compare, chk, buffer);
var tmp = array;
array = buffer;
buffer = tmp;
}
return array;
}
function RunPass(arr, comp, chk, result) {
var len = arr.length;
var i = 0;
var dbl = chk * 2;
var l, r, e;
var li, ri;
for (l = 0; l < len; l += dbl) {
r = l + chk;
e = r + chk;
if (r > len) {
r = len;
}
if (e > len) {
e = len;
}
li = l;
ri = r;
while (true) {
if (li < r && ri < e) {
if (comp(arr[li], arr[ri]) <= 0) {
result[i++] = arr[li++];
} else {
result[i++] = arr[ri++];
}
} else if (li < r) {
result[i++] = arr[li++];
} else if (ri < e) {
result[i++] = arr[ri++];
} else {
break;
}
}
}
}
var StableSort = function(array, compare) {
if (compare === void 0) {
compare = Compare;
}
if (!array || array.length < 2) {
return array;
}
if (Device.features.stableSort) {
return array.sort(compare);
}
var result = Process(array, compare);
if (result !== array) {
RunPass(result, null, array.length, array);
}
return array;
};
module2.exports = StableSort;
}
),
/***/
25630: (
/***/
(module2) => {
var Swap = function(array, item1, item2) {
if (item1 === item2) {
return array;
}
var index1 = array.indexOf(item1);
var index2 = array.indexOf(item2);
if (index1 < 0 || index2 < 0) {
throw new Error("Supplied items must be elements of the same array");
}
array[index1] = item2;
array[index2] = item1;
return array;
};
module2.exports = Swap;
}
),
/***/
37105: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Matrix: __webpack_require__2(54915),
Add: __webpack_require__2(71146),
AddAt: __webpack_require__2(51067),
BringToTop: __webpack_require__2(66905),
CountAllMatching: __webpack_require__2(21612),
Each: __webpack_require__2(95428),
EachInRange: __webpack_require__2(36914),
FindClosestInSorted: __webpack_require__2(81957),
Flatten: __webpack_require__2(43491),
GetAll: __webpack_require__2(46710),
GetFirst: __webpack_require__2(58731),
GetRandom: __webpack_require__2(26546),
MoveDown: __webpack_require__2(70864),
MoveTo: __webpack_require__2(69693),
MoveUp: __webpack_require__2(40853),
MoveAbove: __webpack_require__2(85835),
MoveBelow: __webpack_require__2(83371),
NumberArray: __webpack_require__2(20283),
NumberArrayStep: __webpack_require__2(593),
QuickSelect: __webpack_require__2(43886),
Range: __webpack_require__2(88492),
Remove: __webpack_require__2(72905),
RemoveAt: __webpack_require__2(60248),
RemoveBetween: __webpack_require__2(81409),
RemoveRandomElement: __webpack_require__2(31856),
Replace: __webpack_require__2(42169),
RotateLeft: __webpack_require__2(86003),
RotateRight: __webpack_require__2(49498),
SafeRange: __webpack_require__2(82011),
SendToBack: __webpack_require__2(89545),
SetAll: __webpack_require__2(17810),
Shuffle: __webpack_require__2(33680),
SortByDigits: __webpack_require__2(90126),
SpliceOne: __webpack_require__2(19133),
StableSort: __webpack_require__2(19186),
Swap: __webpack_require__2(25630)
};
}
),
/***/
86922: (
/***/
(module2) => {
var CheckMatrix = function(matrix) {
if (!Array.isArray(matrix) || !Array.isArray(matrix[0])) {
return false;
}
var size = matrix[0].length;
for (var i = 1; i < matrix.length; i++) {
if (matrix[i].length !== size) {
return false;
}
}
return true;
};
module2.exports = CheckMatrix;
}
),
/***/
63362: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Pad = __webpack_require__2(41836);
var CheckMatrix = __webpack_require__2(86922);
var MatrixToString = function(matrix) {
var str = "";
if (!CheckMatrix(matrix)) {
return str;
}
for (var r = 0; r < matrix.length; r++) {
for (var c = 0; c < matrix[r].length; c++) {
var cell = matrix[r][c].toString();
if (cell !== "undefined") {
str += Pad(cell, 2);
} else {
str += "?";
}
if (c < matrix[r].length - 1) {
str += " |";
}
}
if (r < matrix.length - 1) {
str += "\n";
for (var i = 0; i < matrix[r].length; i++) {
str += "---";
if (i < matrix[r].length - 1) {
str += "+";
}
}
str += "\n";
}
}
return str;
};
module2.exports = MatrixToString;
}
),
/***/
92598: (
/***/
(module2) => {
var ReverseColumns = function(matrix) {
return matrix.reverse();
};
module2.exports = ReverseColumns;
}
),
/***/
21224: (
/***/
(module2) => {
var ReverseRows = function(matrix) {
for (var i = 0; i < matrix.length; i++) {
matrix[i].reverse();
}
return matrix;
};
module2.exports = ReverseRows;
}
),
/***/
98717: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var RotateMatrix = __webpack_require__2(37829);
var Rotate180 = function(matrix) {
return RotateMatrix(matrix, 180);
};
module2.exports = Rotate180;
}
),
/***/
44657: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var RotateMatrix = __webpack_require__2(37829);
var RotateLeft = function(matrix, amount) {
if (amount === void 0) {
amount = 1;
}
for (var i = 0; i < amount; i++) {
matrix = RotateMatrix(matrix, 90);
}
return matrix;
};
module2.exports = RotateLeft;
}
),
/***/
37829: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var CheckMatrix = __webpack_require__2(86922);
var TransposeMatrix = __webpack_require__2(2429);
var RotateMatrix = function(matrix, direction) {
if (direction === void 0) {
direction = 90;
}
if (!CheckMatrix(matrix)) {
return null;
}
if (typeof direction !== "string") {
direction = (direction % 360 + 360) % 360;
}
if (direction === 90 || direction === -270 || direction === "rotateLeft") {
matrix = TransposeMatrix(matrix);
matrix.reverse();
} else if (direction === -90 || direction === 270 || direction === "rotateRight") {
matrix.reverse();
matrix = TransposeMatrix(matrix);
} else if (Math.abs(direction) === 180 || direction === "rotate180") {
for (var i = 0; i < matrix.length; i++) {
matrix[i].reverse();
}
matrix.reverse();
}
return matrix;
};
module2.exports = RotateMatrix;
}
),
/***/
92632: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var RotateMatrix = __webpack_require__2(37829);
var RotateRight = function(matrix, amount) {
if (amount === void 0) {
amount = 1;
}
for (var i = 0; i < amount; i++) {
matrix = RotateMatrix(matrix, -90);
}
return matrix;
};
module2.exports = RotateRight;
}
),
/***/
69512: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var RotateLeft = __webpack_require__2(86003);
var RotateRight = __webpack_require__2(49498);
var TranslateMatrix = function(matrix, x, y) {
if (x === void 0) {
x = 0;
}
if (y === void 0) {
y = 0;
}
if (y !== 0) {
if (y < 0) {
RotateLeft(matrix, Math.abs(y));
} else {
RotateRight(matrix, y);
}
}
if (x !== 0) {
for (var i = 0; i < matrix.length; i++) {
var row = matrix[i];
if (x < 0) {
RotateLeft(row, Math.abs(x));
} else {
RotateRight(row, x);
}
}
}
return matrix;
};
module2.exports = TranslateMatrix;
}
),
/***/
2429: (
/***/
(module2) => {
var TransposeMatrix = function(array) {
var sourceRowCount = array.length;
var sourceColCount = array[0].length;
var result = new Array(sourceColCount);
for (var i = 0; i < sourceColCount; i++) {
result[i] = new Array(sourceRowCount);
for (var j = sourceRowCount - 1; j > -1; j--) {
result[i][j] = array[j][i];
}
}
return result;
};
module2.exports = TransposeMatrix;
}
),
/***/
54915: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
CheckMatrix: __webpack_require__2(86922),
MatrixToString: __webpack_require__2(63362),
ReverseColumns: __webpack_require__2(92598),
ReverseRows: __webpack_require__2(21224),
Rotate180: __webpack_require__2(98717),
RotateLeft: __webpack_require__2(44657),
RotateMatrix: __webpack_require__2(37829),
RotateRight: __webpack_require__2(92632),
Translate: __webpack_require__2(69512),
TransposeMatrix: __webpack_require__2(2429)
};
}
),
/***/
71334: (
/***/
(module2) => {
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var ArrayBufferToBase64 = function(arrayBuffer, mediaType) {
var bytes = new Uint8Array(arrayBuffer);
var len = bytes.length;
var base64 = mediaType ? "data:" + mediaType + ";base64," : "";
for (var i = 0; i < len; i += 3) {
base64 += chars[bytes[i] >> 2];
base64 += chars[(bytes[i] & 3) << 4 | bytes[i + 1] >> 4];
base64 += chars[(bytes[i + 1] & 15) << 2 | bytes[i + 2] >> 6];
base64 += chars[bytes[i + 2] & 63];
}
if (len % 3 === 2) {
base64 = base64.substring(0, base64.length - 1) + "=";
} else if (len % 3 === 1) {
base64 = base64.substring(0, base64.length - 2) + "==";
}
return base64;
};
module2.exports = ArrayBufferToBase64;
}
),
/***/
53134: (
/***/
(module2) => {
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var lookup = new Uint8Array(256);
for (var i = 0; i < chars.length; i++) {
lookup[chars.charCodeAt(i)] = i;
}
var Base64ToArrayBuffer = function(base64) {
base64 = base64.substr(base64.indexOf(",") + 1);
var len = base64.length;
var bufferLength = len * 0.75;
var p = 0;
var encoded1;
var encoded2;
var encoded3;
var encoded4;
if (base64[len - 1] === "=") {
bufferLength--;
if (base64[len - 2] === "=") {
bufferLength--;
}
}
var arrayBuffer = new ArrayBuffer(bufferLength);
var bytes = new Uint8Array(arrayBuffer);
for (var i2 = 0; i2 < len; i2 += 4) {
encoded1 = lookup[base64.charCodeAt(i2)];
encoded2 = lookup[base64.charCodeAt(i2 + 1)];
encoded3 = lookup[base64.charCodeAt(i2 + 2)];
encoded4 = lookup[base64.charCodeAt(i2 + 3)];
bytes[p++] = encoded1 << 2 | encoded2 >> 4;
bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;
bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;
}
return arrayBuffer;
};
module2.exports = Base64ToArrayBuffer;
}
),
/***/
65839: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
ArrayBufferToBase64: __webpack_require__2(71334),
Base64ToArrayBuffer: __webpack_require__2(53134)
};
}
),
/***/
91799: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Array: __webpack_require__2(37105),
Base64: __webpack_require__2(65839),
Objects: __webpack_require__2(1183),
String: __webpack_require__2(31749),
NOOP: __webpack_require__2(29747),
NULL: __webpack_require__2(20242)
};
}
),
/***/
41786: (
/***/
(module2) => {
var Clone = function(obj) {
var clone = {};
for (var key in obj) {
if (Array.isArray(obj[key])) {
clone[key] = obj[key].slice(0);
} else {
clone[key] = obj[key];
}
}
return clone;
};
module2.exports = Clone;
}
),
/***/
62644: (
/***/
(module2) => {
var DeepCopy = function(inObject) {
var outObject;
var value;
var key;
if (typeof inObject !== "object" || inObject === null) {
return inObject;
}
outObject = Array.isArray(inObject) ? [] : {};
for (key in inObject) {
value = inObject[key];
outObject[key] = DeepCopy(value);
}
return outObject;
};
module2.exports = DeepCopy;
}
),
/***/
79291: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var IsPlainObject = __webpack_require__2(41212);
var Extend = function() {
var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, i = 1, length = arguments.length, deep = false;
if (typeof target === "boolean") {
deep = target;
target = arguments[1] || {};
i = 2;
}
if (length === i) {
target = this;
--i;
}
for (; i < length; i++) {
if ((options = arguments[i]) != null) {
for (name in options) {
src = target[name];
copy = options[name];
if (target === copy) {
continue;
}
if (deep && copy && (IsPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) {
if (copyIsArray) {
copyIsArray = false;
clone = src && Array.isArray(src) ? src : [];
} else {
clone = src && IsPlainObject(src) ? src : {};
}
target[name] = Extend(deep, clone, copy);
} else if (copy !== void 0) {
target[name] = copy;
}
}
}
}
return target;
};
module2.exports = Extend;
}
),
/***/
23568: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var MATH = __webpack_require__2(75508);
var GetValue = __webpack_require__2(35154);
var GetAdvancedValue = function(source, key, defaultValue) {
var value = GetValue(source, key, null);
if (value === null) {
return defaultValue;
} else if (Array.isArray(value)) {
return MATH.RND.pick(value);
} else if (typeof value === "object") {
if (value.hasOwnProperty("randInt")) {
return MATH.RND.integerInRange(value.randInt[0], value.randInt[1]);
} else if (value.hasOwnProperty("randFloat")) {
return MATH.RND.realInRange(value.randFloat[0], value.randFloat[1]);
}
} else if (typeof value === "function") {
return value(key);
}
return value;
};
module2.exports = GetAdvancedValue;
}
),
/***/
95540: (
/***/
(module2) => {
var GetFastValue = function(source, key, defaultValue) {
var t = typeof source;
if (!source || t === "number" || t === "string") {
return defaultValue;
} else if (source.hasOwnProperty(key) && source[key] !== void 0) {
return source[key];
} else {
return defaultValue;
}
};
module2.exports = GetFastValue;
}
),
/***/
82840: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var GetValue = __webpack_require__2(35154);
var Clamp = __webpack_require__2(45319);
var GetMinMaxValue = function(source, key, min, max, defaultValue) {
if (defaultValue === void 0) {
defaultValue = min;
}
var value = GetValue(source, key, defaultValue);
return Clamp(value, min, max);
};
module2.exports = GetMinMaxValue;
}
),
/***/
35154: (
/***/
(module2) => {
var GetValue = function(source, key, defaultValue, altSource) {
if (!source && !altSource || typeof source === "number") {
return defaultValue;
} else if (source && source.hasOwnProperty(key)) {
return source[key];
} else if (altSource && altSource.hasOwnProperty(key)) {
return altSource[key];
} else if (key.indexOf(".") !== -1) {
var keys = key.split(".");
var parentA = source;
var parentB = altSource;
var valueA = defaultValue;
var valueB = defaultValue;
var valueAFound = true;
var valueBFound = true;
for (var i = 0; i < keys.length; i++) {
if (parentA && parentA.hasOwnProperty(keys[i])) {
valueA = parentA[keys[i]];
parentA = parentA[keys[i]];
} else {
valueAFound = false;
}
if (parentB && parentB.hasOwnProperty(keys[i])) {
valueB = parentB[keys[i]];
parentB = parentB[keys[i]];
} else {
valueBFound = false;
}
}
if (valueAFound) {
return valueA;
} else if (valueBFound) {
return valueB;
} else {
return defaultValue;
}
} else {
return defaultValue;
}
};
module2.exports = GetValue;
}
),
/***/
69036: (
/***/
(module2) => {
var HasAll = function(source, keys) {
for (var i = 0; i < keys.length; i++) {
if (!source.hasOwnProperty(keys[i])) {
return false;
}
}
return true;
};
module2.exports = HasAll;
}
),
/***/
1985: (
/***/
(module2) => {
var HasAny = function(source, keys) {
for (var i = 0; i < keys.length; i++) {
if (source.hasOwnProperty(keys[i])) {
return true;
}
}
return false;
};
module2.exports = HasAny;
}
),
/***/
97022: (
/***/
(module2) => {
var HasValue = function(source, key) {
return source.hasOwnProperty(key);
};
module2.exports = HasValue;
}
),
/***/
41212: (
/***/
(module2) => {
var IsPlainObject = function(obj) {
if (!obj || typeof obj !== "object" || obj.nodeType || obj === obj.window) {
return false;
}
try {
if (obj.constructor && !{}.hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf")) {
return false;
}
} catch (e) {
return false;
}
return true;
};
module2.exports = IsPlainObject;
}
),
/***/
46975: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Clone = __webpack_require__2(41786);
var Merge = function(obj1, obj2) {
var clone = Clone(obj1);
for (var key in obj2) {
if (!clone.hasOwnProperty(key)) {
clone[key] = obj2[key];
}
}
return clone;
};
module2.exports = Merge;
}
),
/***/
269: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var Clone = __webpack_require__2(41786);
var MergeRight = function(obj1, obj2) {
var clone = Clone(obj1);
for (var key in obj2) {
if (clone.hasOwnProperty(key)) {
clone[key] = obj2[key];
}
}
return clone;
};
module2.exports = MergeRight;
}
),
/***/
18254: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
var HasValue = __webpack_require__2(97022);
var Pick = function(object, keys) {
var obj = {};
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (HasValue(object, key)) {
obj[key] = object[key];
}
}
return obj;
};
module2.exports = Pick;
}
),
/***/
61622: (
/***/
(module2) => {
var SetValue = function(source, key, value) {
if (!source || typeof source === "number") {
return false;
} else if (source.hasOwnProperty(key)) {
source[key] = value;
return true;
} else if (key.indexOf(".") !== -1) {
var keys = key.split(".");
var parent = source;
var prev = source;
for (var i = 0; i < keys.length; i++) {
if (parent.hasOwnProperty(keys[i])) {
prev = parent;
parent = parent[keys[i]];
} else {
return false;
}
}
prev[keys[keys.length - 1]] = value;
return true;
}
return false;
};
module2.exports = SetValue;
}
),
/***/
1183: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Clone: __webpack_require__2(41786),
DeepCopy: __webpack_require__2(62644),
Extend: __webpack_require__2(79291),
GetAdvancedValue: __webpack_require__2(23568),
GetFastValue: __webpack_require__2(95540),
GetMinMaxValue: __webpack_require__2(82840),
GetValue: __webpack_require__2(35154),
HasAll: __webpack_require__2(69036),
HasAny: __webpack_require__2(1985),
HasValue: __webpack_require__2(97022),
IsPlainObject: __webpack_require__2(41212),
Merge: __webpack_require__2(46975),
MergeRight: __webpack_require__2(269),
Pick: __webpack_require__2(18254),
SetValue: __webpack_require__2(61622)
};
}
),
/***/
27902: (
/***/
(module2) => {
var Format = function(string, values) {
return string.replace(/%([0-9]+)/g, function(s, n) {
return values[Number(n) - 1];
});
};
module2.exports = Format;
}
),
/***/
41836: (
/***/
(module2) => {
var Pad = function(str, len, pad, dir) {
if (len === void 0) {
len = 0;
}
if (pad === void 0) {
pad = " ";
}
if (dir === void 0) {
dir = 3;
}
str = str.toString();
var padlen = 0;
if (len + 1 >= str.length) {
switch (dir) {
case 1:
str = new Array(len + 1 - str.length).join(pad) + str;
break;
case 3:
var right = Math.ceil((padlen = len - str.length) / 2);
var left = padlen - right;
str = new Array(left + 1).join(pad) + str + new Array(right + 1).join(pad);
break;
default:
str = str + new Array(len + 1 - str.length).join(pad);
break;
}
}
return str;
};
module2.exports = Pad;
}
),
/***/
33628: (
/***/
(module2) => {
var RemoveAt = function(string, index) {
if (index === 0) {
return string.slice(1);
} else {
return string.slice(0, index - 1) + string.slice(index);
}
};
module2.exports = RemoveAt;
}
),
/***/
27671: (
/***/
(module2) => {
var Reverse = function(string) {
return string.split("").reverse().join("");
};
module2.exports = Reverse;
}
),
/***/
45650: (
/***/
(module2) => {
var UUID = function() {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0;
var v = c === "x" ? r : r & 3 | 8;
return v.toString(16);
});
};
module2.exports = UUID;
}
),
/***/
35355: (
/***/
(module2) => {
var UppercaseFirst = function(str) {
return str && str[0].toUpperCase() + str.slice(1);
};
module2.exports = UppercaseFirst;
}
),
/***/
31749: (
/***/
(module2, __unused_webpack_exports, __webpack_require__2) => {
module2.exports = {
Format: __webpack_require__2(27902),
Pad: __webpack_require__2(41836),
RemoveAt: __webpack_require__2(33628),
Reverse: __webpack_require__2(27671),
UppercaseFirst: __webpack_require__2(35355),
UUID: __webpack_require__2(45650)
};
}
)
/******/
};
var __webpack_module_cache__ = {};
function __webpack_require__(moduleId) {
var cachedModule = __webpack_module_cache__[moduleId];
if (cachedModule !== void 0) {
return cachedModule.exports;
}
var module2 = __webpack_module_cache__[moduleId] = {
/******/
// no module.id needed
/******/
// no module.loaded needed
/******/
exports: {}
/******/
};
__webpack_modules__[moduleId](module2, module2.exports, __webpack_require__);
return module2.exports;
}
(() => {
__webpack_require__.g = function() {
if (typeof globalThis === "object") return globalThis;
try {
return this || new Function("return this")();
} catch (e) {
if (typeof window === "object") return window;
}
}();
})();
var __webpack_exports__ = __webpack_require__(85454);
return __webpack_exports__;
})()
);
});
}
});
export default require_phaser();
/*! Bundled license information:
phaser/dist/phaser.js:
(**
* @author samme
* @copyright 2013-2024 Phaser Studio Inc.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*)
(**
* @author Richard Davey <rich@phaser.io>
* @copyright 2013-2024 Phaser Studio Inc.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*)
(**
* @author Richard Davey <rich@phaser.io>
* @author samme <samme.npm@gmail.com>
* @copyright 2013-2024 Phaser Studio Inc.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*)
(**
* @author Jason Nicholls <nicholls.jason@gmail.com>
* @copyright 2018 Photon Storm Ltd.
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
*)
(**
* @author Richard Davey <rich@phaser.io>
* @author Felipe Alfonso <@bitnenfer>
* @copyright 2013-2024 Phaser Studio Inc.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*)
(**
* @author Florian Vazelle
* @author Geoffrey Glaive
* @copyright 2013-2024 Phaser Studio Inc.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*)
(**
* @author Richard Davey
* @copyright 2013-2024 Phaser Studio Inc.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*)
(**
* @author Richard Davey <rich@phaser.io>
* @author Florian Mertens
* @copyright 2013-2024 Phaser Studio Inc.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*)
(**
* @author Richard Davey <rich@phaser.io>
* @author Igor Ognichenko <ognichenko.igor@gmail.com>
* @copyright 2013-2024 Phaser Studio Inc.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*)
(**
* @author Richard Davey <rich@phaser.io>
* @copyright 2021 Photon Storm Ltd.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*)
(**
* @author Greg McLean <GregDevProjects>
* @copyright 2021 Photon Storm Ltd.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*)
(**
* @author Vladislav Forsh <vlad@robowhale.com>
* @copyright 2021 RoboWhale
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*)
(**
* @author Richard Davey <rich@phaser.io>
* @author @samme
* @copyright 2013-2024 Phaser Studio Inc.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*)
(**
* @author Joachim Grill <joachim@codeandweb.com>
* @author Richard Davey <rich@phaser.io>
* @copyright 2018 CodeAndWeb GmbH
* @copyright 2013-2024 Phaser Studio Inc.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*)
(**
* @author Stefan Hedman <schteppe@gmail.com> (http://steffe.se)
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*)
(**
* @author Richard Davey <rich@phaser.io>
* @copyright 2013-2024 Phaser Studio Inc.
* @license {@link https://github.com/photonstorm/phaser3-plugin-template/blob/master/LICENSE|MIT License}
*)
(**
* @author Benjamin D. Richards <benjamindrichards@gmail.com>
* @copyright 2013-2024 Phaser Studio Inc.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*)
(**
* @author Richard Davey <rich@phaser.io>
* @author Felipe Alfonso <@bitnenfer>
* @author Matthew Groves <@doormat>
* @copyright 2013-2024 Phaser Studio Inc.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*)
(**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2013-2023 Photon Storm Ltd.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*)
(**
* @author samme
* @copyright 2021 Photon Storm Ltd.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*)
(**
* @author Richard Davey <rich@phaser.io>
* @author Pavle Goloskokovic <pgoloskokovic@gmail.com> (http://prunegames.com)
* @copyright 2013-2024 Phaser Studio Inc.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*)
(**
* @author pi-kei
* @copyright 2013-2024 Phaser Studio Inc.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*)
(**
* @author Vladimir Agafonkin
* @author Richard Davey <rich@phaser.io>
* @copyright 2013-2024 Phaser Studio Inc.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*)
(**
* @author Ben Richards <benjamindrichards@gmail.com>
* @copyright 2024 Photon Storm Ltd.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*)
(**
* @author Seth Berrier <berriers@uwstout.edu>
* @copyright 2013-2024 Phaser Studio Inc.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*)
(**
* @author Richard Davey <rich@phaser.io>
* @author Angry Bytes (and contributors)
* @copyright 2013-2024 Phaser Studio Inc.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*)
(**
* @author Niklas von Hertzen (https://github.com/niklasvh/base64-arraybuffer)
* @author Richard Davey <rich@phaser.io>
* @copyright 2013-2024 Phaser Studio Inc.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*)
*/
//# sourceMappingURL=phaser.js.map