Merge branch 'master' into webgl-wrappers

This commit is contained in:
Ben Richards 2024-02-01 11:00:08 +13:00
commit 587b6e7bcd
24 changed files with 138 additions and 182 deletions

View file

@ -10,12 +10,29 @@
* The `dropped` argument has now been adeded to the documentation for the `DRAG_END` and `GAMEOBJECT_DRAG_END` events (thanks @samme)
* `Container.onChildDestroyed` is a new internal method used to destroy Container children. Previously, if you destroyed a Game Object in an exclusive Container, the game object would (momentarily) move onto the Scene display list and emit an ADDED_TO_SCENE event. Also, if you added a Sprite to a non-exclusive Container and stopped the Scene, you would get a TypeError (evaluating 'this.anims.destroy'). This happened because the fromChild argument in the DESTROY event was misinterpreted as destroyChild in the Container's remove(), and the Container was calling the Sprite's destroy() again. (thanks @samme)
* The `Text` and `TileSprite` Game Objects now place their textures into the global `TextureManager` and a `_textureKey` private string property has been added which contains a UUID to reference that texture.
* `Tilemaps.Components.WeightedRandomize` now uses the Phaser `Math.RND.frac` method with a seed instead of the `Math.Random` static method. (thanks @jorbascrumps)
* `Tilemaps.Components.IsometricCullTiles` does the `CheckIsoBounds` method check last when building the outputArray, as to help optimize in situations where the tile would not be visible anyways. (thanks @zegenie)
* `Tilemaps.Components.WeightedRandomize` now uses the Phaser `Math.RND.frac` method with a seed instead the `Math.Random` static method. (thanks @jorbascrumps)
* The `Layer.removeAll`, `remove` and `add` methods have been removed. These methods are all still available via the `List` class that Layer inherits, but the `destroyChild` parameters are no longer available.
* The `Renderer.Canvas` and `Renderer.WebGL` will now only be included in the build file if the corresponding feature flags `CANVAS_RENDERER` and/or `WEBGL_RENDERER` are set to `true`. For Canvas only builds this saves a lot of space in the build (thanks @samme)
* You can now specify an `autoResize` boolean in the `RenderTargetConfig` which is passed to the Render Targets when they are created by a pipeline.
* The `UtilityPipeline` now sets `autoResize` to `true` in its Render Target Config, so that the global `fullFrame` and `halfFrame` Render Targets will automatically resize if the renderer changes.
* `Actions.PlaceOnLine` now has an added `ease` parameter which accepts a string from the EaseMap or a custom ease function to allow for different distrubutions along a line. (thanks @sB3p)
# Bug Fixes
* The `InputManager.onTouchMove` function has been fixed so it now correctly handles touch events on pages that have scrolled horizontally or vertically and shifted the viewport. Fix #6489 (thanks @somechris @hyewonjo)
* `Factory.staticBody` had the wrong return type in the docs/TS defs. Fix #6693 (thanks @ddhaiby)
* The `Time.Timeline` class didn't show as extending the Event Emitter, or have `config` as an optional argument in the docs / TS defs. Fix #6673 (thanks @ghclark2)
* `Animations.AnimationFrame#duration` is now the complete duration of the frame. Before this included `Animations.AnimationState#msPerFrame` with the value of `Animations.AnimationFrame#duration`. The fix to remove `Animations.AnimationState#msPerFrame` from `Animations.AnimationFrame#duration` has been removed from `Animations.AnimationManager#createFromAseprite` because of this clarification. Fix #6712 (thanks @Nerodon @TomMalitz)
* The `NineSlice` Game Object method `setSize` now recalculates its origin by calling the `updateDisplayOrigin` method. (thanks @dhashvir)
* When a `Layer` Game Object is destroyed, i.e. from changing or restarting a Scene, it will no longer cause an error when trying to destroy the children on its display list. Fix #6675 (thanks @crockergd @gm0nk)
* `DynamicTexture` will now automatically call `setSize(width, height)` for both WebGL and Canvas. Previously it only did it for WebGL. This fixes an issue where DynamicTextures in Canvas mode would have a width and height of -1. Fix #6682 (thanks @samme)
* `DynamicTexture.setSize` will now check to see if the `glTexture` bound to the current frame is stale, and if so, destroy it before binding the one from the Render Target. This fixes an issue where constantly destroying and creating Dynamic Textures would cause a memory leak in WebGL. Fix #6669 (thanks @DavidTalevski)
* The `BloomFX` and `BlurFX` and any custom pipeline that relies on using the `UtilityPipeline` full or half frame targets will now correctly draw even after the renderer size changes. Fix #6677 (thanks @Nerodon)
* The `PostFXPipeline.postBatch` method will now skip `onDraw` if the pipeline hasn't booted, introducing an artificial frame skip. This should potentially fix glitch errors on mobile devices where Post FX would appear corrupted for a single frame. Fix #6681 (thank @moufmouf @tongliang999)
* The `Matter.Body` function `scale` has been updated so if the Body originally had an `inertia` of `Infinity` this will be restored at the end of the call. This happens if you set a Matter Body to have fixed rotation. Fix #6369 (thanks @sushovande)
* Modified `RandomDataGenerator.weightedPick` method to avoid sampling past the last element. Fix #6701 (thanks @jameskirkwood)
## Examples, Documentation, Beta Testing and TypeScript
@ -24,4 +41,6 @@ My thanks to the following for helping with the Phaser 3 Examples, Beta Testing,
@AlvaroEstradaDev
@stevenwithaph
@paxperscientiam
@samme
@actionmoon
@rafael-lua

View file

@ -5,9 +5,11 @@
*/
var GetPoints = require('../geom/line/GetPoints');
var GetEasedPoints = require('../geom/line/GetEasedPoints');
/**
* Positions an array of Game Objects on evenly spaced points of a Line.
* If the ease parameter is supplied, it will space the points based on that easing function along the line.
*
* @function Phaser.Actions.PlaceOnLine
* @since 3.0.0
@ -16,12 +18,21 @@ var GetPoints = require('../geom/line/GetPoints');
*
* @param {(array|Phaser.GameObjects.GameObject[])} items - An array of Game Objects. The contents of this array are updated by this Action.
* @param {Phaser.Geom.Line} line - The Line to position the Game Objects on.
*
* @param {(string|function)} [ease] - An optional ease to use. This can be either a string from the EaseMap, or a custom function.
* @return {(array|Phaser.GameObjects.GameObject[])} The array of Game Objects that was passed to this Action.
*/
var PlaceOnLine = function (items, line)
var PlaceOnLine = function (items, line, ease)
{
var points = GetPoints(line, items.length);
var points;
if (ease)
{
points = GetEasedPoints(line, ease, items.length);
}
else
{
points = GetPoints(line, items.length);
}
for (var i = 0; i < items.length; i++)
{

View file

@ -362,7 +362,7 @@ var Animation = new Class({
// When is the first update due?
state.accumulator = 0;
state.nextTick = state.msPerFrame + state.currentFrame.duration;
state.nextTick = (state.currentFrame.duration) ? state.currentFrame.duration : state.msPerFrame;
},
/**
@ -515,7 +515,7 @@ var Animation = new Class({
{
state.accumulator -= state.nextTick;
state.nextTick = state.msPerFrame + state.currentFrame.duration;
state.nextTick = (state.currentFrame.duration) ? state.currentFrame.duration : state.msPerFrame;
},
/**

View file

@ -115,8 +115,7 @@ var AnimationFrame = new Class({
this.nextFrame = null;
/**
* Additional time (in ms) that this frame should appear for during playback.
* The value is added onto the msPerFrame set by the animation.
* The duration, in ms, of this frame of the animation.
*
* @name Phaser.Animations.AnimationFrame#duration
* @type {number}

View file

@ -451,14 +451,6 @@ var AnimationManager = new Class({
}
}
// Fix duration to play nice with how the next tick is calculated.
var msPerFrame = totalDuration / animFrames.length;
animFrames.forEach(function (entry)
{
entry.duration -= msPerFrame;
});
if (direction === 'reverse')
{
animFrames = animFrames.reverse();

View file

@ -346,7 +346,7 @@ var Config = new Class({
var renderConfig = GetValue(config, 'render', null);
/**
* @const {Phaser.Types.Core.PipelineConfig} Phaser.Core.Config#pipeline - An object mapping WebGL names to WebGLPipeline classes. These should be class constructors, not instances.
* @const {(Phaser.Types.Core.PipelineConfig|Phaser.Renderer.WebGL.WebGLPipeline[])} Phaser.Core.Config#pipeline - An object mapping WebGL names to WebGLPipeline classes. These should be class constructors, not instances.
*/
this.pipeline = GetValue(renderConfig, 'pipeline', null, config);

View file

@ -17,7 +17,7 @@
* @property {number} [maxLights=10] - The maximum number of lights allowed to be visible within range of a single Camera in the LightManager.
* @property {number} [maxTextures=-1] - When in WebGL mode, this sets the maximum number of GPU Textures to use. The default, -1, will use all available units. The WebGL1 spec says all browsers should provide a minimum of 8.
* @property {string} [mipmapFilter=''] - The mipmap magFilter to be used when creating WebGL textures. Don't set unless you wish to create mipmaps. Set to one of the following: 'NEAREST', 'LINEAR', 'NEAREST_MIPMAP_NEAREST', 'LINEAR_MIPMAP_NEAREST', 'NEAREST_MIPMAP_LINEAR' or 'LINEAR_MIPMAP_LINEAR'.
* @property {Phaser.Types.Core.PipelineConfig} [pipeline] - The WebGL Pipeline configuration object.
* @property {(Phaser.Types.Core.PipelineConfig|Phaser.Renderer.WebGL.WebGLPipeline[])} [pipeline] - The WebGL Pipeline configuration object.
* @property {boolean} [autoMobilePipeline=true] - Automatically enable the Mobile Pipeline if iOS or Android detected?
* @property {string} [defaultPipeline='MultiPipeline'] - The WebGL Pipeline that Game Objects will use by default. Set to 'MultiPipeline' as standard.
*/

View file

@ -89,7 +89,7 @@ var Displacement = new Class({
*
* You can only use a whole texture, not a frame from a texture atlas or sprite sheet.
*
* @method Phaser.GameObjects.Components.FX#setTexture
* @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.

View file

@ -12,7 +12,6 @@ var DataManager = require('../../data/DataManager');
var EventEmitter = require('eventemitter3');
var GameObjectEvents = require('../events');
var List = require('../../structs/List');
var RemoveBetween = require('../../utils/array/RemoveBetween');
var Render = require('./LayerRender');
var SceneEvents = require('../../scene/events');
var StableSort = require('../../utils/array/StableSort');
@ -605,104 +604,6 @@ var Layer = new Class({
return this;
},
/**
* Adds the given Game Object, or array of Game Objects, to this Layer.
*
* Each Game Object must be unique within the Layer.
*
* @method Phaser.GameObjects.Layer#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 Layer.
*
* @return {this} This Layer instance.
*/
add: function (child)
{
List.prototype.add.call(this, child);
return this;
},
/**
* Removes the given Game Object, or array of Game Objects, from this Layer.
*
* The Game Objects must already be children of this Layer.
*
* You can also optionally call `destroy` on each Game Object that is removed from the Layer.
*
* @method Phaser.GameObjects.Layer#remove
* @since 3.70.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 Layer.
* @param {boolean} [destroyChild=false] - Optionally call `destroy` on each child successfully removed from this Layer.
*
* @return {this} This Layer instance.
*/
remove: function (child, destroyChild)
{
var removed = List.prototype.remove.call(this, child);
if (destroyChild && removed)
{
if (!Array.isArray(removed))
{
removed = [ removed ];
}
for (var i = 0; i < removed.length; i++)
{
removed[i].destroy();
}
}
return this;
},
/**
* Removes all Game Objects from this Layer.
*
* You can also optionally call `destroy` on each Game Object that is removed from the Layer.
*
* @method Phaser.GameObjects.Layer#removeAll
* @since 3.4.0
*
* @param {boolean} [destroyChild=false] - Optionally call `destroy` on each Game Object successfully removed from this Layer.
*
* @return {this} This Layer 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(GameObjectEvents.DESTROY, this.remove, this);
list[i].destroy();
}
}
this.list = [];
}
else
{
RemoveBetween(list, 0, list.length, this.removeChildCallback, this);
}
return this;
},
/**
* This callback is invoked when this Game Object is added to a Scene.
*
@ -829,9 +730,9 @@ var Layer = new Class({
*/
addChildCallback: function (gameObject)
{
gameObject.once(GameObjectEvents.DESTROY, this.remove, this);
var displayList = gameObject.displayList;
if (gameObject.displayList && gameObject.displayList !== this)
if (displayList && displayList !== this)
{
gameObject.removeFromDisplayList();
}
@ -861,8 +762,6 @@ var Layer = new Class({
*/
removeChildCallback: function (gameObject)
{
gameObject.off(GameObjectEvents.DESTROY, this.remove, this);
this.queueDepthSort();
gameObject.displayList = null;
@ -1062,7 +961,7 @@ var Layer = new Class({
if (this.displayList)
{
this.displayList.remove(this, true);
this.displayList.remove(this, true, false);
this.displayList.queueDepthSort();
}

View file

@ -840,6 +840,8 @@ var NineSlice = new Class({
this.width = width;
this.height = height;
this.updateDisplayOrigin();
var input = this.input;
if (input && !input.customHitArea)

View file

@ -15,6 +15,8 @@ var Point = require('../point/Point');
* Provide a `stepRate` to ensure a specific distance between each point on the line. Set `quantity` to `0` when
* providing a `stepRate`.
*
* See also `GetEasedPoints` for a way to distribute the points across the line according to an ease type or input function.
*
* @function Phaser.Geom.Line.GetPoints
* @since 3.0.0
*

View file

@ -390,7 +390,7 @@ var RandomDataGenerator = new Class({
*/
weightedPick: function (array)
{
return array[~~(Math.pow(this.frac(), 2) * array.length + 0.5)];
return array[~~(Math.pow(this.frac(), 2) * (array.length - 0.5) + 0.5)];
},
/**

View file

@ -2,6 +2,6 @@
* @typedef {object} Phaser.Types.Math.Vector2Like
* @since 3.0.0
*
* @property {number} [x] - The x component.
* @property {number} [y] - The y component.
* @property {number} x - The x component.
* @property {number} y - The y component.
*/

View file

@ -741,6 +741,8 @@ var Axes = require('../geometry/Axes');
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];
@ -792,6 +794,11 @@ var Axes = require('../geometry/Axes');
body.circleRadius = null;
}
}
if (wasFixedRotation)
{
Body.setInertia(body, Infinity);
}
};
/**

View file

@ -14,9 +14,17 @@
module.exports = {
Canvas: require('./canvas'),
Events: require('./events'),
Snapshot: require('./snapshot'),
WebGL: require('./webgl')
Snapshot: require('./snapshot')
};
if (typeof CANVAS_RENDERER)
{
module.exports.Canvas = require('./canvas');
}
if (typeof WEBGL_RENDERER)
{
module.exports.WebGL = require('./webgl');
}

View file

@ -501,16 +501,17 @@ var WebGLPipeline = new Class({
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));
renderTargets.push(new RenderTarget(renderer, targetWidth, targetHeight, 1, minFilter, autoClear, autoResize));
}
else
{
renderTargets.push(new RenderTarget(renderer, width, height, scale, minFilter, autoClear));
renderTargets.push(new RenderTarget(renderer, width, height, scale, minFilter, autoClear, autoResize));
}
}
}

View file

@ -289,8 +289,10 @@ var PostFXPipeline = new Class({
{
this.bootFX();
}
else
{
this.onDraw(this.currentRenderTarget);
}
this.onPostBatch(gameObject);

View file

@ -59,16 +59,20 @@ var UtilityPipeline = new Class({
{
config.renderTarget = GetFastValue(config, 'renderTarget', [
{
scale: 1
scale: 1,
autoResize: true
},
{
scale: 1
scale: 1,
autoResize: true
},
{
scale: 0.5
scale: 0.5,
autoResize: true
},
{
scale: 0.5
scale: 0.5,
autoResize: true
}
]);

View file

@ -5,6 +5,7 @@
* @property {number} [scale=1] - A value between 0 and 1. Controls the size of this Render Target in relation to the Renderer. A value of 1 matches it. 0.5 makes the Render Target half the size of the renderer, etc.
* @property {number} [minFilter=0] - The minFilter mode of the texture. 0 is `LINEAR`, 1 is `NEAREST`.
* @property {boolean} [autoClear=true] - Controls if this Render Target is automatically cleared (via `gl.COLOR_BUFFER_BIT`) during the bind.
* @property {boolean} [autoResize=false] - Controls if this Render Target is automatically resized when the Renderer resizes.
* @property {number} [width] - The width of the Render Target. This is optional. If given it overrides the `scale` property.
* @property {number} [height=width] - The height of the Render Target. This is optional. If not given, it will be set to the same as the `width` value.
*/

View file

@ -577,7 +577,7 @@ var SceneManager = new Class({
sys.step(time, delta);
}
if (sys.scenePlugin._target)
if (sys.scenePlugin && sys.scenePlugin._target)
{
sys.scenePlugin.step(time, delta);
}

View file

@ -226,10 +226,7 @@ var DynamicTexture = new Class({
*/
this.pipeline = (!isCanvas) ? renderer.pipelines.get(PIPELINES.SINGLE_PIPELINE) : null;
if (!isCanvas)
{
this.setSize(width, height);
}
},
/**
@ -272,7 +269,10 @@ var DynamicTexture = new Class({
if (renderTarget.willResize(width, height))
{
renderTarget.resize(width, height);
}
if (renderTarget.texture !== source.glTexture)
{
// The texture has been resized, so is new, so we need to delete the old one
this.renderer.deleteTexture(source.glTexture);
}

View file

@ -400,7 +400,7 @@ var Tilemap = new Class({
if (!this.scene.sys.textures.exists(key))
{
console.warn('Invalid Tileset Image: ' + key);
console.warn('Texture key "%s" not found', key);
return null;
}
@ -410,7 +410,7 @@ var Tilemap = new Class({
if (index === null && this.format === Formats.TILED_JSON)
{
console.warn('No data found for Tileset: ' + tilesetName);
console.warn('Tilemap has no tileset "%s". Its tilesets are %o', tilesetName, this.tilesets);
return null;
}

View file

@ -49,8 +49,6 @@ var IsometricCullTiles = function (layer, camera, outputArray, renderOrder)
for (y = drawTop; y < drawBottom; y++)
{
for (x = drawLeft; x < drawRight; x++)
{
if (skipCull || CheckIsoBounds(x, y, layer, camera))
{
tile = mapData[y][x];
@ -59,8 +57,12 @@ var IsometricCullTiles = function (layer, camera, outputArray, renderOrder)
continue;
}
outputArray.push(tile);
if (!skipCull && !CheckIsoBounds(x, y, layer, camera))
{
continue;
}
outputArray.push(tile);
}
}
}
@ -71,8 +73,6 @@ var IsometricCullTiles = function (layer, camera, outputArray, renderOrder)
for (y = drawTop; y < drawBottom; y++)
{
for (x = drawRight; x >= drawLeft; x--)
{
if (skipCull || CheckIsoBounds(x, y, layer, camera))
{
tile = mapData[y][x];
@ -81,8 +81,12 @@ var IsometricCullTiles = function (layer, camera, outputArray, renderOrder)
continue;
}
outputArray.push(tile);
if (!skipCull && !CheckIsoBounds(x, y, layer, camera))
{
continue;
}
outputArray.push(tile);
}
}
}
@ -93,8 +97,6 @@ var IsometricCullTiles = function (layer, camera, outputArray, renderOrder)
for (y = drawBottom; y >= drawTop; y--)
{
for (x = drawLeft; x < drawRight; x++)
{
if (skipCull || CheckIsoBounds(x, y, layer, camera))
{
tile = mapData[y][x];
@ -103,8 +105,12 @@ var IsometricCullTiles = function (layer, camera, outputArray, renderOrder)
continue;
}
outputArray.push(tile);
if (!skipCull && !CheckIsoBounds(x, y, layer, camera))
{
continue;
}
outputArray.push(tile);
}
}
}
@ -115,8 +121,6 @@ var IsometricCullTiles = function (layer, camera, outputArray, renderOrder)
for (y = drawBottom; y >= drawTop; y--)
{
for (x = drawRight; x >= drawLeft; x--)
{
if (skipCull || CheckIsoBounds(x, y, layer, camera))
{
tile = mapData[y][x];
@ -125,8 +129,12 @@ var IsometricCullTiles = function (layer, camera, outputArray, renderOrder)
continue;
}
outputArray.push(tile);
if (!skipCull && !CheckIsoBounds(x, y, layer, camera))
{
continue;
}
outputArray.push(tile);
}
}
}

View file

@ -5,6 +5,7 @@
*/
var GetTilesWithin = require('./GetTilesWithin');
var MATH = require('../../math');
/**
* Randomizes the indexes of a rectangular region of tiles (in tile coordinates) within the
@ -51,7 +52,7 @@ var WeightedRandomize = function (tileX, tileY, width, height, weightedIndexes,
for (i = 0; i < tiles.length; i++)
{
var rand = Math.random() * weightTotal;
var rand = MATH.RND.frac() * weightTotal;
var sum = 0;
var randomIndex = -1;
@ -64,7 +65,7 @@ var WeightedRandomize = function (tileX, tileY, width, height, weightedIndexes,
var chosen = weightedIndexes[j].index;
randomIndex = Array.isArray(chosen)
? chosen[Math.floor(Math.random() * chosen.length)]
? chosen[Math.floor(MATH.RND.frac() * chosen.length)]
: chosen;
break;
}